diff --git a/mypy/subtypes.py b/mypy/subtypes.py index cdfb13c759ed..e8bb3bffa858 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -12,6 +12,8 @@ # Circular import; done in the function instead. # import mypy.solve from mypy.nodes import ( + ARG_STAR, + ARG_STAR2, CONTRAVARIANT, COVARIANT, Decorator, @@ -1291,6 +1293,16 @@ def are_parameters_compatible( right_star = right.var_arg() right_star2 = right.kw_arg() + # Treat "def _(*a: Any, **kw: Any) -> X" similarly to "Callable[..., X]" + if ( + right.arg_kinds == [ARG_STAR, ARG_STAR2] + and right_star + and isinstance(get_proper_type(right_star.typ), AnyType) + and right_star2 + and isinstance(get_proper_type(right_star2.typ), AnyType) + ): + return True + # Match up corresponding arguments and check them for compatibility. In # every pair (argL, argR) of corresponding arguments from L and R, argL must # be "more general" than argR if L is to be a subtype of R. diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index a620c63ef58b..488531845be5 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -7136,6 +7136,16 @@ class B(A): # E: Final class __main__.B has abstract attributes "foo" class C: class C1(XX): pass # E: Name "XX" is not defined +[case testArgsKwargsInheritance] +from typing import Any + +class A(object): + def f(self, *args: Any, **kwargs: Any) -> int: ... + +class B(A): + def f(self, x: int) -> int: ... +[builtins fixtures/dict.pyi] + [case testClassScopeImports] class Foo: from mod import plain_function # E: Unsupported class scoped import diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index a91b6099a02e..8793406f69e7 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -188,9 +188,9 @@ if int(): ee_var = everywhere if int(): - ee_var = specific_1 # The difference between Callable[..., blah] and one with a *args: Any, **kwargs: Any is that the ... goes loosely both ways. + ee_var = specific_1 if int(): - ee_def = specific_1 # E: Incompatible types in assignment (expression has type "Callable[[int, str], None]", variable has type "Callable[[VarArg(Any), KwArg(Any)], None]") + ee_def = specific_1 [builtins fixtures/dict.pyi] @@ -1787,7 +1787,7 @@ def f2(*args, **kwargs) -> int: pass d(f1) e(f2) d(f2) -e(f1) # E: Argument 1 to "e" has incompatible type "Callable[[VarArg(Any)], int]"; expected "Callable[[VarArg(Any), KwArg(Any)], int]" +e(f1) [builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 60e95877336c..d83d0470c6b0 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -3160,7 +3160,7 @@ from test1 import aaaa # E: Module "test1" has no attribute "aaaa" import b [file a.py] class Foo: - def frobnicate(self, *args, **kwargs): pass + def frobnicate(self, x, *args, **kwargs): pass [file b.py] from a import Foo class Bar(Foo): @@ -3178,12 +3178,12 @@ class Bar(Foo): [out1] tmp/b.py:3: error: Signature of "frobnicate" incompatible with supertype "Foo" tmp/b.py:3: note: Superclass: -tmp/b.py:3: note: def frobnicate(self, *args: Any, **kwargs: Any) -> Any +tmp/b.py:3: note: def frobnicate(self, x: Any, *args: Any, **kwargs: Any) -> Any tmp/b.py:3: note: Subclass: tmp/b.py:3: note: def frobnicate(self) -> None [out2] tmp/b.py:3: error: Signature of "frobnicate" incompatible with supertype "Foo" tmp/b.py:3: note: Superclass: -tmp/b.py:3: note: def frobnicate(self, *args: Any, **kwargs: Any) -> Any +tmp/b.py:3: note: def frobnicate(self, x: Any, *args: Any, **kwargs: Any) -> Any tmp/b.py:3: note: Subclass: tmp/b.py:3: note: def frobnicate(self, *args: Any) -> None