def buildTryFinallyNode(provider, node, source_ref): # Try/finally node statements. return StatementTryFinally( tried=buildStatementsNode(provider=provider, nodes=node.body, source_ref=source_ref), final=buildStatementsNode(provider=provider, nodes=node.finalbody, source_ref=source_ref), source_ref=source_ref)
def buildTryNode(provider, node, source_ref): # Note: This variant is used for Python3.3 or higher only, older stuff uses the above # ones, this one merges try/except with try/finally in the "ast". We split it up # again, as it's logically separated of course. return StatementTryFinally(tried=StatementsSequence( statements=(buildTryExceptionNode(provider=provider, node=node, source_ref=source_ref), ), source_ref=source_ref), final=buildStatementsNode( provider=provider, nodes=node.finalbody, source_ref=source_ref), source_ref=source_ref)
def makeTryFinallyStatement(tried, final, source_ref): if type(tried) in (tuple, list): tried = StatementsSequence( statements = tried, source_ref = source_ref ) if type(final) in (tuple, list): final = StatementsSequence( statements = final, source_ref = source_ref ) if tried is not None and not tried.isStatementsSequence(): tried = makeStatementsSequenceFromStatement(tried) if final is not None and not final.isStatementsSequence(): final = makeStatementsSequenceFromStatement(final) return StatementTryFinally( tried = tried, final = final, public_exc = False, source_ref = source_ref )
def buildExecNode(provider, node, source_ref): # "exec" statements, should only occur with Python2. exec_globals = node.globals exec_locals = node.locals body = node.body orig_globals = exec_globals # Handle exec(a,b,c) to be same as exec a, b, c if exec_locals is None and exec_globals is None and \ getKind(body) == "Tuple": parts = body.elts body = parts[0] if len(parts) > 1: exec_globals = parts[1] if len(parts) > 2: exec_locals = parts[2] else: return StatementRaiseException( exception_type=ExpressionBuiltinExceptionRef( exception_name="TypeError", source_ref=source_ref), exception_value=ExpressionConstantRef(constant="""\ exec: arg 1 must be a string, file, or code object""", source_ref=source_ref), exception_trace=None, exception_cause=None, source_ref=source_ref) if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if orig_globals is None: provider.markAsUnqualifiedExecContaining(source_ref) temp_scope = provider.allocateTempScope("exec") globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider=provider, globals_node=buildNode(provider, exec_globals, source_ref, True), locals_node=buildNode(provider, exec_locals, source_ref, True), temp_scope=temp_scope, source_ref=source_ref) source_code = buildNode(provider, body, source_ref) source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="source") # Source needs some special treatment for eval, if it's a string, it # must be stripped. file_fixup = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source=ExpressionCallEmpty(called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), attribute_name="read", source_ref=source_ref), source_ref=source_ref), source_ref=source_ref) ] statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source=source_code, source_ref=source_ref, ), StatementConditional(condition=ExpressionBuiltinIsinstance( cls=ExpressionBuiltinAnonymousRef( builtin_name="file", source_ref=source_ref, ), instance=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref), yes_branch=StatementsSequence( statements=file_fixup, source_ref=source_ref), no_branch=None, source_ref=source_ref), StatementExec(source_code=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), globals_arg=globals_ref, locals_arg=locals_ref, source_ref=source_ref)) tried.setChild("statements", tried.getStatements() + statements) final.setStatements(final.getStatements() + ( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), )) return StatementTryFinally(tried=tried, final=final, public_exc=False, source_ref=source_ref)
def buildTryFinallyNode(provider, build_tried, node, source_ref): if Utils.python_version < 300: # Prevent "continue" statements in the final blocks pushBuildContext("finally") final = buildStatementsNode( provider = provider, nodes = node.finalbody, source_ref = source_ref ) popBuildContext() return StatementTryFinally( tried = build_tried(), final = final, public_exc = Utils.python_version >= 300, # TODO: Use below code source_ref = source_ref ) else: temp_scope = provider.allocateTempScope("try_finally") tmp_indicator_var = provider.allocateTempVariable( temp_scope = temp_scope, name = "unhandled_indicator" ) pushIndicatorVariable(tmp_indicator_var) statements = ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref.atInternal() ), build_tried(), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), source = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref.atInternal() ) ) # Prevent "continue" statements in the final blocks pushBuildContext("finally") final = buildStatementsNode( provider = provider, nodes = node.finalbody, source_ref = source_ref ) popBuildContext() popIndicatorVariable() tried = StatementsSequence( statements = mergeStatements(statements, allow_none = True), source_ref = source_ref ) prelude = StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), right = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( StatementPreserveFrameException( source_ref = source_ref.atInternal() ), StatementPublishException( source_ref = source_ref.atInternal() ) ), source_ref = source_ref.atInternal() ), no_branch = None, source_ref = source_ref.atInternal() ) postlude = ( StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), right = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), tolerant = False, source_ref = source_ref.atInternal() ), StatementReraiseFrameException( source_ref = source_ref.atInternal() ), ), source_ref = source_ref.atInternal() ), no_branch = StatementsSequence( statements = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), tolerant = False, source_ref = source_ref.atInternal() ), ), source_ref = source_ref.atInternal() ), source_ref = source_ref.atInternal() ), ) final = StatementsSequence( statements = mergeStatements( ( prelude, makeTryFinallyStatement( tried = final, final = postlude, source_ref = source_ref.atInternal() ), ) ), source_ref = source_ref.atInternal() ) return StatementTryFinally( tried = tried, final = final, public_exc = True, source_ref = source_ref )
def buildExecNode(provider, node, source_ref): # "exec" statements, should only occur with Python2. # This is using many variables, due to the many details this is # dealing with. The locals and globals need to be dealt with in # temporary variables, and we need handling of indicators, so # that is just the complexity, pylint: disable=R0914 exec_globals = node.globals exec_locals = node.locals body = node.body orig_globals = exec_globals # Handle exec(a,b,c) to be same as exec a, b, c if exec_locals is None and exec_globals is None and \ getKind(body) == "Tuple": parts = body.elts body = parts[0] if len(parts) > 1: exec_globals = parts[1] if len(parts) > 2: exec_locals = parts[2] else: return StatementRaiseException( exception_type=ExpressionBuiltinExceptionRef( exception_name="TypeError", source_ref=source_ref), exception_value=ExpressionConstantRef(constant="""\ exec: arg 1 must be a string, file, or code object""", source_ref=source_ref), exception_trace=None, exception_cause=None, source_ref=source_ref) if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if orig_globals is None: provider.markAsUnqualifiedExecContaining(source_ref) temp_scope = provider.allocateTempScope("exec") locals_value = buildNode(provider, exec_locals, source_ref, True) if locals_value is None: locals_value = ExpressionConstantRef(constant=None, source_ref=source_ref) globals_value = buildNode(provider, exec_globals, source_ref, True) if globals_value is None: globals_value = ExpressionConstantRef(constant=None, source_ref=source_ref) source_code = buildNode(provider, body, source_ref) source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="exec_source") globals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="globals") locals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="locals") plain_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="plain") tried = makeStatementsSequenceFromStatements( # First evaluate the source code expressions. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable, source_ref=source_ref), source=source_code, source_ref=source_ref), # Assign globals and locals temporary the values given, then fix it # up, taking note in the "plain" temporary variable, if it was an # "exec" statement with None arguments, in which case the copy back # will be necessary. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), source=globals_value, source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source=locals_value, source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparisonIs(left=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantRef( constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), source=ExpressionBuiltinGlobals(source_ref=source_ref), source_ref=source_ref, ), StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source=ExpressionBuiltinLocals( source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=True, source_ref=source_ref), source_ref=source_ref, )), no_branch=None, source_ref=source_ref), ), no_branch=makeStatementsSequenceFromStatements( StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), source_ref=source_ref, )), no_branch=None, source_ref=source_ref)), source_ref=source_ref), # Source needs some special treatment for not done for "eval", if it's a # file object, then must be read. StatementConditional( condition=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef(variable=source_variable, source_ref=source_ref), classes=ExpressionBuiltinAnonymousRef( builtin_name="file", source_ref=source_ref, ), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable, source_ref=source_ref), source=ExpressionCallEmpty( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=source_variable, source_ref=source_ref), attribute_name="read", source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref), StatementTryFinally( tried=makeStatementsSequenceFromStatement(statement=StatementExec( source_code=ExpressionTempVariableRef(variable=source_variable, source_ref=source_ref), globals_arg=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), locals_arg=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source_ref=source_ref)), final=makeStatementsSequenceFromStatements( StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementLocalsDictSync( locals_arg=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref, ), source_ref=source_ref.atInternal())), no_branch=None, source_ref=source_ref), ), public_exc=False, source_ref=source_ref)) final = makeStatementsSequenceFromStatements( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=source_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), ) return StatementTryFinally(tried=tried, final=final, public_exc=False, source_ref=source_ref)
def _buildWithNode( provider, context_expr, assign_target, body, source_ref ): with_source = buildNode( provider, context_expr, source_ref ) result = StatementTempBlock( source_ref = source_ref ) tmp_source_variable = result.getTempVariable( "with_source" ) tmp_exit_variable = result.getTempVariable( "with_exit" ) tmp_enter_variable = result.getTempVariable( "with_enter" ) tmp_indicator_variable = result.getTempVariable( "indicator" ) statements = ( buildAssignmentStatements( provider = provider, node = assign_target, allow_none = True, source = ExpressionTempVariableRef( variable = tmp_enter_variable.makeReference( result ), source_ref = source_ref ), source_ref = source_ref ), body ) with_body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) # The "__enter__" and "__exit__" were normal attribute lookups under CPython2.6, but # that changed with CPython2.7. if Utils.python_version < 270: attribute_lookup_class = ExpressionAttributeLookup else: attribute_lookup_class = ExpressionSpecialAttributeLookup statements = [ # First assign the with context to a temporary variable. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_source_variable.makeReference( result ), source_ref = source_ref ), source = with_source, source_ref = source_ref ), # Next, assign "__enter__" and "__exit__" attributes to temporary variables. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_exit_variable.makeReference( result ), source_ref = source_ref ), source = attribute_lookup_class( expression = ExpressionTempVariableRef( variable = tmp_source_variable.makeReference( result ), source_ref = source_ref ), attribute_name = "__exit__", source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_enter_variable.makeReference( result ), source_ref = source_ref ), source = ExpressionCallEmpty( called = attribute_lookup_class( expression = ExpressionTempVariableRef( variable = tmp_source_variable.makeReference( result ), source_ref = source_ref ), attribute_name = "__enter__", source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_variable.makeReference( result ), source_ref = source_ref ), source = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ), ] source_ref = source_ref.atInternal() statements += [ StatementTryFinally( tried = makeStatementsSequenceFromStatement( statement = makeTryExceptSingleHandlerNode( tried = with_body, exception_name = "BaseException", handler_body = StatementsSequence( statements = ( # Prevents final block from calling __exit__ as well. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_variable.makeReference( result ), source_ref = source_ref ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), StatementConditional( condition = ExpressionCallNoKeywords( called = ExpressionTempVariableRef( variable = tmp_exit_variable.makeReference( result ), source_ref = source_ref ), args = ExpressionMakeTuple( elements = ( ExpressionCaughtExceptionTypeRef( source_ref = source_ref ), ExpressionCaughtExceptionValueRef( source_ref = source_ref ), ExpressionCaughtExceptionTracebackRef( source_ref = source_ref ), ), source_ref = source_ref ), source_ref = source_ref ), no_branch = makeStatementsSequenceFromStatement( statement = StatementRaiseException( exception_type = None, exception_value = None, exception_trace = None, exception_cause = None, source_ref = source_ref ) ), yes_branch = None, source_ref = source_ref ), ), source_ref = source_ref ), source_ref = source_ref ), ), final = makeStatementsSequenceFromStatement( statement = StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_variable.makeReference( result ), source_ref = source_ref ), right = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementExpressionOnly( expression = ExpressionCallNoKeywords( called = ExpressionTempVariableRef( variable = tmp_exit_variable.makeReference( result ), source_ref = source_ref ), args = ExpressionConstantRef( constant = ( None, None, None ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref ) ), source_ref = source_ref ) ] result.setBody( StatementsSequence( statements = statements, source_ref = source_ref ) ) return result
def buildForLoopNode(provider, node, source_ref): # The for loop is re-formulated according to developer manual. An iterator # is created, and looped until it gives StopIteration. The else block is # taken if a for loop exits normally, i.e. because of iterator # exhaustion. We do this by introducing an indicator variable. source = buildNode(provider, node.iter, source_ref) temp_scope = provider.allocateTempScope("for_loop") tmp_iter_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="for_iterator") tmp_value_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="iter_value") else_block = buildStatementsNode( provider=provider, nodes=node.orelse if node.orelse else None, source_ref=source_ref) if else_block is not None: tmp_break_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="break_indicator") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator_variable.makeReference( provider), source_ref=source_ref), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref) ] else: statements = [] statements.append(StatementBreakLoop(source_ref=source_ref.atInternal())) handler_body = makeStatementsSequence(statements=statements, allow_none=False, source_ref=source_ref) statements = (makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference(provider), source_ref=source_ref), source=ExpressionBuiltinNext1(value=ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=handler_body, source_ref=source_ref), buildAssignmentStatements( provider=provider, node=node.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref)) statements += (buildStatementsNode(provider=provider, nodes=node.body, source_ref=source_ref), ) loop_body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) if else_block is not None: statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator_variable.makeReference( provider), source_ref=source_ref), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=source_ref) ] else: statements = [] cleanup_statements = ( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref.atInternal()), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(provider), source_ref=source_ref), tolerant=False, source_ref=source_ref.atInternal())) statements += [ # First create the iterator and store it. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(provider), source_ref=source_ref), source=ExpressionBuiltinIter1( value=source, source_ref=source.getSourceReference()), source_ref=source_ref), StatementTryFinally(tried=makeStatementsSequenceFromStatement( statement=StatementLoop(body=loop_body, source_ref=source_ref)), final=StatementsSequence( statements=cleanup_statements, source_ref=source_ref.atInternal()), source_ref=source_ref.atInternal()) ] if else_block is not None: statements += [ StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator_variable.makeReference( provider), source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=else_block, no_branch=None, source_ref=source_ref) ] return StatementsSequence(statements=statements, source_ref=source_ref)
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source, source_ref): # This is using many variable names on purpose, so as to give names to the # unpacked detail values, pylint: disable=R0914 if kind == "Name": variable_ref = detail return StatementAssignmentVariable(variable_ref=variable_ref, source=source, source_ref=source_ref) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute(expression=lookup_source, attribute_name=attribute_name, source=source, source_ref=source_ref) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript(expression=subscribed, subscript=subscript, source=source, source_ref=source_ref) elif kind == "Slice": lookup_source, lower, upper = detail return StatementAssignmentSlice(expression=lookup_source, lower=lower, upper=upper, source=source, source_ref=source_ref) elif kind == "Tuple": temp_scope = provider.allocateTempScope("tuple_unpack") source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="source_iter") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_iter_var.makeReference(provider), source_ref=source_ref), source=ExpressionBuiltinIter1(value=source, source_ref=source_ref), source_ref=source_ref) ] element_vars = [ provider.allocateTempVariable(temp_scope=temp_scope, name="element_%d" % (element_index + 1)) for element_index in range(len(detail)) ] starred = False for element_index, element in enumerate(detail): element_var = element_vars[element_index] if element[0] != "Starred": statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=element_var.makeReference(provider), source_ref=source_ref), source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=source_iter_var.makeReference( provider), source_ref=source_ref), count=element_index + 1, source_ref=source_ref), source_ref=source_ref)) else: starred = True statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=element_var.makeReference(provider), source_ref=source_ref), source=ExpressionBuiltinList( value=ExpressionTempVariableRef( variable=source_iter_var.makeReference( provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)) if not starred: statements.append( StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef( variable=source_iter_var.makeReference(provider), source_ref=source_ref), count=len(detail), source_ref=source_ref)) for element_index, element in enumerate(detail): if element[0] == "Starred": element = element[1] element_var = element_vars[element_index] statements.append( buildAssignmentStatementsFromDecoded( provider=provider, kind=element[0], detail=element[1], source=ExpressionTempVariableRef( variable=element_var.makeReference(provider), source_ref=source_ref), source_ref=source_ref)) final_statements = [] final_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=source_iter_var.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref)) # TODO: In that order, or reversed. for element_var in element_vars: final_statements.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=element_var.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref)) return StatementTryFinally( tried=StatementsSequence(statements=statements, source_ref=source_ref), final=StatementsSequence(statements=final_statements, source_ref=source_ref), source_ref=source_ref) else: assert False, (kind, source_ref, detail)