Skip to content

Commit 85310a4

Browse files
committed
Fine-grained: Add tests for unpacking expressions (and fix crash)
Also fix crash on incompatible dictionary unpack. Fixes #4959. Work towards #4951.
1 parent 3d94cae commit 85310a4

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

mypy/messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ def incompatible_argument(self, n: int, m: int, callee: CallableType, arg_type:
639639
# For function calls with keyword arguments, display the argument name rather than the
640640
# number.
641641
arg_label = str(n)
642-
if isinstance(context, CallExpr):
642+
if isinstance(context, CallExpr) and len(context.arg_names) >= n:
643643
arg_name = context.arg_names[n - 1]
644644
if arg_name is not None:
645645
arg_label = '"{}"'.format(arg_name)

test-data/unit/fine-grained.test

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5800,3 +5800,87 @@ class M(type):
58005800
[out]
58015801
==
58025802
a.py:2: error: Argument 1 to "f" of "M" has incompatible type "int"; expected "str"
5803+
5804+
[case testExtendedUnpacking-skip-cache]
5805+
from typing import List
5806+
from a import g
5807+
def f() -> List[int]:
5808+
a, *b = g()
5809+
return b
5810+
5811+
[file a.py]
5812+
from typing import Tuple
5813+
def g() -> Tuple[str, int, int]: pass
5814+
5815+
[file a.py.2]
5816+
from typing import Tuple
5817+
def g() -> Tuple[str, str]: pass
5818+
5819+
[builtins fixtures/tuple.pyi]
5820+
[out]
5821+
==
5822+
main:5: error: Incompatible return value type (got "List[str]", expected "List[int]")
5823+
5824+
[case testUnpackInExpression1-skip-cache]
5825+
from typing import Tuple, List
5826+
from a import t
5827+
5828+
def f() -> Tuple[int, int]:
5829+
return (1, *t())
5830+
5831+
def g() -> List[int]:
5832+
return [1, *t()]
5833+
5834+
[file a.py]
5835+
from typing import Tuple
5836+
def t() -> Tuple[int]: ...
5837+
5838+
[file a.py.2]
5839+
from typing import Tuple
5840+
def t() -> Tuple[str]: ...
5841+
5842+
[builtins fixtures/list.pyi]
5843+
[out]
5844+
==
5845+
main:5: error: Incompatible return value type (got "Tuple[int, str]", expected "Tuple[int, int]")
5846+
main:8: error: List item 1 has incompatible type "Tuple[str]"; expected "int"
5847+
5848+
[case testUnpackInExpression2-skip-cache]
5849+
from typing import Set
5850+
from a import t
5851+
5852+
def f() -> Set[int]:
5853+
return {1, *t()}
5854+
5855+
[file a.py]
5856+
from typing import Tuple
5857+
def t() -> Tuple[int]: pass
5858+
5859+
[file a.py.2]
5860+
from typing import Tuple
5861+
def t() -> Tuple[str]: pass
5862+
5863+
[builtins fixtures/set.pyi]
5864+
[out]
5865+
==
5866+
main:5: error: Argument 2 to <set> has incompatible type "*Tuple[str]"; expected "int"
5867+
5868+
[case testUnpackInExpression3-skip-cache]
5869+
from typing import Dict
5870+
from a import d
5871+
5872+
def f() -> Dict[int, str]:
5873+
return {1: '', **d()}
5874+
5875+
[file a.py]
5876+
from typing import Dict
5877+
def d() -> Dict[int, str]: pass
5878+
5879+
[file a.py.2]
5880+
from typing import Dict
5881+
def d() -> Dict[int, int]: pass
5882+
5883+
[builtins fixtures/dict.pyi]
5884+
[out]
5885+
==
5886+
main:5: error: Argument 1 to "update" of "dict" has incompatible type "Dict[int, int]"; expected "Mapping[int, str]"

test-data/unit/pythoneval.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,3 +1259,14 @@ class B:
12591259
[out]
12601260
_testInvalidSlots.py:2: error: Incompatible types in assignment (expression has type "int", base class "object" defined the type as "Union[str, Iterable[str], None]")
12611261
_testInvalidSlots.py:4: error: Incompatible types in assignment (expression has type "Tuple[int, int]", base class "object" defined the type as "Union[str, Iterable[str], None]")
1262+
1263+
[case testDictWithStarStarSpecialCase]
1264+
from typing import Dict
1265+
1266+
def f() -> Dict[int, str]:
1267+
return {1: '', **d()}
1268+
1269+
def d() -> Dict[int, int]:
1270+
return {}
1271+
[out]
1272+
_testDictWithStarStarSpecialCase.py:4: error: Argument 1 to "update" of "dict" has incompatible type "Dict[int, int]"; expected "Mapping[int, str]"

0 commit comments

Comments
 (0)