Skip to content

Commit a0e2a2d

Browse files
Make any callable compatible with (*args: Any, **kwargs: Any) (#11203)
Resolves #5876 Co-authored-by: hauntsaninja <> Co-authored-by: Ivan Levkivskyi <[email protected]>
1 parent 52f1dd3 commit a0e2a2d

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

mypy/subtypes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# Circular import; done in the function instead.
1313
# import mypy.solve
1414
from mypy.nodes import (
15+
ARG_STAR,
16+
ARG_STAR2,
1517
CONTRAVARIANT,
1618
COVARIANT,
1719
Decorator,
@@ -1291,6 +1293,16 @@ def are_parameters_compatible(
12911293
right_star = right.var_arg()
12921294
right_star2 = right.kw_arg()
12931295

1296+
# Treat "def _(*a: Any, **kw: Any) -> X" similarly to "Callable[..., X]"
1297+
if (
1298+
right.arg_kinds == [ARG_STAR, ARG_STAR2]
1299+
and right_star
1300+
and isinstance(get_proper_type(right_star.typ), AnyType)
1301+
and right_star2
1302+
and isinstance(get_proper_type(right_star2.typ), AnyType)
1303+
):
1304+
return True
1305+
12941306
# Match up corresponding arguments and check them for compatibility. In
12951307
# every pair (argL, argR) of corresponding arguments from L and R, argL must
12961308
# be "more general" than argR if L is to be a subtype of R.

test-data/unit/check-classes.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7136,6 +7136,16 @@ class B(A): # E: Final class __main__.B has abstract attributes "foo"
71367136
class C:
71377137
class C1(XX): pass # E: Name "XX" is not defined
71387138

7139+
[case testArgsKwargsInheritance]
7140+
from typing import Any
7141+
7142+
class A(object):
7143+
def f(self, *args: Any, **kwargs: Any) -> int: ...
7144+
7145+
class B(A):
7146+
def f(self, x: int) -> int: ...
7147+
[builtins fixtures/dict.pyi]
7148+
71397149
[case testClassScopeImports]
71407150
class Foo:
71417151
from mod import plain_function # E: Unsupported class scoped import

test-data/unit/check-functions.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ if int():
188188
ee_var = everywhere
189189

190190
if int():
191-
ee_var = specific_1 # The difference between Callable[..., blah] and one with a *args: Any, **kwargs: Any is that the ... goes loosely both ways.
191+
ee_var = specific_1
192192
if int():
193-
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]")
193+
ee_def = specific_1
194194

195195
[builtins fixtures/dict.pyi]
196196

@@ -1787,7 +1787,7 @@ def f2(*args, **kwargs) -> int: pass
17871787
d(f1)
17881788
e(f2)
17891789
d(f2)
1790-
e(f1) # E: Argument 1 to "e" has incompatible type "Callable[[VarArg(Any)], int]"; expected "Callable[[VarArg(Any), KwArg(Any)], int]"
1790+
e(f1)
17911791

17921792
[builtins fixtures/dict.pyi]
17931793

test-data/unit/check-modules.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,7 +3160,7 @@ from test1 import aaaa # E: Module "test1" has no attribute "aaaa"
31603160
import b
31613161
[file a.py]
31623162
class Foo:
3163-
def frobnicate(self, *args, **kwargs): pass
3163+
def frobnicate(self, x, *args, **kwargs): pass
31643164
[file b.py]
31653165
from a import Foo
31663166
class Bar(Foo):
@@ -3178,12 +3178,12 @@ class Bar(Foo):
31783178
[out1]
31793179
tmp/b.py:3: error: Signature of "frobnicate" incompatible with supertype "Foo"
31803180
tmp/b.py:3: note: Superclass:
3181-
tmp/b.py:3: note: def frobnicate(self, *args: Any, **kwargs: Any) -> Any
3181+
tmp/b.py:3: note: def frobnicate(self, x: Any, *args: Any, **kwargs: Any) -> Any
31823182
tmp/b.py:3: note: Subclass:
31833183
tmp/b.py:3: note: def frobnicate(self) -> None
31843184
[out2]
31853185
tmp/b.py:3: error: Signature of "frobnicate" incompatible with supertype "Foo"
31863186
tmp/b.py:3: note: Superclass:
3187-
tmp/b.py:3: note: def frobnicate(self, *args: Any, **kwargs: Any) -> Any
3187+
tmp/b.py:3: note: def frobnicate(self, x: Any, *args: Any, **kwargs: Any) -> Any
31883188
tmp/b.py:3: note: Subclass:
31893189
tmp/b.py:3: note: def frobnicate(self, *args: Any) -> None

0 commit comments

Comments
 (0)