You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Protocol incorrectly matches when positional or keyword parameter matches *args #21014
When a protocol defines a function with a keyword or positional parameter (a: int) -> None, a concrete function where said parameter is missing, but matches the *args parameter (*args: int) -> None will be seen as implementing the protocol.
I would expect (a: int) -> None to also need matching **kwargs such as (*args: int, **kwargs: int) -> None and for it to only match *args alone when specified as a positional only argument (e.g. (a: int, /) -> None)
Otherwise it cannot be called safely, pyright and ty both successfully raise errors for this case.
main.py:13: error: Argument 1 to "f" has incompatible type "C"; expected "P" [arg-type]
because calling the method as foo(a=1) would fail.
Actual Behavior
mypy:
Success: no issues found in 1 source file
pyright:
Argument of type "C" cannot be assigned to parameter "o" of type "P" in function "f"
"C" is incompatible with protocol "P"
"foo" is an incompatible type
Type "(*args: int) -> None" is not assignable to type "(a: int) -> None"
Missing keyword parameter "a" (reportArgumentType)
ty:
Argument to function `f` is incorrect: Expected `P`, found `C` (invalid-argument-type) [Ln 17, Col 3]
python:
Traceback (most recent call last):
File "xxx.py", line 17, in <module>
f(C())
~^^^^^
File "xxx.py", line 14, in f
o.foo(a=1)
~~~~~^^^^^
TypeError: C.foo() got an unexpected keyword argument 'a'
Your Environment
Mypy version used: 1.19.1 and master
Mypy command-line flags: --strict
Mypy configuration options from mypy.ini (and other config files):
I am quite sure this is a duplicate, but can't find original after a quick search. This is a very old intentional exception that we should get rid of at some point, at least with --strict. This is not specific to protocols, nor to star arguments, mypy currently allows something like this:
Yeah. Btw for protocols it is also just removing ignore_pos_arg_names=True from is_protocol_implementation(). Btw I guess fallout may be smaller for protocols.
Activity
ilevkivskyi commentedon Mar 12, 2026
I am quite sure this is a duplicate, but can't find original after a quick search. This is a very old intentional exception that we should get rid of at some point, at least with
--strict. This is not specific to protocols, nor to star arguments, mypy currently allows something like this:even though it is not safe. This is because of tons of code written in days predating mypy.
hauntsaninja commentedon Mar 12, 2026
For LSP, I had opened #18355. Based on primer it will need to be off by default.
The code paths for LSP and this are different though, so that PR won't fix this.
ilevkivskyi commentedon Mar 12, 2026
Yeah. Btw for protocols it is also just removing
ignore_pos_arg_names=Truefromis_protocol_implementation(). Btw I guess fallout may be smaller for protocols.