Skip to content

Commit d61babb

Browse files
authored
Don't map actual **kwargs to formal *args (#6096)
The fix was originally proposed by @elazarg. Fixes #1969.
1 parent 18b3cbd commit d61babb

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

mypy/argmap.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ def map_actuals_to_formals(actual_kinds: List[int],
8181
no_certain_match = (
8282
not formal_to_actual[fi]
8383
or actual_kinds[formal_to_actual[fi][0]] == nodes.ARG_STAR)
84-
if ((formal_names[fi] and no_certain_match)
85-
or formal_kinds[fi] == nodes.ARG_STAR2):
84+
if ((formal_names[fi]
85+
and no_certain_match
86+
and formal_kinds[fi] != nodes.ARG_STAR) or
87+
formal_kinds[fi] == nodes.ARG_STAR2):
8688
formal_to_actual[fi].append(ai)
8789
return formal_to_actual
8890

test-data/unit/check-kwargs.test

+18
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,21 @@ class A:
403403
tmp/m.py:1: error: Unsupported operand types for + ("int" and "str")
404404
main:2: error: Unexpected keyword argument "x" for "A"
405405
tmp/m.py:3: note: "A" defined here
406+
407+
[case testStarArgsAndKwArgsSpecialCase]
408+
from typing import Dict, Mapping
409+
410+
def f(*vargs: int, **kwargs: object) -> None:
411+
pass
412+
413+
def g(arg: int = 0, **kwargs: object) -> None:
414+
pass
415+
416+
d = {} # type: Dict[str, object]
417+
f(**d)
418+
g(**d) # E: Argument 1 to "g" has incompatible type "**Dict[str, object]"; expected "int"
419+
420+
m = {} # type: Mapping[str, object]
421+
f(**m)
422+
g(**m) # TODO: Should be an error
423+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)