diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index f54703997b53..be4361801154 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -998,13 +998,6 @@ def analyze_ordinary_member_access(self, e: MemberExpr, e.name, original_type, e, is_lvalue, False, False, self.named_type, self.not_ready_callback, self.msg, original_type=original_type, chk=self.chk) - if isinstance(member_type, CallableType): - for v in member_type.variables: - v.id.meta_level = 0 - if isinstance(member_type, Overloaded): - for it in member_type.items(): - for v in it.variables: - v.id.meta_level = 0 if is_lvalue: return member_type else: diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 7390bb7baf93..a105c13c393b 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -88,7 +88,9 @@ def analyze_member_access(name: str, else: signature = bind_self(signature, original_type) typ = map_instance_to_supertype(typ, method.info) - return expand_type_by_instance(signature, typ) + member_type = expand_type_by_instance(signature, typ) + freeze_type_vars(member_type) + return member_type else: # Not a method. return analyze_member_var_access(name, typ, info, node, @@ -298,6 +300,16 @@ def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo, node: Cont return AnyType() +def freeze_type_vars(member_type: Type) -> None: + if isinstance(member_type, CallableType): + for v in member_type.variables: + v.id.meta_level = 0 + if isinstance(member_type, Overloaded): + for it in member_type.items(): + for v in it.variables: + v.id.meta_level = 0 + + def handle_partial_attribute_type(typ: PartialType, is_lvalue: bool, msg: MessageBuilder, context: Context) -> Type: if typ.type is None: diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 0ce740ac60ed..56251284553a 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -1834,6 +1834,19 @@ class D: g = D().m # This should not crash: see https://github.com/python/mypy/issues/2804 [builtins fixtures/dict.pyi] +[case testGenericMethodRestoreMetaLevel3] +from typing import TypeVar +T = TypeVar('T') + +class C: + def m(self, x: T) -> T: + return x + +class D(C): + def __init__(self) -> None: + self.d = super().m # This should not crash: see https://github.com/python/mypy/issues/2804 +[builtins fixtures/dict.pyi] + [case testIncrementalPerFileFlags] # flags: --config-file tmp/mypy.ini import a