def getClassBasesMroConversionHelper(): helper_name = "_mro_entries_conversion" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=("bases", ), ps_pos_only_args=(), ps_list_star_arg=None, ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ), inline_const_args=False, # TODO: Allow this. ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "base") args_variable = result.getVariableForAssignment(variable_name="bases") non_type_case = makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionListOperationExtend( list_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=makeExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), args=makeExpressionMakeTuple( elements=(ExpressionVariableRef( variable=args_variable, source_ref=internal_source_ref), ), source_ref=internal_source_ref, ), kw=None, source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), no_branch=StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ) type_case = StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ) loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), makeStatementConditional( condition=ExpressionConditionalAnd( left=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode( constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), right=ExpressionBuiltinIssubclass( cls=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode( constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), yes_branch=type_case, no_branch=non_type_case, source_ref=internal_source_ref, ), ) final = ( StatementReleaseVariable(variable=args_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=[], source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(loop_body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionBuiltinTuple( value=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) result.setChild( "body", makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, )), ) return result
def getSetUnpackingHelper(): helper_name = "_unpack_set" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=(), ps_list_star_arg="args", ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ps_pos_only_args=(), ), ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "set") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementExpressionOnly( expression=ExpressionSetOperationUpdate( set_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) args_variable = result.getVariableForAssignment(variable_name="args") final = ( StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=set(), source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, ))) return result
def getDictUnpackingHelper(): helper_name = "_unpack_dict" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( ps_name = helper_name, ps_normal_args = (), ps_list_star_arg = "args", ps_dict_star_arg = None, ps_default_count = 0, ps_kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "dict") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable = tmp_item_variable, source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), makeTryExceptSingleHandlerNode( tried = StatementDictOperationUpdate( dict_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "AttributeError", handler_body = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "TypeError", args = ( makeBinaryOperationNode( operator = "Mod", left = makeConstantRefNode( constant = """\ '%s' object is not a mapping""", source_ref = internal_source_ref, user_provided = True ), right = ExpressionMakeTuple( elements = ( ExpressionAttributeLookup( source = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), attribute_name = "__name__", source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), # We get handed our args responsibility. StatementDelVariable( variable = args_variable, tolerant = False, source_ref = internal_source_ref ) ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable = tmp_iter_variable, source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable = tmp_result_variable, source = makeConstantRefNode( constant = {}, source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def _buildContractionBodyNode( provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, function_body, for_asyncgen, source_ref, ): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=too-many-branches,too-many-locals # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. tmp_variables = [] if emit_class is not ExpressionYield: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) statements = [] # First assign the iterator if we are an outline. if assign_provider: statements.append( StatementAssignmentVariable( variable=iter_tmp, source=_makeIteratorCreation( provider=provider, qual=node.generators[0], for_asyncgen=False, source_ref=source_ref, ), source_ref=source_ref.atInternal(), )) if for_asyncgen and python_version >= 370 and node.generators[0].is_async: statements.append( StatementAssignmentVariable( variable=iter_tmp, source=ExpressionTempVariableRef(variable=iter_tmp, source_ref=source_ref), source_ref=source_ref, )) if start_value is not None: statements.append( StatementAssignmentVariable( variable=container_tmp, source=makeConstantRefNode(constant=start_value, source_ref=source_ref), source_ref=source_ref.atInternal(), )) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class( ExpressionTempVariableRef(variable=container_tmp, source_ref=source_ref), buildNode( provider=function_body if not assign_provider else provider, node=node.elt, source_ref=source_ref, ), source_ref=source_ref, ) else: assert emit_class is ExpressionYield current_body = emit_class( buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref, ) else: current_body = emit_class( dict_arg=ExpressionTempVariableRef(variable=container_tmp, source_ref=source_ref), key=buildNode( provider=function_body if not assign_provider else provider, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body if not assign_provider else provider, node=node.value, source_ref=source_ref, ), source_ref=source_ref, ) if current_body.isExpression(): current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode(variable=iter_tmp, source_ref=source_ref) if for_asyncgen and python_version >= 370: iterator_ref = ExpressionYieldFromWaitable( expression=iterator_ref, source_ref=source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = _makeIteratorCreation( provider=provider if assign_provider else function_body, qual=qual, for_asyncgen=False, source_ref=source_ref, ) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable=tmp_iter_variable, source=value_iterator, source_ref=source_ref, ) ] iterator_ref = ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_value_variable, source=_makeIteratorNext(iterator_ref=iterator_ref, qual=qual, source_ref=source_ref), source_ref=source_ref, ), exception_name=_getStopIterationName(qual), handler_body=StatementLoopBreak(source_ref=source_ref), source_ref=source_ref, ), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef(variable=tmp_value_variable, source_ref=source_ref), source_ref=source_ref, ), ] conditions = buildNodeList( provider=provider if assign_provider else function_body, nodes=qual.ifs, source_ref=source_ref, ) if len(conditions) >= 1: loop_statements.append( makeStatementConditional( condition=buildAndNode(values=conditions, source_ref=source_ref), yes_branch=current_body, no_branch=None, source_ref=source_ref, )) else: loop_statements.append(current_body) nested_statements.append( StatementLoop( body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref, )) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable(variable=tmp_iter_variable, source_ref=source_ref)) current_body = StatementsSequence(statements=mergeStatements( nested_statements, False), source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) release_statements = [ StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) for tmp_variable in tmp_variables ] return statements, release_statements
def buildWhileLoopNode(provider, node, source_ref): # The while loop is re-formulated according to developer manual. The # condition becomes an early condition to break the loop. The else block is # taken if a while loop exits normally, i.e. because of condition not being # true. We do this by introducing an indicator variable. else_block = buildStatementsNode( provider=provider, nodes=node.orelse if node.orelse else None, source_ref=source_ref, ) if else_block is not None: temp_scope = provider.allocateTempScope("while_loop") tmp_break_indicator = provider.allocateTempVariable( temp_scope=temp_scope, name="break_indicator" ) statements = ( StatementAssignmentVariable( variable=tmp_break_indicator, source=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), StatementLoopBreak(source_ref=source_ref), ) else: statements = (StatementLoopBreak(source_ref=source_ref),) pushBuildContext("loop_body") loop_statements = buildStatementsNode( provider=provider, nodes=node.body, source_ref=source_ref ) popBuildContext() # The loop body contains a conditional statement at the start that breaks # the loop if it fails. loop_body = makeStatementsSequence( statements=( makeStatementConditional( condition=ExpressionOperationNOT( operand=buildNode(provider, node.test, source_ref), source_ref=source_ref, ), yes_branch=StatementsSequence( statements=statements, source_ref=source_ref ), no_branch=None, source_ref=source_ref, ), loop_statements, ), allow_none=True, source_ref=source_ref, ) loop_statement = StatementLoop(body=loop_body, source_ref=source_ref) if else_block is None: return loop_statement else: statements = ( StatementAssignmentVariable( variable=tmp_break_indicator, source=makeConstantRefNode(constant=False, source_ref=source_ref), source_ref=source_ref, ), loop_statement, makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator, source_ref=source_ref ), right=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), yes_branch=else_block, no_branch=None, source_ref=source_ref, ), ) statements = ( makeTryFinallyStatement( provider=provider, tried=statements, final=StatementReleaseVariable( variable=tmp_break_indicator, source_ref=source_ref ), source_ref=source_ref, ), ) return StatementsSequence( statements=mergeStatements(statements, False), source_ref=source_ref )
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, outer_iter_ref, temp_scope, assign_provider, source_ref, function_body): if start_value is not None: statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal()) ] if assign_provider: tmp_variables = [] else: tmp_variables = [container_tmp] else: statements = [] tmp_variables = [] if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: def makeIteratorRef(): return outer_iter_ref.makeCloneAt(source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] def makeIteratorRef(): return ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference( function_body), source_ref=source_ref), source=ExpressionBuiltinNext1(value=makeIteratorRef(), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=makeStatementsSequenceFromStatement( statement=StatementBreakLoop( source_ref=source_ref.atInternal())), public_exc=False, source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(function_body), source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) == 1: loop_statements.append( StatementConditional( condition=conditions[0], yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) elif len(conditions) > 1: loop_statements.append( StatementConditional( condition=buildAndNode(provider=function_body, values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) if tmp_iter_variable is not None: nested_statements.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), tolerant=False, source_ref=source_ref)) current_body = StatementsSequence(statements=nested_statements, source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) if emit_class is ExpressionYield: statements.insert(0, StatementGeneratorEntry(source_ref=source_ref)) del_statements = [] for tmp_variable in tmp_variables: del_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable.makeReference(function_body), source_ref=source_ref), tolerant=True, source_ref=source_ref.atInternal())) return statements, del_statements
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 = provider.allocateTempVariable( temp_scope = temp_scope, name = "break_indicator" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, 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 ) ) 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, source_ref = source_ref ), source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ), exception_name = "StopIteration", handler_body = handler_body, public_exc = False, source_ref = source_ref ), buildAssignmentStatements( provider = provider, node = node.target, source = ExpressionTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source_ref = source_ref ) ) pushBuildContext("loop_body") pushIndicatorVariable(None) statements += ( buildStatementsNode( provider = provider, nodes = node.body, source_ref = source_ref ), ) popIndicatorVariable() popBuildContext() loop_body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) cleanup_statements = [ StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ] if else_block is not None: statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ) ] else: statements = [] statements += [ # First create the iterator and store it. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source = ExpressionBuiltinIter1( value = source, source_ref = source.getSourceReference() ), source_ref = source_ref ), makeTryFinallyStatement( tried = StatementLoop( body = loop_body, source_ref = source_ref ), final = StatementsSequence( statements = cleanup_statements, source_ref = source_ref ), source_ref = source_ref ) ] if else_block is not None: statements += [ StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_break_indicator, 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 ) ] statements = ( makeTryFinallyStatement( tried = statements, final = StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), tolerant = False, source_ref = source_ref ), source_ref = source_ref ), ) return StatementsSequence( statements = statements, source_ref = source_ref )
def _buildForLoopNode(provider, node, sync, 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. # We handle async and sync both here, leading to cases, pylint: disable=too-many-locals source = buildNode(provider, node.iter, source_ref) # Temporary variables, we need one for the iterator, and one for the current # value. 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 = provider.allocateTempVariable( temp_scope = temp_scope, name = "break_indicator" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ) ] else: statements = [] statements.append( StatementLoopBreak( source_ref = source_ref ) ) handler_body = makeStatementsSequence( statements = statements, allow_none = False, source_ref = source_ref ) if sync: next_node = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source_ref = source_ref ) else: next_node = ExpressionAsyncNext( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source_ref = source_ref ) statements = ( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source = next_node, source_ref = source_ref ), exception_name = "StopIteration" if sync else "StopAsyncIteration", handler_body = handler_body, source_ref = source_ref ), buildAssignmentStatements( provider = provider, node = node.target, source = ExpressionTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source_ref = source_ref ) ) pushBuildContext("loop_body") statements += ( buildStatementsNode( provider = provider, nodes = node.body, source_ref = source_ref ), ) popBuildContext() loop_body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) cleanup_statements = [ StatementReleaseVariable( variable = tmp_value_variable, source_ref = source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = source_ref ) ] if else_block is not None: statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = makeConstantRefNode( constant = False, source_ref = source_ref ), source_ref = source_ref ) ] else: statements = [] if sync: iter_source = ExpressionBuiltinIter1( value = source, source_ref = source.getSourceReference() ) else: iter_source = ExpressionAsyncIter( value = source, source_ref = source.getSourceReference() ) statements += [ # First create the iterator and store it. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source = iter_source, source_ref = source_ref ), makeTryFinallyStatement( provider = provider, tried = StatementLoop( body = loop_body, source_ref = source_ref ), final = StatementsSequence( statements = cleanup_statements, source_ref = source_ref ), source_ref = source_ref ) ] if else_block is not None: statements += [ StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), right = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = else_block, no_branch = None, source_ref = source_ref ) ] statements = ( makeTryFinallyStatement( provider = provider, tried = statements, final = StatementReleaseVariable( variable = tmp_break_indicator, source_ref = source_ref ), source_ref = source_ref ), ) return makeStatementsSequenceFromStatements( *statements )
def _buildContractionNode(provider, node, name, emit_class, start_value, assign_provider, source_ref): # The contraction nodes are reformulated to function bodies, with loops as # described in the developer manual. They use a lot of temporary names, # nested blocks, etc. and so a lot of variable names. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. assert provider.isParentVariableProvider(), provider function_body = ExpressionFunctionBody( provider=provider, name=name, doc=None, parameters=make_contraction_parameters, source_ref=source_ref) if start_value is not None: container_tmp = function_body.allocateTempVariable(None, "result") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal()) ] else: statements = [] if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_iter_variable = function_body.allocateTempVariable( temp_scope=None, name="contraction_iter_%d" % count) tmp_value_variable = function_body.allocateTempVariable( temp_scope=None, name="iter_value_%d" % count) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: value_iterator = ExpressionVariableRef(variable_name="__iterator", source_ref=source_ref) else: value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) # First create the iterator and store it, next should be loop body nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] loop_statements = [ makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference( function_body), source_ref=source_ref), source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=makeStatementsSequenceFromStatement( statement=StatementBreakLoop( source_ref=source_ref.atInternal())), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(function_body), source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) == 1: loop_statements.append( StatementConditional( condition=conditions[0], yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) elif len(conditions) > 1: loop_statements.append( StatementConditional( condition=buildAndNode(provider=function_body, values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) nested_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), tolerant=False, source_ref=source_ref)) current_body = StatementsSequence(statements=nested_statements, source_ref=source_ref) statements.append(current_body) if start_value is not None: statements.append( StatementReturn(expression=ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source_ref=source_ref)) function_body.setBody( StatementsFrame(statements=mergeStatements(statements), guard_mode="pass_through" if emit_class is not ExpressionYield else "generator", var_names=(), arg_count=0, kw_only_count=0, has_starlist=False, has_stardict=False, code_name="contraction", source_ref=source_ref)) return ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(ExpressionBuiltinIter1( value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), ), source_ref=source_ref)
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, source_ref, function_body): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 tmp_variables = [] if assign_provider: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) # First assign the iterator if we are an outline. if assign_provider: statements = [ StatementAssignmentVariable( variable_ref=makeVariableTargetRefNode(variable=iter_tmp, source_ref=source_ref), source=ExpressionBuiltinIter1(value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref.atInternal()) ] else: statements = [] if start_value is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp, source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal())) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = ExpressionDictOperationSet( dict_arg=ExpressionTempVariableRef(variable=container_tmp, source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode(variable=iter_tmp, source_ref=source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] iterator_ref = ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable, source_ref=source_ref), source=ExpressionBuiltinNext1(value=iterator_ref, source_ref=source_ref), source_ref=source_ref), exception_name="StopIteration", handler_body=StatementBreakLoop( source_ref=source_ref.atInternal()), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef(variable=tmp_value_variable, source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) >= 1: loop_statements.append( StatementConditional( condition=buildAndNode(values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable(variable=tmp_iter_variable, source_ref=source_ref)) current_body = StatementsSequence(statements=mergeStatements( nested_statements, False), source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) if emit_class is ExpressionYield: statements.insert(0, StatementGeneratorEntry(source_ref=source_ref)) release_statements = [ StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) for tmp_variable in tmp_variables ] return statements, release_statements
def getListUnpackingHelper(): helper_name = "_unpack_list" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( name = helper_name, normal_args = (), list_star_arg = "args", dict_star_arg = None, default_count = 0, kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementExpressionOnly( expression = ExpressionListOperationExtend( list_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable_name = "args", variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source = ExpressionConstantRef( constant = [], source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_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) result = StatementTempBlock(source_ref=source_ref) tmp_iter_variable = result.getTempVariable("for_iterator") iterate_tmp_block = StatementTempBlock(source_ref=source_ref) tmp_value_variable = iterate_tmp_block.getTempVariable("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 = result.getTempVariable( "break_indicator") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator_variable.makeReference( result), 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( iterate_tmp_block), source_ref=source_ref), source=ExpressionBuiltinNext1(value=ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference(result), 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( iterate_tmp_block), source_ref=source_ref), source_ref=source_ref)) iterate_tmp_block.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) statements = (iterate_tmp_block, 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( result), source_ref=source_ref), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=source_ref) ] else: statements = [] statements += [ # First create the iterator and store it. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(result), source_ref=source_ref), source=ExpressionBuiltinIter1( value=source, source_ref=source.getSourceReference()), source_ref=source_ref), StatementLoop(body=loop_body, source_ref=source_ref) ] if else_block is not None: statements += [ StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator_variable.makeReference( result), 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) ] result.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) return result
def buildWhileLoopNode(provider, node, source_ref): # The while loop is re-formulated according to developer manual. The condition becomes # an early condition to break the loop. The else block is taken if a while loop exits # normally, i.e. because of condition not being true. We do this by introducing an # indicator variable. else_block = buildStatementsNode( provider=provider, nodes=node.orelse if node.orelse else None, source_ref=source_ref) if else_block is not None: temp_block = StatementTempBlock(source_ref=source_ref) tmp_break_indicator_variable = temp_block.getTempVariable( "break_indicator") statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator_variable.makeReference( temp_block), source_ref=source_ref), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), StatementBreakLoop(source_ref=source_ref)) else: statements = (StatementBreakLoop(source_ref=source_ref), ) # The loop body contains a conditional statement at the start that breaks the loop if # it fails. loop_body = makeStatementsSequence(statements=(StatementConditional( condition=buildNode(provider, node.test, source_ref), no_branch=StatementsSequence(statements=statements, source_ref=source_ref), yes_branch=None, source_ref=source_ref), buildStatementsNode( provider=provider, nodes=node.body, source_ref=source_ref)), allow_none=True, source_ref=source_ref) loop_statement = StatementLoop(body=loop_body, source_ref=source_ref) if else_block is None: return loop_statement else: statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator_variable.makeReference( temp_block), source_ref=source_ref), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=source_ref), loop_statement, StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator_variable. makeReference(temp_block), 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)) temp_block.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) return temp_block