示例#1
0
def _buildWithNode(provider, context_expr, assign_target, body, source_ref):
    with_source = buildNode(provider, context_expr, source_ref)

    temp_scope = provider.allocateTempScope("with")

    tmp_source_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "source"
    )
    tmp_exit_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "exit"
    )
    tmp_enter_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "enter"
    )
    tmp_indicator_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name = "indicator"
    )

    statements = (
        buildAssignmentStatements(
            provider   = provider,
            node       = assign_target,
            allow_none = True,
            source     = ExpressionTempVariableRef(
                variable   = tmp_enter_variable.makeReference(provider),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        body
    )

    with_body = makeStatementsSequence(
        statements = statements,
        allow_none = True,
        source_ref = source_ref
    )

    if Options.isFullCompat() and with_body is not None:
        with_exit_source_ref = with_body.getStatements()[-1].\
          getSourceReference()
    else:
        with_exit_source_ref = source_ref


    # The "__enter__" and "__exit__" were normal attribute lookups under
    # CPython2.6, but that changed with CPython2.7.
    if Utils.python_version < 270:
        attribute_lookup_class = ExpressionAttributeLookup
    else:
        attribute_lookup_class = ExpressionSpecialAttributeLookup

    statements = [
        # First assign the with context to a temporary variable.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_source_variable.makeReference(provider),
                source_ref = source_ref
            ),
            source       = with_source,
            source_ref   = source_ref
        ),
        # Next, assign "__enter__" and "__exit__" attributes to temporary
        # variables.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_exit_variable.makeReference(provider),
                source_ref = source_ref
            ),
            source       = attribute_lookup_class(
                expression     = ExpressionTempVariableRef(
                    variable   = tmp_source_variable.makeReference(provider),
                    source_ref = source_ref
                ),
                attribute_name = "__exit__",
                source_ref     = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_enter_variable.makeReference( provider ),
                source_ref = source_ref
            ),
            source       = ExpressionCallEmpty(
                called         = attribute_lookup_class(
                    expression     = ExpressionTempVariableRef(
                        variable   = tmp_source_variable.makeReference(
                            provider
                        ),
                        source_ref = source_ref
                    ),
                    attribute_name = "__enter__",
                    source_ref     = source_ref
                ),
                source_ref      = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_indicator_variable.makeReference(provider),
                source_ref = source_ref
            ),
            source       = ExpressionConstantRef(
                constant   = True,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
    ]

    source_ref = source_ref.atInternal()

    statements += [
        makeTryFinallyStatement(
            tried      = makeTryExceptSingleHandlerNode(
                tried          = with_body,
                exception_name = "BaseException",
                handler_body   = StatementsSequence(
                    statements = (
                        # Prevents final block from calling __exit__ as
                        # well.
                        StatementAssignmentVariable(
                            variable_ref = ExpressionTargetTempVariableRef(
                                variable   = tmp_indicator_variable.\
                                  makeReference(provider),
                                source_ref = source_ref
                            ),
                            source       = ExpressionConstantRef(
                                constant   = False,
                                source_ref = source_ref
                            ),
                            source_ref   = source_ref
                        ),
                        StatementConditional(
                            condition  = ExpressionCallNoKeywords(
                                called          = ExpressionTempVariableRef(
                                    variable   = tmp_exit_variable.\
                                      makeReference(provider),
                                    source_ref = source_ref
                                ),
                                args = ExpressionMakeTuple(
                                    elements   = (
                                        ExpressionCaughtExceptionTypeRef(
                                            source_ref = source_ref
                                        ),
                                        ExpressionCaughtExceptionValueRef(
                                            source_ref = source_ref
                                        ),
                                        ExpressionCaughtExceptionTracebackRef(
                                            source_ref = source_ref
                                        ),
                                    ),
                                    source_ref = source_ref
                                ),
                                source_ref      = source_ref
                            ),
                            no_branch  = makeStatementsSequenceFromStatement(
                                statement = StatementRaiseException(
                                    exception_type  = None,
                                    exception_value = None,
                                    exception_trace = None,
                                    exception_cause = None,
                                    source_ref      = source_ref
                                )
                            ),
                            yes_branch = None,
                            source_ref = source_ref
                        ),
                    ),
                    source_ref     = source_ref
                ),
                public_exc = Utils.python_version >= 270,
                source_ref = source_ref
            ),
            final      = StatementConditional(
                condition      = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_indicator_variable.makeReference(
                            provider
                        ),
                        source_ref = source_ref
                    ),
                    right      = ExpressionConstantRef(
                        constant    = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = makeStatementsSequenceFromStatement(
                    statement = StatementExpressionOnly(
                        expression = ExpressionCallNoKeywords(
                            called     = ExpressionTempVariableRef(
                                variable   = tmp_exit_variable.\
                                  makeReference(provider),
                                source_ref = source_ref
                            ),
                            args       = ExpressionConstantRef(
                                constant   = (None, None, None),
                                source_ref = source_ref
                            ),
                            source_ref = with_exit_source_ref
                        ),
                        source_ref     = source_ref
                    )
                ),
                no_branch  = None,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    ]

    return makeTryFinallyStatement(
        tried = statements,
        final = (
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_source_variable.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            ),
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_enter_variable.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            ),
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_exit_variable.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            ),
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_indicator_variable.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            ),
        ),
        source_ref  = source_ref
    )
