Skip to content

Commit

Permalink
Fix crash when super outside of method is called (#9173)
Browse files Browse the repository at this point in the history
* Fix crash when super outside of method is called

* Change error message

* empty
  • Loading branch information
Unattend authored Aug 2, 2020
1 parent a9c9a41 commit 20b4628
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 0 deletions.
4 changes: 4 additions & 0 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3464,6 +3464,10 @@ def visit_super_expr(self, e: SuperExpr) -> Type:
self.chk.fail(message_registry.SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1, e)
return AnyType(TypeOfAny.from_error)

if len(mro) == index + 1:
self.chk.fail(message_registry.TARGET_CLASS_HAS_NO_BASE_CLASS, e)
return AnyType(TypeOfAny.from_error)

for base in mro[index+1:]:
if e.name in base.names or base == mro[-1]:
if e.info and e.info.fallback_to_any and base == mro[-1]:
Expand Down
1 change: 1 addition & 0 deletions mypy/message_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
SUPER_POSITIONAL_ARGS_REQUIRED = '"super" only accepts positional arguments' # type: Final
SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1 = \
'Argument 2 for "super" not an instance of argument 1' # type: Final
TARGET_CLASS_HAS_NO_BASE_CLASS = 'Target class has no base class' # type: Final
SUPER_OUTSIDE_OF_METHOD_NOT_SUPPORTED = \
'super() outside of a method is not supported' # type: Final
SUPER_ENCLOSING_POSITIONAL_ARGS_REQUIRED = \
Expand Down
14 changes: 14 additions & 0 deletions test-data/unit/check-super.test
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,20 @@ class B(A):
class C:
a = super().whatever # E: super() outside of a method is not supported

[case testSuperWithObjectClassAsFirstArgument]
class A:
def f(self) -> None:
super(object, self).f() # E: Target class has no base class

[case testSuperWithTypeVarAsFirstArgument]
from typing import TypeVar

T = TypeVar('T')

def f(obj: T) -> None:
super(obj.__class__, obj).f() # E: Target class has no base class
[builtins fixtures/__new__.pyi]

[case testSuperWithSingleArgument]
class B:
def f(self) -> None: pass
Expand Down
2 changes: 2 additions & 0 deletions test-data/unit/fixtures/__new__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ from typing import Any
class object:
def __init__(self) -> None: pass

__class__ = object

def __new__(cls) -> Any: pass

class type:
Expand Down

0 comments on commit 20b4628

Please sign in to comment.