Skip to content

Commit aaafd15

Browse files
Michael0x2amsullivan
authored andcommitted
Fix iterable unpacking so star args are always of type list (#5165)
Consider the following program: from typing import Iterable, Iterator, Tuple class SomeIterable(Iterable[int]): def __iter__(self) -> Iterator[int]: return [1, 2, 3].__iter__() a = SomeIterable() b: Tuple[int, ...] = (1, 2, 3) a1, *a2 = a b1, *b2 = b reveal_type(a2) reveal_type(b2) Previously, the revealed types were `SomeIterable` and `builtins.tuple[int]`: mypy assumed that `a2` and `b2` will have the same type as whatever is on the right-hand side. However, at runtime, both `a2` and `b2` are actually of type `List[int]`. Fix that.
1 parent 8b9f205 commit aaafd15

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

mypy/checker.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,8 @@ def check_multi_assignment_from_iterable(self, lvalues: List[Lvalue], rvalue_typ
20172017
item_type = self.iterable_item_type(cast(Instance, rvalue_type))
20182018
for lv in lvalues:
20192019
if isinstance(lv, StarExpr):
2020-
self.check_assignment(lv.expr, self.temp_node(rvalue_type, context),
2020+
items_type = self.named_generic_type('builtins.list', [item_type])
2021+
self.check_assignment(lv.expr, self.temp_node(items_type, context),
20212022
infer_lvalue_type)
20222023
else:
20232024
self.check_assignment(lv, self.temp_node(item_type, context),

test-data/unit/check-tuples.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,29 @@ class A: pass
563563
[builtins fixtures/list.pyi]
564564
[out]
565565

566+
[case testAssignmentToStarFromIterable]
567+
from typing import List, Tuple, Iterable
568+
569+
class CustomIterable(Iterable[int]): pass
570+
571+
a: List[int]
572+
b: Tuple[int, ...]
573+
c: Tuple[int, int, int]
574+
d: Iterable[int]
575+
e: CustomIterable
576+
577+
a1, *a2 = a
578+
b1, *b2 = b
579+
c1, *c2 = c
580+
d1, *d2 = d
581+
e1, *e2 = e
582+
583+
reveal_type(a2) # E: Revealed type is 'builtins.list[builtins.int*]'
584+
reveal_type(b2) # E: Revealed type is 'builtins.list[builtins.int*]'
585+
reveal_type(c2) # E: Revealed type is 'builtins.list[builtins.int*]'
586+
reveal_type(d2) # E: Revealed type is 'builtins.list[builtins.int]'
587+
reveal_type(e2) # E: Revealed type is 'builtins.list[builtins.int]'
588+
[builtins fixtures/tuple.pyi]
566589

567590
-- Nested tuple assignment
568591
-- ----------------------------

test-data/unit/check-unions.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ good: Union[List[int], List[str]]
752752

753753
x, *y, z = lst = good
754754
reveal_type(x) # E: Revealed type is 'Union[builtins.int*, builtins.str*]'
755-
reveal_type(y) # E: Revealed type is 'Union[builtins.list[builtins.int], builtins.list[builtins.str]]'
755+
reveal_type(y) # E: Revealed type is 'Union[builtins.list[builtins.int*], builtins.list[builtins.str*]]'
756756
reveal_type(z) # E: Revealed type is 'Union[builtins.int*, builtins.str*]'
757757
reveal_type(lst) # E: Revealed type is 'Union[builtins.list[builtins.int], builtins.list[builtins.str]]'
758758
[builtins fixtures/list.pyi]

0 commit comments

Comments
 (0)