示例#2
0
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_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator, 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), )

    pushBuildContext("loop_body")
    pushIndicatorVariable(None)
    loop_statements = buildStatementsNode(provider=provider,
                                          nodes=node.body,
                                          source_ref=source_ref)
    popIndicatorVariable()
    popBuildContext()

    # 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), 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_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator, 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,
                              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=StatementReleaseVariable(
                                                  variable=tmp_break_indicator,
                                                  tolerant=False,
                                                  source_ref=source_ref),
                                              source_ref=source_ref), )

        return StatementsSequence(statements=statements, source_ref=source_ref)
def _buildInplaceAssignAttributeNode(lookup_source, attribute_name,
                                     tmp_variable1, tmp_variable2, operator,
                                     expression, source_ref):
    # First assign the target value to a temporary variable.
    preserve_to_tmp = StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
        source=ExpressionAttributeLookup(
            source=lookup_source.makeCloneAt(source_ref),
            attribute_name=attribute_name,
            source_ref=source_ref),
        source_ref=source_ref)

    # Second assign the in-place result to a temporary variable
    inplace_to_tmp = StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable2,
                                                     source_ref=source_ref),
        source=ExpressionOperationBinaryInplace(operator=operator,
                                                left=ExpressionTempVariableRef(
                                                    variable=tmp_variable1,
                                                    source_ref=source_ref),
                                                right=expression,
                                                source_ref=source_ref),
        source_ref=source_ref)

    # Third, copy it over, if the reference values change, i.e. IsNot is true.
    copy_back_from_tmp = StatementConditional(
        condition=ExpressionComparisonIsNOT(
            left=ExpressionTempVariableRef(variable=tmp_variable1,
                                           source_ref=source_ref),
            right=ExpressionTempVariableRef(variable=tmp_variable2,
                                            source_ref=source_ref),
            source_ref=source_ref),
        yes_branch=makeStatementsSequenceFromStatement(
            statement=StatementAssignmentAttribute(
                expression=lookup_source.makeCloneAt(source_ref),
                attribute_name=attribute_name,
                source=ExpressionTempVariableRef(variable=tmp_variable2,
                                                 source_ref=source_ref),
                source_ref=source_ref)),
        no_branch=None,
        source_ref=source_ref)

    copy_back_from_tmp = makeTryFinallyStatement(
        tried=copy_back_from_tmp,
        final=StatementDelVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable2, source_ref=source_ref),
            tolerant=False,
            source_ref=source_ref),
        source_ref=source_ref)

    return (
        preserve_to_tmp,
        # making sure the above temporary variable is deleted in any case.
        makeTryFinallyStatement(
            tried=(
                inplace_to_tmp,
                copy_back_from_tmp,
            ),
            final=StatementDelVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_variable1, source_ref=source_ref),
                tolerant=False,
                source_ref=source_ref),
            source_ref=source_ref))
示例#4
0
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=R0914

    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)
