@@ -2483,36 +2483,47 @@ 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
2495+ and 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+ and iterable_end is not None
2520+ and iterable_type is not None ):
2521+ iterable_num = iterable_end - iterable_start + 1
2522+ rvalue_needed = len (lvalues ) - (len (rvalues ) - iterable_num )
2523+ if rvalue_needed > 0 :
2524+ rvalues = rvalues [0 : iterable_start ] + [TempNode (iterable_type )
2525+ for i in range (rvalue_needed )] + rvalues [iterable_end + 1 :]
2526+
25162527 if self .check_rvalue_count_in_assignment (lvalues , len (rvalues ), context ):
25172528 star_index = next ((i for i , lv in enumerate (lvalues ) if
25182529 isinstance (lv , StarExpr )), len (lvalues ))
0 commit comments