diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 310aac82b13c7..0141271eccbac 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2410,15 +2410,6 @@ def lookup_operator(op_name: str, base_type: Type) -> Optional[Type]: """Looks up the given operator and returns the corresponding type, if it exists.""" local_errors = make_local_errors() - - # TODO: Remove this call and rely just on analyze_member_access - # Currently, it seems we still need this to correctly deal with - # things like metaclasses? - # - # E.g. see the pythoneval.testMetaclassOpAccessAny test case. - if not self.has_member(base_type, op_name): - return None - member = analyze_member_access( name=op_name, typ=base_type, @@ -3799,43 +3790,6 @@ def is_valid_keyword_var_arg(self, typ: Type) -> bool: [self.named_type('builtins.unicode'), AnyType(TypeOfAny.special_form)]))) - def has_member(self, typ: Type, member: str) -> bool: - """Does type have member with the given name?""" - # TODO: refactor this to use checkmember.analyze_member_access, otherwise - # these two should be carefully kept in sync. - typ = get_proper_type(typ) - - if isinstance(typ, TypeVarType): - typ = get_proper_type(typ.upper_bound) - if isinstance(typ, TupleType): - typ = tuple_fallback(typ) - if isinstance(typ, LiteralType): - typ = typ.fallback - if isinstance(typ, Instance): - return typ.type.has_readable_member(member) - if isinstance(typ, CallableType) and typ.is_type_obj(): - return typ.fallback.type.has_readable_member(member) - elif isinstance(typ, AnyType): - return True - elif isinstance(typ, UnionType): - result = all(self.has_member(x, member) for x in typ.relevant_items()) - return result - elif isinstance(typ, TypeType): - # Type[Union[X, ...]] is always normalized to Union[Type[X], ...], - # so we don't need to care about unions here. - item = typ.item - if isinstance(item, TypeVarType): - item = get_proper_type(item.upper_bound) - if isinstance(item, TupleType): - item = tuple_fallback(item) - if isinstance(item, Instance) and item.type.metaclass_type is not None: - return self.has_member(item.type.metaclass_type, member) - if isinstance(item, AnyType): - return True - return False - else: - return False - def not_ready_callback(self, name: str, context: Context) -> None: """Called when we can't infer the type of a variable because it's not ready yet. diff --git a/mypy/typeops.py b/mypy/typeops.py index 828791333f364..d143588aada3f 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -719,5 +719,5 @@ def custom_special_method(typ: Type, name: str, check_all: bool = False) -> bool if isinstance(typ, AnyType): # Avoid false positives in uncertain cases. return True - # TODO: support other types (see ExpressionChecker.has_member())? + # TODO: support other types (see analyze_member_access)? return False diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index ed547510b46c3..e924402c8614e 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -6650,7 +6650,7 @@ reveal_type(0.5 + C) # N: Revealed type is 'Any' reveal_type(0.5 + D()) # N: Revealed type is 'Any' reveal_type(D() + 0.5) # N: Revealed type is 'Any' -reveal_type("str" + D()) # N: Revealed type is 'builtins.str' +reveal_type("str" + D()) # N: Revealed type is 'Any' reveal_type(D() + "str") # N: Revealed type is 'Any'