示例#5
0
def buildExecNode(provider, node, source_ref):
    # "exec" statements, should only occur with Python2.

    # This is using many variables, due to the many details this is
    # dealing with. The locals and globals need to be dealt with in
    # temporary variables, and we need handling of indicators, so
    # that is just the complexity, pylint: disable=R0914

    exec_globals = node.globals
    exec_locals = node.locals
    body = node.body

    orig_globals = exec_globals

    # Handle exec(a,b,c) to be same as exec a, b, c
    if exec_locals is None and exec_globals is None and \
       getKind(body) == "Tuple":
        parts = body.elts
        body  = parts[0]

        if len(parts) > 1:
            exec_globals = parts[1]

            if len(parts) > 2:
                exec_locals = parts[2]
        else:
            return StatementRaiseException(
                exception_type  = ExpressionBuiltinExceptionRef(
                    exception_name = "TypeError",
                    source_ref     = source_ref
                ),
                exception_value = makeConstantRefNode(
                    constant   = """\
exec: arg 1 must be a string, file, or code object""",
                    source_ref = source_ref
                ),
                exception_trace = None,
                exception_cause = None,
                source_ref      = source_ref
            )

    if not provider.isCompiledPythonModule():
        provider.markAsExecContaining()

        if orig_globals is None:
            provider.markAsUnqualifiedExecContaining(source_ref)

    temp_scope = provider.allocateTempScope("exec")

    locals_value  = buildNode(provider, exec_locals, source_ref, True)

    if locals_value is None:
        locals_value = ExpressionConstantNoneRef(
            source_ref = source_ref
        )

    globals_value = buildNode(provider, exec_globals, source_ref, True)

    if globals_value is None:
        globals_value = ExpressionConstantNoneRef(
            source_ref = source_ref
        )

    source_code = buildNode(provider, body, source_ref)

    source_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "exec_source"
    )

    globals_keeper_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "globals"
    )

    locals_keeper_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "locals"
    )

    plain_indicator_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "plain"
    )

    tried = (
        # First evaluate the source code expressions.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = source_variable,
                source_ref = source_ref
            ),
            source       = source_code,
            source_ref   = source_ref
        ),
        # Assign globals and locals temporary the values given, then fix it
        # up, taking note in the "plain" temporary variable, if it was an
        # "exec" statement with None arguments, in which case the copy back
        # will be necessary.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = globals_keeper_variable,
                source_ref = source_ref
            ),
            source       = globals_value,
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = locals_keeper_variable,
                source_ref = source_ref
            ),
            source       = locals_value,
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = plain_indicator_variable,
                source_ref = source_ref
            ),
            source       = makeConstantRefNode(
                constant   = False,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementConditional(
            condition  = ExpressionComparisonIs(
                left       = ExpressionTempVariableRef(
                    variable   = globals_keeper_variable,
                    source_ref = source_ref
                ),
                right      = ExpressionConstantNoneRef(
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            yes_branch = makeStatementsSequenceFromStatements(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = globals_keeper_variable,
                        source_ref = source_ref
                    ),
                    source       = ExpressionBuiltinGlobals(
                        source_ref = source_ref
                    ),
                    source_ref   = source_ref,
                ),
                StatementConditional(
                    condition  = ExpressionComparisonIs(
                        left       = ExpressionTempVariableRef(
                            variable   = locals_keeper_variable,
                            source_ref = source_ref
                        ),
                        right      = ExpressionConstantNoneRef(
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = makeStatementsSequenceFromStatements(
                        StatementAssignmentVariable(
                            variable_ref = ExpressionTargetTempVariableRef(
                                variable   = locals_keeper_variable,
                                source_ref = source_ref
                            ),
                            source       = _getLocalsClassNode(provider)(
                                source_ref = source_ref
                            ),
                            source_ref   = source_ref,
                        ),
                        StatementAssignmentVariable(
                            variable_ref = ExpressionTargetTempVariableRef(
                                variable   = plain_indicator_variable,
                                source_ref = source_ref
                            ),
                            source       = makeConstantRefNode(
                                constant   = True,
                                source_ref = source_ref
                            ),
                            source_ref   = source_ref,
                        )
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                ),
            ),
            no_branch  = makeStatementsSequenceFromStatements(
                StatementConditional(
                    condition  = ExpressionComparisonIs(
                        left       = ExpressionTempVariableRef(
                            variable   = locals_keeper_variable,
                            source_ref = source_ref
                        ),
                        right      = ExpressionConstantNoneRef(
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = makeStatementsSequenceFromStatement(
                        statement = StatementAssignmentVariable(
                            variable_ref = ExpressionTargetTempVariableRef(
                                variable   = locals_keeper_variable,
                                source_ref = source_ref
                            ),
                            source       = ExpressionTempVariableRef(
                                variable   = globals_keeper_variable,
                                source_ref = source_ref
                            ),
                            source_ref   = source_ref,
                        )
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        ),
        # Source needs some special treatment for not done for "eval", if it's a
        # file object, then  must be read.
        StatementConditional(
            condition  = ExpressionBuiltinIsinstance(
                instance   = ExpressionTempVariableRef(
                    variable   = source_variable,
                    source_ref = source_ref
                ),
                classes    = ExpressionBuiltinAnonymousRef(
                    builtin_name = "file",
                    source_ref   = source_ref,
                ),
                source_ref = source_ref
            ),
            yes_branch = makeStatementsSequenceFromStatement(
                statement = StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = source_variable,
                        source_ref = source_ref
                    ),
                    source       = ExpressionCallEmpty(
                        called     = ExpressionAttributeLookup(
                            source         = ExpressionTempVariableRef(
                                variable   = source_variable,
                                source_ref = source_ref
                            ),
                            attribute_name = "read",
                            source_ref     = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    source_ref   = source_ref
                )
            ),
            no_branch  = None,
            source_ref = source_ref
        ),
        makeTryFinallyStatement(
            provider   = provider,
            tried      = StatementExec(
                source_code = ExpressionTempVariableRef(
                    variable   = source_variable,
                    source_ref = source_ref
                ),
                globals_arg = ExpressionTempVariableRef(
                    variable   = globals_keeper_variable,
                    source_ref = source_ref
                ),
                locals_arg  = ExpressionTempVariableRef(
                    variable   = locals_keeper_variable,
                    source_ref = source_ref
                ),
                source_ref  = source_ref
            ),
            final      = StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = plain_indicator_variable,
                        source_ref = source_ref
                    ),
                    right      = makeConstantRefNode(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = makeStatementsSequenceFromStatement(
                    statement = StatementLocalsDictSync(
                        locals_arg = ExpressionTempVariableRef(
                            variable   = locals_keeper_variable,
                            source_ref = source_ref,
                        ),
                        source_ref = source_ref.atInternal()
                    )
                ),
                no_branch  = None,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    final = (
        StatementReleaseVariable(
            variable   = source_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = globals_keeper_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = locals_keeper_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = plain_indicator_variable,
            source_ref = source_ref
        ),
    )

    return makeTryFinallyStatement(
        provider   = provider,
        tried      = tried,
        final      = final,
        source_ref = source_ref
    )
示例#6
0
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node,
                             temp_scope, source_ref):
    """ Wrap the locals and globals arguments for "eval".

        This is called from the outside, and when the node tree
        already exists.
    """

    globals_keeper_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "globals"
    )

    locals_keeper_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "locals"
    )

    if locals_node is None:
        locals_node = ExpressionConstantNoneRef(
            source_ref = source_ref
        )

    if globals_node is None:
        globals_node = ExpressionConstantNoneRef(
            source_ref = source_ref
        )

    post_statements = []

    if provider.isExpressionClassBody():
        post_statements.append(
            StatementLocalsDictSync(
                locals_arg = ExpressionTempVariableRef(
                    variable   = locals_keeper_variable,
                    source_ref = source_ref,
                ),
                source_ref = source_ref.atInternal()
            )
        )

    post_statements += [
        StatementReleaseVariable(
            variable   = globals_keeper_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = locals_keeper_variable,
            source_ref = source_ref
        )
    ]

    # The locals default is dependent on exec_mode, globals or locals.
    locals_default = ExpressionConditional(
        condition      = ExpressionComparisonIs(
            left       = ExpressionTempVariableRef(
                variable   = globals_keeper_variable,
                source_ref = source_ref
            ),
            right      = ExpressionConstantNoneRef(
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        expression_no  = ExpressionTempVariableRef(
            variable   = globals_keeper_variable,
            source_ref = source_ref
        ),
        expression_yes = _getLocalsClassNode(provider)(
            source_ref = source_ref
        ),
        source_ref     = source_ref
    )

    pre_statements = [
        # First assign globals and locals temporary the values given.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = globals_keeper_variable,
                source_ref = source_ref
            ),
            source       = globals_node,
            source_ref   = source_ref,
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = locals_keeper_variable,
                source_ref = source_ref
            ),
            source       = locals_node,
            source_ref   = source_ref,
        ),
        StatementConditional(
            condition  = ExpressionComparisonIs(
                left       = ExpressionTempVariableRef(
                    variable   = locals_keeper_variable,
                    source_ref = source_ref
                ),
                right      = ExpressionConstantNoneRef(
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            yes_branch = makeStatementsSequenceFromStatement(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = locals_keeper_variable,
                        source_ref = source_ref
                    ),
                    source       = locals_default,
                    source_ref   = source_ref,
                )
            ),
            no_branch  = None,
            source_ref = source_ref
        ),
        StatementConditional(
            condition  = ExpressionComparisonIs(
                left       = ExpressionTempVariableRef(
                    variable   = globals_keeper_variable,
                    source_ref = source_ref
                ),
                right      = ExpressionConstantNoneRef(
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            yes_branch = makeStatementsSequenceFromStatement(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = globals_keeper_variable,
                        source_ref = source_ref
                    ),
                    source       = ExpressionBuiltinGlobals(
                        source_ref = source_ref
                    ),
                    source_ref   = source_ref,
                )
            ),
            no_branch  = None,
            source_ref = source_ref
        )
    ]

    return (
        ExpressionTempVariableRef(
            variable   = globals_keeper_variable,
            source_ref = source_ref
              if globals_node is None else
            globals_node.getSourceReference()

        ),
        ExpressionTempVariableRef(
            variable   = locals_keeper_variable,
            source_ref = source_ref
              if locals_node is None else
            locals_node.getSourceReference()
        ),
        makeStatementsSequence(pre_statements, False, source_ref),
        makeStatementsSequence(post_statements, False, source_ref)
    )
def buildLambdaNode(provider, node, source_ref):
    # Many details to deal with

    assert getKind(node) == "Lambda"

    function_kind, flags = detectFunctionBodyKind(nodes=(node.body, ))

    outer_body, function_body, code_object = buildFunctionWithParsing(
        provider=provider,
        function_kind=function_kind,
        name="<lambda>",
        function_doc=None,
        flags=flags,
        node=node,
        source_ref=source_ref)

    if function_kind == "Function":
        code_body = function_body
    else:
        code_body = ExpressionGeneratorObjectBody(provider=function_body,
                                                  name="<lambda>",
                                                  flags=set(),
                                                  source_ref=source_ref)

    if function_kind == "Generator":
        function_body.setBody(
            makeStatementsSequenceFromStatement(statement=StatementReturn(
                expression=ExpressionMakeGeneratorObject(
                    generator_ref=ExpressionFunctionRef(
                        function_body=code_body, source_ref=source_ref),
                    code_object=code_object,
                    source_ref=source_ref),
                source_ref=source_ref)))

    defaults = buildNodeList(provider, node.args.defaults, source_ref)
    kw_defaults = buildParameterKwDefaults(provider=provider,
                                           node=node,
                                           function_body=function_body,
                                           source_ref=source_ref)

    body = buildNode(
        provider=code_body,
        node=node.body,
        source_ref=source_ref,
    )

    if function_kind == "Generator":
        if python_version < 270:
            tmp_return_value = code_body.allocateTempVariable(
                temp_scope=None, name="yield_return")

            statements = (StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_return_value,
                    source_ref=source_ref,
                ),
                source=body,
                source_ref=source_ref),
                          StatementConditional(
                              condition=ExpressionComparisonIsNOT(
                                  left=ExpressionTempVariableRef(
                                      variable=tmp_return_value,
                                      source_ref=source_ref,
                                  ),
                                  right=ExpressionConstantNoneRef(
                                      source_ref=source_ref),
                                  source_ref=source_ref),
                              yes_branch=makeStatementsSequenceFromStatement(
                                  statement=StatementExpressionOnly(
                                      expression=ExpressionYield(
                                          expression=ExpressionTempVariableRef(
                                              variable=tmp_return_value,
                                              source_ref=source_ref,
                                          ),
                                          source_ref=source_ref),
                                      source_ref=source_ref)),
                              no_branch=None,
                              source_ref=source_ref))
            body = makeTryFinallyStatement(provider=provider,
                                           tried=statements,
                                           final=StatementReleaseVariable(
                                               variable=tmp_return_value,
                                               source_ref=source_ref),
                                           source_ref=source_ref)
        else:
            body = StatementExpressionOnly(expression=body,
                                           source_ref=source_ref)
    else:
        body = StatementReturn(expression=body, source_ref=source_ref)

    body = StatementsFrame(
        statements=mergeStatements((body, )),
        code_object=code_object,
        guard_mode="generator" if function_kind == "Generator" else "full",
        source_ref=body.getSourceReference())

    body = makeStatementsSequenceFromStatement(statement=body, )

    code_body.setBody(body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    return ExpressionFunctionCreation(function_ref=ExpressionFunctionRef(
        function_body=outer_body, source_ref=source_ref),
                                      code_object=code_object,
                                      defaults=defaults,
                                      kw_defaults=kw_defaults,
                                      annotations=annotations,
                                      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):
    # 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,R0915
    if start_value is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp, 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, 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, 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 = 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, 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=makeStatementsSequenceFromStatement(
                    statement=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=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,
                                                 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, 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, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref.atInternal()))

    return statements, del_statements
示例#9
0
def buildPrintNode(provider, node, source_ref):
    # "print" statements, should only occur with Python2.

    if node.dest is not None:
        temp_scope = provider.allocateTempScope("print")

        tmp_target_variable = provider.allocateTempVariable(
            temp_scope=temp_scope, name="target")

        target_default_statement = StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_target_variable, source_ref=source_ref),
            source=ExpressionImportModuleHard(module_name="sys",
                                              import_name="stdout",
                                              source_ref=source_ref),
            source_ref=source_ref)

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_target_variable, source_ref=source_ref),
                source=buildNode(provider=provider,
                                 node=node.dest,
                                 source_ref=source_ref),
                source_ref=source_ref),
            StatementConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionTempVariableRef(
                        variable=tmp_target_variable, source_ref=source_ref),
                    right=ExpressionConstantRef(constant=None,
                                                source_ref=source_ref),
                    source_ref=source_ref),
                yes_branch=makeStatementsSequenceFromStatement(
                    statement=target_default_statement),
                no_branch=None,
                source_ref=source_ref)
        ]

    values = buildNodeList(provider=provider,
                           nodes=node.values,
                           source_ref=source_ref)

    if node.dest is not None:
        print_statements = [
            StatementPrintValue(dest=ExpressionTempVariableRef(
                variable=tmp_target_variable, source_ref=source_ref),
                                value=value,
                                source_ref=source_ref) for value in values
        ]

        if node.nl:
            print_statements.append(
                StatementPrintNewline(dest=ExpressionTempVariableRef(
                    variable=tmp_target_variable, source_ref=source_ref),
                                      source_ref=source_ref))

        statements.append(
            makeTryFinallyStatement(provider=provider,
                                    tried=print_statements,
                                    final=StatementReleaseVariable(
                                        variable=tmp_target_variable,
                                        source_ref=source_ref),
                                    source_ref=source_ref))
    else:
        statements = [
            StatementPrintValue(dest=None, value=value, source_ref=source_ref)
            for value in values
        ]

        if node.nl:
            statements.append(
                StatementPrintNewline(dest=None, source_ref=source_ref))

    return makeStatementsSequenceFromStatements(*statements)
