Skip to content

Commit 08fb8d1

Browse files
committed
fix some potential errors and add more unit test
1 parent fcd5855 commit 08fb8d1

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

mypy/checker.py

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,36 +2483,45 @@ def check_assignment_to_multiple_lvalues(self, lvalues: List[Lvalue], rvalue: Ex
24832483
# control in cases like: a, b = [int, str] where rhs would get
24842484
# type List[object]
24852485
rvalues = [] # type: List[Expression]
2486-
lhs_len = len(lvalues)
2487-
idx_of_iterable = []
2488-
item_type_of_iterable = [] # type: List['mypy.types.Type']
2489-
idx = 0
2490-
for rval in rvalue.items:
2486+
iterable_type = None # type: Optional[Type]
2487+
last_idx = None # type: Optional[int]
2488+
for idx_rval, rval in enumerate(rvalue.items):
24912489
if isinstance(rval, StarExpr):
24922490
typs = get_proper_type(self.expr_checker.visit_star_expr(rval).type)
24932491
if isinstance(typs, TupleType):
24942492
rvalues.extend([TempNode(typ) for typ in typs.items])
2495-
lhs_len -= len(typs.items)
2496-
idx += len(typs.items)
24972493
elif self.type_is_iterable(typs) and isinstance(typs, Instance):
2498-
item_type_of_iterable.append(self.iterable_item_type(typs))
2499-
idx_of_iterable.append(idx)
2494+
if (iterable_type is not None and
2495+
iterable_type != self.iterable_item_type(typs)):
2496+
self.fail("Contiguous iterable with same type expected", context)
2497+
else:
2498+
if last_idx is None or last_idx + 1 == idx_rval:
2499+
rvalues.append(rval)
2500+
last_idx = idx_rval
2501+
iterable_type = self.iterable_item_type(typs)
2502+
else:
2503+
self.fail("Contiguous iterable with same type expected", context)
25002504
else:
2501-
self.fail("StarExpr should not be a '{}'".format(typs), context)
2505+
self.fail("Invalid type '{}' for *expr (iterable expected)".format(typs),
2506+
context)
25022507
else:
25032508
rvalues.append(rval)
2504-
lhs_len -= 1
2505-
idx += 1
2506-
num_every_iterable = 0
2507-
num_last_iterable = 0
2508-
if len(idx_of_iterable):
2509-
num_every_iterable = int(lhs_len / len(idx_of_iterable))
2510-
num_last_iterable = lhs_len - (len(idx_of_iterable) - 1) * int(num_every_iterable)
2511-
for i, (idx, item_type) in enumerate(zip(idx_of_iterable, item_type_of_iterable)):
2512-
if i == (len(idx_of_iterable) - 1):
2513-
rvalues[idx:idx] = [TempNode(item_type) for _ in range(num_last_iterable)]
2514-
else:
2515-
rvalues[idx:idx] = [TempNode(item_type) for _ in range(num_every_iterable)]
2509+
iterable_start = None # type: Optional[int]
2510+
iterable_end = None # type: Optional[int]
2511+
for i, rval in enumerate(rvalues):
2512+
if isinstance(rval, StarExpr):
2513+
typs = get_proper_type(self.expr_checker.visit_star_expr(rval).type)
2514+
if self.type_is_iterable(typs) and isinstance(typs, Instance):
2515+
if iterable_start is None:
2516+
iterable_start = i
2517+
iterable_end = i
2518+
if iterable_start is not None:
2519+
iterable_num = iterable_end - iterable_start + 1
2520+
rvalue_needed = len(lvalues) - (len(rvalues) - iterable_num)
2521+
if rvalue_needed > 0:
2522+
rvalues = rvalues[0: iterable_start] + [TempNode(iterable_type)
2523+
for i in range(rvalue_needed)] + rvalues[iterable_end + 1:]
2524+
25162525
if self.check_rvalue_count_in_assignment(lvalues, len(rvalues), context):
25172526
star_index = next((i for i, lv in enumerate(lvalues) if
25182527
isinstance(lv, StarExpr)), len(lvalues))

test-data/unit/check-tuples.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,4 +1445,16 @@ reveal_type(y3) # N: Revealed type is 'builtins.int*'
14451445
reveal_type(y4) # N: Revealed type is 'builtins.int*'
14461446
reveal_type(z3) # N: Revealed type is 'builtins.str'
14471447

1448+
x5, x6, y5, y6, z4 = *points2, *points2, "test"
1449+
1450+
reveal_type(x5) # N: Revealed type is 'builtins.int*'
1451+
reveal_type(x6) # N: Revealed type is 'builtins.int*'
1452+
reveal_type(y6) # N: Revealed type is 'builtins.int*'
1453+
reveal_type(y6) # N: Revealed type is 'builtins.int*'
1454+
reveal_type(z4) # N: Revealed type is 'builtins.str'
1455+
1456+
points3 = ["test1", "test2"]
1457+
x7, x8, y7, y8 = *points2, *points3 # E: Contiguous iterable with same type expected
1458+
1459+
x9, y9, y10, z9, y10 = *points2, 1, *points2 # E: Contiguous iterable with same type expected
14481460
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)