Beispiel #1
0
 def selectNextBuiltinClass(iterator, default, source_ref):
     if default is None:
         return ExpressionBuiltinNext1(value=iterator,
                                       source_ref=source_ref)
     else:
         return ExpressionBuiltinNext2(iterator=iterator,
                                       default=default,
                                       source_ref=source_ref)
Beispiel #2
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

    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, "dict")
    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),
        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=(ExpressionOperationBinary(
                        operator="Mod",
                        left=ExpressionConstantRef(
                            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),
    )

    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 _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 _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 getSetUnpackingHelper():
    helper_name = "_unpack_set"

    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, "set")
    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 = 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_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   = 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 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