示例#10
0
def buildForLoopNode(provider, node, source_ref):
    # The for loop is re-formulated according to developer manual. An iterator
    # is created, and looped until it gives StopIteration. The else block is
    # taken if a for loop exits normally, i.e. because of iterator
    # exhaustion. We do this by introducing an indicator variable.

    source = buildNode(provider, node.iter, source_ref)

    temp_scope = provider.allocateTempScope("for_loop")

    tmp_iter_variable = provider.allocateTempVariable(temp_scope=temp_scope,
                                                      name="for_iterator")

    tmp_value_variable = provider.allocateTempVariable(temp_scope=temp_scope,
                                                       name="iter_value")

    else_block = buildStatementsNode(
        provider=provider,
        nodes=node.orelse if node.orelse else None,
        source_ref=source_ref)

    if else_block is not None:
        tmp_break_indicator_variable = provider.allocateTempVariable(
            temp_scope=temp_scope, name="break_indicator")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        provider),
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=True,
                                             source_ref=source_ref),
                source_ref=source_ref)
        ]
    else:
        statements = []

    statements.append(StatementBreakLoop(source_ref=source_ref.atInternal()))

    handler_body = makeStatementsSequence(statements=statements,
                                          allow_none=False,
                                          source_ref=source_ref)

    statements = (makeTryExceptSingleHandlerNode(
        tried=makeStatementsSequenceFromStatement(
            statement=StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_value_variable.makeReference(provider),
                    source_ref=source_ref),
                source=ExpressionBuiltinNext1(value=ExpressionTempVariableRef(
                    variable=tmp_iter_variable.makeReference(provider),
                    source_ref=source_ref),
                                              source_ref=source_ref),
                source_ref=source_ref)),
        exception_name="StopIteration",
        handler_body=handler_body,
        source_ref=source_ref),
                  buildAssignmentStatements(
                      provider=provider,
                      node=node.target,
                      source=ExpressionTempVariableRef(
                          variable=tmp_value_variable.makeReference(provider),
                          source_ref=source_ref),
                      source_ref=source_ref))

    statements += (buildStatementsNode(provider=provider,
                                       nodes=node.body,
                                       source_ref=source_ref), )

    loop_body = makeStatementsSequence(statements=statements,
                                       allow_none=True,
                                       source_ref=source_ref)

    if else_block is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        provider),
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=False,
                                             source_ref=source_ref),
                source_ref=source_ref)
        ]
    else:
        statements = []

    cleanup_statements = (
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_value_variable.makeReference(provider),
            source_ref=source_ref),
                             tolerant=True,
                             source_ref=source_ref.atInternal()),
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_iter_variable.makeReference(provider),
            source_ref=source_ref),
                             tolerant=False,
                             source_ref=source_ref.atInternal()))

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable.makeReference(provider),
                source_ref=source_ref),
            source=ExpressionBuiltinIter1(
                value=source, source_ref=source.getSourceReference()),
            source_ref=source_ref),
        StatementTryFinally(tried=makeStatementsSequenceFromStatement(
            statement=StatementLoop(body=loop_body, source_ref=source_ref)),
                            final=StatementsSequence(
                                statements=cleanup_statements,
                                source_ref=source_ref.atInternal()),
                            source_ref=source_ref.atInternal())
    ]

    if else_block is not None:
        statements += [
            StatementConditional(condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        provider),
                    source_ref=source_ref),
                right=ExpressionConstantRef(constant=True,
                                            source_ref=source_ref),
                source_ref=source_ref),
                                 yes_branch=else_block,
                                 no_branch=None,
                                 source_ref=source_ref)
        ]

    return StatementsSequence(statements=statements, source_ref=source_ref)
