Report an error if *args or **kwargs are passed when all other arguments are filled.
Bug Report
You can pass **kwargs or *args to a function, even if all of its arguments are already passed. I would expect this to raise an error, since it's only valid for empty kwargs and args.
To Reproduce playground link
def f(x: int) -> int:
return x + 1
def g(x: int, **kwargs) -> int:
return f(x, **kwargs)
def h(x: int, args: list[int]) -> int:
return f(x, *args)
g(1, bar=42)
h(2, [])
h(3, [1337])
Expected Behavior
In both g and h, the x argument is specified, so I would expecting passing **kwargs or *args to produce an error, since they can never correctly pass additional arguments.
Actual Behavior
Success: no issues found in 1 source file
Your Environment
I tried several versions of mypy (including 1.16.0 and master) with python3.12 in mypy playground.
I tried with both with and without --check-untyped-defs
** Related Issues
- This is a more general case of https://github.com/python/mypy/issues/13380 (that issue specifically mentions functions with no arguments)
- https://github.com/python/mypy/issues/12206 is another issue with splatting, but I don't think it's quite the same
Interestingly, if I add
def k(x: int, args: list[int]) -> int:
return f(x=x, *args)
it produces an error:
main.py:11: error: "f" gets multiple values for keyword argument "x" [misc]
This is more-or-less the sort of error I would expect, although the wording is a bit confusing.
This wording is almost the same as the message of the corresponding RuntimeError, so I think it's good enough.
This behavior is a bit inconsistent, though, your FR to reject calls where all args are present together with vararg sounds good! In both cases the only case when unpacking is valid is an empty arg/kwarg, so rejecting such calls would be helpful.
This is related to a recent discussion in the Python typing forum.
Thanks @erictraut, the proposed "allow any set of arguments that could potentially succeed at runtime EXCEPT if the only potential argument-to-parameter mappings involve unpacking empty arguments" approach sounds like the behavior that I expected.