diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index eb585aba42df..b97c78cba2fc 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4390,13 +4390,14 @@ def visit_super_expr(self, e: SuperExpr) -> Type: index = mro.index(type_info) else: method = self.chk.scope.top_function() - assert method is not None # Mypy explicitly allows supertype upper bounds (and no upper bound at all) # for annotating self-types. However, if such an annotation is used for # checking super() we will still get an error. So to be consistent, we also # allow such imprecise annotations for use with super(), where we fall back - # to the current class MRO instead. - if is_self_type_like(instance_type, is_classmethod=method.is_class): + # to the current class MRO instead. This works only from inside a method. + if method is not None and is_self_type_like( + instance_type, is_classmethod=method.is_class + ): if e.info and type_info in e.info.mro: mro = e.info.mro index = mro.index(type_info) diff --git a/test-data/unit/check-super.test b/test-data/unit/check-super.test index 0913f4f25126..6537f563a99c 100644 --- a/test-data/unit/check-super.test +++ b/test-data/unit/check-super.test @@ -409,3 +409,10 @@ class B(A): reveal_type(super().foo()) # N: Revealed type is "T`-1" return super().foo() [builtins fixtures/classmethod.pyi] + +[case testWrongSuperOutsideMethodNoCrash] +class B: + x: int +class C1(B): ... +class C2(B): ... +super(C1, C2).x # E: Argument 2 for "super" not an instance of argument 1