def makeTryExceptNoRaise( tried, handlers, no_raise, source_ref ):
    # This helper executes the core re-formulation of "no_raise" blocks, which are the
    # "else" blocks of try/except statements. We use an indicator variable instead, which
    # will signal that the tried block executed up to the end. And then we make the else
    # block be a conditional statement checking that. This is a separate function, so it
    # can be re-used in other re-formulations, e.g. with statements.

    assert no_raise is not None
    assert len( handlers ) > 0

    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_handler_indicator_variable = result.getTempVariable( "unhandled_indicator" )

    for handler in handlers:
        handler.setExceptionBranch(
            makeStatementsSequence(
                statements = (
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = tmp_handler_indicator_variable.makeReference( result ),
                            source_ref = source_ref.atInternal()
                        ),
                        source       = ExpressionConstantRef(
                            constant   = False,
                            source_ref = source_ref
                        ),
                        source_ref   = no_raise.getSourceReference().atInternal()
                    ),
                    handler.getExceptionBranch()
                ),
                allow_none = True,
                source_ref = source_ref
            )
        )

    result.setBody(
        StatementsSequence(
            statements = (
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_handler_indicator_variable.makeReference( result ),
                        source_ref = source_ref.atInternal()
                    ),
                    source     = ExpressionConstantRef(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                StatementTryExcept(
                    tried      = tried,
                    handlers   = handlers,
                    source_ref = source_ref
                ),
                StatementConditional(
                    condition  = ExpressionComparisonIs(
                        left = ExpressionTempVariableRef(
                            variable   = tmp_handler_indicator_variable.makeReference( result ),
                            source_ref = source_ref
                        ),
                        right = ExpressionConstantRef(
                            constant   = True,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = no_raise,
                    no_branch  = None,
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        )
    )

    return result
def buildTryExceptionNode(provider, node, source_ref):
    # Try/except nodes. Re-formulated as described in the developer
    # manual. Exception handlers made the assignment to variables explicit. Same
    # for the "del" as done for Python3. Also catches always work a tuple of
    # exception types and hides away that they may be built or not.

    # Many variables and branches, due to the re-formulation that is going on
    # here, which just has the complexity, pylint: disable=R0912,R0914

    tried = buildStatementsNode(provider=provider,
                                nodes=node.body,
                                source_ref=source_ref)

    handlers = []

    for handler in node.handlers:
        exception_expression, exception_assign, exception_block = (
            handler.type, handler.name, handler.body)

        if exception_assign is None:
            statements = [
                buildStatementsNode(provider=provider,
                                    nodes=exception_block,
                                    source_ref=source_ref)
            ]
        elif python_version < 300:
            statements = [
                buildAssignmentStatements(
                    provider=provider,
                    node=exception_assign,
                    source=ExpressionCaughtExceptionValueRef(
                        source_ref=source_ref.atInternal()),
                    source_ref=source_ref.atInternal()),
                buildStatementsNode(provider=provider,
                                    nodes=exception_block,
                                    source_ref=source_ref)
            ]
        else:
            # Python3 requires temporary assignment of exception assignment.
            target_info = decodeAssignTarget(
                provider=provider,
                node=exception_assign,
                source_ref=source_ref,
            )

            kind, detail = target_info

            assert kind == "Name", kind
            kind = "Name_Exception"

            statements = [
                buildAssignmentStatements(
                    provider=provider,
                    node=exception_assign,
                    source=ExpressionCaughtExceptionValueRef(
                        source_ref=source_ref.atInternal()),
                    source_ref=source_ref.atInternal()),
                makeTryFinallyStatement(provider=provider,
                                        tried=buildStatementsNode(
                                            provider=provider,
                                            nodes=exception_block,
                                            source_ref=source_ref),
                                        final=buildDeleteStatementFromDecoded(
                                            kind=kind,
                                            detail=detail,
                                            source_ref=source_ref),
                                        source_ref=source_ref)
            ]

        handler_body = makeStatementsSequence(statements=statements,
                                              allow_none=True,
                                              source_ref=source_ref)

        exception_types = buildNode(provider=provider,
                                    node=exception_expression,
                                    source_ref=source_ref,
                                    allow_none=True)

        # The exception types should be a tuple, so as to be most general.
        if exception_types is None:
            if handler is not node.handlers[-1]:
                SyntaxErrors.raiseSyntaxError(
                    reason="default 'except:' must be last",
                    source_ref=source_ref.atLineNumber(
                        handler.lineno -
                        1 if Options.isFullCompat() else handler.lineno))

        handlers.append((
            exception_types,
            handler_body,
        ))

    # Re-raise by default
    exception_handling = makeReraiseExceptionStatement(source_ref=source_ref)

    for exception_type, handler in reversed(handlers):
        if exception_type is None:
            # A default handler was given, so use that indeed.
            exception_handling = handler
        else:
            exception_handling = StatementsSequence(
                statements=(StatementConditional(
                    condition=ExpressionComparisonExceptionMatch(
                        left=ExpressionCaughtExceptionTypeRef(
                            source_ref=exception_type.source_ref),
                        right=exception_type,
                        source_ref=exception_type.source_ref),
                    yes_branch=handler,
                    no_branch=exception_handling,
                    source_ref=exception_type.source_ref), ),
                source_ref=exception_type.source_ref)

    if exception_handling is None:
        # For Python3, we need not publish at all, if all we do is to revert
        # that immediately. For Python2, the publish may release previously
        # published exception, which has side effects potentially.
        if python_version < 300:
            exception_handling = StatementsSequence(
                statements=(
                    StatementPreserveFrameException(
                        preserver_id=0,  # unused with Python2
                        source_ref=source_ref.atInternal()),
                    StatementPublishException(
                        source_ref=source_ref.atInternal()),
                ),
                source_ref=source_ref.atInternal())
    else:
        if python_version < 300:
            exception_handling.setStatements((
                StatementPreserveFrameException(
                    preserver_id=0,  # unused with Python2
                    source_ref=source_ref.atInternal()),
                StatementPublishException(source_ref=source_ref.atInternal()),
            ) + exception_handling.getStatements())
        else:
            preserver_id = provider.allocatePreserverId()

            exception_handling = makeStatementsSequenceFromStatements(
                StatementPreserveFrameException(
                    preserver_id=preserver_id,
                    source_ref=source_ref.atInternal()),
                StatementPublishException(source_ref=source_ref.atInternal()),
                makeTryFinallyStatement(
                    provider=provider,
                    tried=exception_handling,
                    final=StatementRestoreFrameException(
                        preserver_id=preserver_id,
                        source_ref=source_ref.atInternal()),
                    source_ref=source_ref),
            )

    no_raise = buildStatementsNode(provider=provider,
                                   nodes=node.orelse,
                                   source_ref=source_ref)

    if no_raise is None:
        if tried is None:
            return None

        return StatementTry(tried=tried,
                            except_handler=exception_handling,
                            break_handler=None,
                            continue_handler=None,
                            return_handler=None,
                            source_ref=source_ref)
    else:
        if tried is None:
            return no_raise

        return makeTryExceptNoRaise(
            provider=provider,
            temp_scope=provider.allocateTempScope("try_except"),
            handling=exception_handling,
            tried=tried,
            no_raise=no_raise,
            source_ref=source_ref)
def _buildContractionBodyNode(provider, node, emit_class, start_value,
                              container_tmp, iter_tmp, temp_scope,
                              assign_provider, function_body, 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 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=iter_tmp,
                                        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=container_tmp,
                                        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

            current_body = emit_class(buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
    else:
        assert emit_class is StatementDictOperationSet

        current_body = StatementDictOperationSet(
            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)

    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)

            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=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=ExpressionBuiltinNext1(value=iterator_ref,
                                                  source_ref=source_ref),
                    source_ref=source_ref),
                exception_name="StopIteration",
                handler_body=StatementLoopBreak(
                    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)

    release_statements = [
        StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref)
        for tmp_variable in tmp_variables
    ]

    return statements, release_statements
def buildTryFinallyNode(provider, build_tried, node, source_ref):

    if Utils.python_version < 300:
        # Prevent "continue" statements in the final blocks
        pushBuildContext("finally")
        final = buildStatementsNode(provider=provider,
                                    nodes=node.finalbody,
                                    source_ref=source_ref)
        popBuildContext()

        return StatementTryFinally(
            tried=build_tried(),
            final=final,
            public_exc=Utils.python_version >= 300,  # TODO: Use below code
            source_ref=source_ref)
    else:
        temp_scope = provider.allocateTempScope("try_finally")

        tmp_indicator_var = provider.allocateTempVariable(
            temp_scope=temp_scope, name="unhandled_indicator")

        pushIndicatorVariable(tmp_indicator_var)

        statements = (StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_indicator_var,
                source_ref=source_ref.atInternal()),
            source=ExpressionConstantRef(constant=False,
                                         source_ref=source_ref),
            source_ref=source_ref.atInternal()), build_tried(),
                      StatementAssignmentVariable(
                          variable_ref=ExpressionTargetTempVariableRef(
                              variable=tmp_indicator_var,
                              source_ref=source_ref.atInternal()),
                          source=ExpressionConstantRef(constant=True,
                                                       source_ref=source_ref),
                          source_ref=source_ref.atInternal()))

        # Prevent "continue" statements in the final blocks
        pushBuildContext("finally")
        final = buildStatementsNode(provider=provider,
                                    nodes=node.finalbody,
                                    source_ref=source_ref)
        popBuildContext()

        popIndicatorVariable()

        tried = StatementsSequence(statements=mergeStatements(statements,
                                                              allow_none=True),
                                   source_ref=source_ref)

        prelude = StatementConditional(
            condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=tmp_indicator_var,
                    source_ref=source_ref.atInternal()),
                right=ExpressionConstantRef(constant=False,
                                            source_ref=source_ref),
                source_ref=source_ref),
            yes_branch=StatementsSequence(
                statements=(StatementPreserveFrameException(
                    source_ref=source_ref.atInternal()),
                            StatementPublishException(
                                source_ref=source_ref.atInternal())),
                source_ref=source_ref.atInternal()),
            no_branch=None,
            source_ref=source_ref.atInternal())

        postlude = (StatementConditional(
            condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=tmp_indicator_var,
                    source_ref=source_ref.atInternal()),
                right=ExpressionConstantRef(constant=False,
                                            source_ref=source_ref),
                source_ref=source_ref),
            yes_branch=StatementsSequence(statements=(
                StatementDelVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_indicator_var,
                        source_ref=source_ref.atInternal()),
                    tolerant=False,
                    source_ref=source_ref.atInternal()),
                StatementReraiseFrameException(
                    source_ref=source_ref.atInternal()),
            ),
                                          source_ref=source_ref.atInternal()),
            no_branch=StatementsSequence(statements=(StatementDelVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_indicator_var,
                    source_ref=source_ref.atInternal()),
                tolerant=False,
                source_ref=source_ref.atInternal()), ),
                                         source_ref=source_ref.atInternal()),
            source_ref=source_ref.atInternal()), )

        final = StatementsSequence(statements=mergeStatements((
            prelude,
            makeTryFinallyStatement(tried=final,
                                    final=postlude,
                                    source_ref=source_ref.atInternal()),
        )),
                                   source_ref=source_ref.atInternal())

        return StatementTryFinally(tried=tried,
                                   final=final,
                                   public_exc=True,
                                   source_ref=source_ref)
