@@ -2483,36 +2483,45 @@ def check_assignment_to_multiple_lvalues(self, lvalues: List[Lvalue], rvalue: Ex
2483
2483
# control in cases like: a, b = [int, str] where rhs would get
2484
2484
# type List[object]
2485
2485
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 ):
2491
2489
if isinstance (rval , StarExpr ):
2492
2490
typs = get_proper_type (self .expr_checker .visit_star_expr (rval ).type )
2493
2491
if isinstance (typs , TupleType ):
2494
2492
rvalues .extend ([TempNode (typ ) for typ in typs .items ])
2495
- lhs_len -= len (typs .items )
2496
- idx += len (typs .items )
2497
2493
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 )
2500
2504
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 )
2502
2507
else :
2503
2508
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
+
2516
2525
if self .check_rvalue_count_in_assignment (lvalues , len (rvalues ), context ):
2517
2526
star_index = next ((i for i , lv in enumerate (lvalues ) if
2518
2527
isinstance (lv , StarExpr )), len (lvalues ))
0 commit comments