@@ -327,28 +327,59 @@ def visit_Try(self, node):
327327 return ControlFlowNode (try_node , last_statements , break_statements = body .break_statements )
328328
329329 def assign_tuple_target (self , node , right_hand_side_variables ):
330- new_assignment_nodes = list ()
331- for i , target in enumerate (node .targets [0 ].elts ):
332- value = node .value .elts [i ]
330+ new_assignment_nodes = []
331+ remaining_variables = list (right_hand_side_variables )
332+ remaining_targets = list (node .targets [0 ].elts )
333+ remaining_values = list (node .value .elts ) # May contain duplicates
333334
335+ def visit (target , value ):
334336 label = LabelVisitor ()
335337 label .visit (target )
336- 338+ rhs_visitor = RHSVisitor ()
339+ rhs_visitor .visit (value )
337340 if isinstance (value , ast .Call ):
338341 new_ast_node = ast .Assign (target , value )
339- new_ast_node .lineno = node .lineno
340- 342+ ast .copy_location (new_ast_node , node )
341343 new_assignment_nodes .append (self .assignment_call_node (label .result , new_ast_node ))
342- 343344 else :
344345 label .result += ' = '
345346 label .visit (value )
346- 347347 new_assignment_nodes .append (self .append_node (AssignmentNode (
348348 label .result ,
349349 extract_left_hand_side (target ),
350350 ast .Assign (target , value ),
351- right_hand_side_variables ,
351+ rhs_visitor .result ,
352+ line_number = node .lineno ,
353+ path = self .filenames [- 1 ]
354+ )))
355+ remaining_targets .remove (target )
356+ remaining_values .remove (value )
357+ for var in rhs_visitor .result :
358+ remaining_variables .remove (var )
359+ 360+ # Pair targets and values until a Starred node is reached
361+ for target , value in zip (node .targets [0 ].elts , node .value .elts ):
362+ if isinstance (target , ast .Starred ) or isinstance (value , ast .Starred ):
363+ break
364+ visit (target , value )
365+ 366+ # If there was a Starred node, pair remaining targets and values from the end
367+ for target , value in zip (reversed (list (remaining_targets )), reversed (list (remaining_values ))):
368+ if isinstance (target , ast .Starred ) or isinstance (value , ast .Starred ):
369+ break
370+ visit (target , value )
371+ 372+ if remaining_targets :
373+ label = LabelVisitor ()
374+ label .handle_comma_separated (remaining_targets )
375+ label .result += ' = '
376+ label .handle_comma_separated (remaining_values )
377+ for target in remaining_targets :
378+ new_assignment_nodes .append (self .append_node (AssignmentNode (
379+ label .result ,
380+ extract_left_hand_side (target ),
381+ ast .Assign (target , remaining_values [0 ]),
382+ remaining_variables ,
352383 line_number = node .lineno ,
353384 path = self .filenames [- 1 ]
354385 )))
@@ -380,8 +411,8 @@ def assign_multi_target(self, node, right_hand_side_variables):
380411 def visit_Assign (self , node ):
381412 rhs_visitor = RHSVisitor ()
382413 rhs_visitor .visit (node .value )
383- if isinstance (node .targets [0 ], ast .Tuple ): # x,y = [1,2]
384- if isinstance (node .value , ast .Tuple ):
414+ if isinstance (node .targets [0 ], ( ast .Tuple , ast . List ) ): # x,y = [1,2]
415+ if isinstance (node .value , ( ast .Tuple , ast . List ) ):
385416 return self .assign_tuple_target (node , rhs_visitor .result )
386417 elif isinstance (node .value , ast .Call ):
387418 call = None
0 commit comments