示例#15
0
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)

    temp_block = StatementTempBlock(source_ref=source_ref)

    if start_value is not None:
        container_tmp = temp_block.getTempVariable("result")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp.makeReference(temp_block),
                    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(temp_block),
                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(temp_block),
            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 qual in reversed(node.generators):
        nested_temp_block = StatementTempBlock(source_ref=source_ref)

        tmp_iter_variable = nested_temp_block.getTempVariable(
            "contraction_iter")

        tmp_value_variable = nested_temp_block.getTempVariable("iter_value")

        # The first iterated value is to be calculated outside of the function and
        # will be given as a parameter "_iterated".
        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(
                        nested_temp_block),
                    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(
                                nested_temp_block),
                            source_ref=source_ref),
                        source=ExpressionBuiltinNext1(
                            value=ExpressionTempVariableRef(
                                variable=tmp_iter_variable.makeReference(
                                    nested_temp_block),
                                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,
                node=qual.target,
                source=ExpressionTempVariableRef(
                    variable=tmp_value_variable.makeReference(
                        nested_temp_block),
                    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=loop_statements,
                                                  source_ref=source_ref),
                          source_ref=source_ref))

        nested_temp_block.setBody(
            StatementsSequence(statements=nested_statements,
                               source_ref=source_ref))

        current_body = nested_temp_block

    statements.append(current_body)

    if start_value is not None:
        statements.append(
            StatementReturn(expression=ExpressionTempVariableRef(
                variable=container_tmp.makeReference(temp_block),
                source_ref=source_ref),
                            source_ref=source_ref))

    temp_block.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    function_body.setBody(
        StatementsFrame(statements=[temp_block],
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        arg_names=(),
                        kw_only_count=0,
                        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)