@@ -648,42 +648,53 @@ async def ast_nonlocal(self, arg):
648648 for var_name in arg .names :
649649 self .curr_func .nonlocal_names .add (var_name )
650650
651- async def ast_assign (self , arg ):
652- """Execute assignment statement."""
653- val = await self .aeval (arg .value )
654- for lhs in arg .targets : # pylint: disable=too-many-nested-blocks
655- if isinstance (lhs , ast .Subscript ):
656- var = await self .aeval (lhs .value )
657- if isinstance (lhs .slice , ast .Index ):
658- ind = await self .aeval (lhs .slice .value )
659- var [ind ] = val
660- elif isinstance (lhs .slice , ast .Slice ):
661- lower = (
662- await self .aeval (lhs .slice .lower ) if lhs .slice .lower else None
663- )
664- upper = (
665- await self .aeval (lhs .slice .upper ) if lhs .slice .upper else None
666- )
667- step = await self .aeval (lhs .slice .step ) if lhs .slice .step else None
668- var [slice (lower , upper , step )] = val
651+ async def recurse_assign (self , lhs , val ):
652+ """Recursive assignment."""
653+ if isinstance (lhs , ast .Tuple ):
654+ try :
655+ val_len = len (val )
656+ except TypeError :
657+ raise TypeError ("cannot unpack non-iterable object" )
658+ if len (lhs .elts ) < val_len :
659+ raise ValueError (
660+ f"too many values to unpack (expected { len (lhs .elts )} )"
661+ )
662+ if len (lhs .elts ) > val_len :
663+ raise ValueError (f"too few values to unpack (expected { len (lhs .elts )} )" )
664+ for lhs_elt , val_elt in zip (lhs .elts , val ):
665+ await self .recurse_assign (lhs_elt , val_elt )
666+ elif isinstance (lhs , ast .Subscript ):
667+ var = await self .aeval (lhs .value )
668+ if isinstance (lhs .slice , ast .Index ):
669+ ind = await self .aeval (lhs .slice .value )
670+ var [ind ] = val
669671 else :
670- var_name = await self .aeval (lhs )
671- if var_name .find ("." ) >= 0 :
672- self .state .set (var_name , val )
673- else :
674- if self .curr_func and var_name in self .curr_func .global_names :
675- self .global_sym_table [var_name ] = val
676- elif self .curr_func and var_name in self .curr_func .nonlocal_names :
677- for sym_table in reversed (self .sym_table_stack [1 :]):
678- if var_name in sym_table :
679- sym_table [var_name ] = val
680- break
681- else :
682- raise TypeError (
683- f"can't find nonlocal '{ var_name } ' for assignment"
684- )
672+ lower = await self .aeval (lhs .slice .lower ) if lhs .slice .lower else None
673+ upper = await self .aeval (lhs .slice .upper ) if lhs .slice .upper else None
674+ step = await self .aeval (lhs .slice .step ) if lhs .slice .step else None
675+ var [slice (lower , upper , step )] = val
676+ else :
677+ var_name = await self .aeval (lhs )
678+ if var_name .find ("." ) >= 0 :
679+ self .state .set (var_name , val )
680+ else :
681+ if self .curr_func and var_name in self .curr_func .global_names :
682+ self .global_sym_table [var_name ] = val
683+ elif self .curr_func and var_name in self .curr_func .nonlocal_names :
684+ for sym_table in reversed (self .sym_table_stack [1 :]):
685+ if var_name in sym_table :
686+ sym_table [var_name ] = val
687+ break
685688 else :
686- self .sym_table [var_name ] = val
689+ raise TypeError (
690+ f"can't find nonlocal '{ var_name } ' for assignment"
691+ )
692+ else :
693+ self .sym_table [var_name ] = val
694+
695+ async def ast_assign (self , arg ):
696+ """Execute assignment statement."""
697+ await self .recurse_assign (arg .targets [0 ], await self .aeval (arg .value ))
687698
688699 async def ast_augassign (self , arg ):
689700 """Execute augmented assignment statement (lhs <BinOp>= value)."""
@@ -991,8 +1002,7 @@ async def ast_list(self, arg):
9911002
9921003 async def ast_tuple (self , arg ):
9931004 """Evaluate Tuple."""
994- if isinstance (arg .ctx , ast .Load ):
995- return tuple (await self .eval_elt_list (arg .elts ))
1005+ return tuple (await self .eval_elt_list (arg .elts ))
9961006
9971007 async def ast_dict (self , arg ):
9981008 """Evaluate dict."""
0 commit comments