unpacking dict in function call with optional arguments fails
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Unpacking a dict when calling a function with **kwargs should not fail. This seems to be related to #4771 and #9676, but slightly different since the function definition is wider than those reports.
To Reproduce
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, cast, TYPE_CHECKING
def test(one: int | None = None, **kwargs: Any) -> int | None:
print(repr(kwargs))
return one
if TYPE_CHECKING:
reveal_type(test)
reveal_type(test())
reveal_type(test(test='one'))
reveal_type(test(**{'test': 'one'}))
which outputs:
test.py:13: note: Revealed type is 'def (one: Union[builtins.int, None] =, **kwargs: Any) -> Union[builtins.int, None]'
test.py:14: note: Revealed type is 'Union[builtins.int, None]'
test.py:15: note: Revealed type is 'Union[builtins.int, None]'
test.py:16: error: Argument 1 to "test" has incompatible type "**Dict[str, str]"; expected "Optional[int]" [arg-type]
Expected Behavior
There is no issue passing kwargs via a dict and you shouldn't need to cast to a Mapping type.
Actual Behavior
There is an error message, but reveal_type(test(**cast(Mapping[str, str], {'test': 'one'}))) (or saving as a temporary variable with Mapping as its type) will allow the code to succeed.
Your Environment
- Mypy version used: 0.800
- Mypy command-line flags:
--show-error-codes - Mypy configuration options from
mypy.ini(and other config files): - Python version used: 3.8
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the supplied Python 3.8 reproducer with mypy and --show-error-codes, comparing direct keyword arguments with the dict unpacking case. Trace argument unpacking alongside optional parameters and **kwargs; done means the dict unpacking call is accepted without requiring a Mapping cast and retains the expected return type.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100