diff --git a/mypy/semanal.py b/mypy/semanal.py index 7bac809..33d798f 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2943,21 +2943,9 @@ class SemanticAnalyzer(NodeVisitor): if isinstance(base.node, TypeInfo): # C.bar where C is a class type_info = base.node - elif isinstance(base.node, Var) and self.function_stack: - # check for self.bar or cls.bar in method/classmethod - func = self.function_stack[-1].type - if isinstance(func, CallableType): - formal_arg = func.argument_by_name(base.node.name()) - if formal_arg and formal_arg.pos == 0: - if ( - isinstance(formal_arg.typ, CallableType) and - isinstance(formal_arg.typ.ret_type, Instance) - ): - # classmethod - type_info = formal_arg.typ.ret_type.type - elif isinstance(formal_arg.typ, Instance): - # instance method - type_info = formal_arg.typ.type + elif isinstance(base.node, Var) and self.type: + # self.bar or cls.bar in method/classmethod + type_info = self.type if type_info: n = type_info.names.get(expr.name) if n is not None and (n.kind == MODULE_REF or isinstance(n.node, TypeInfo)): diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index a139450..2822364 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -1423,6 +1423,9 @@ class C: def foo(self) -> None: x = self.m.a reveal_type(x) # E: Revealed type is 'builtins.str' + y = 'hello' + z = y.m.a # E: "str" has no attribute "m" + reveal_type(z) @classmethod def cmethod(cls) -> None: y = cls.m.a