def makeTryExceptNoRaise(provider, temp_scope, tried, handling, no_raise,
                         public_exc, source_ref):
    # This helper executes the core re-formulation of "no_raise" blocks, which
    # are the "else" blocks of "try"/"except" statements. In order to limit the
    # execution, 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.

    assert no_raise is not None

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

    statements = mergeStatements((StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_handler_indicator_variable.makeReference(provider),
            source_ref=source_ref.atInternal()),
        source=ExpressionConstantRef(constant=False, source_ref=source_ref),
        source_ref=no_raise.getSourceReference().atInternal()), handling),
                                 allow_none=True)

    handling = StatementsSequence(statements=statements, source_ref=source_ref)

    tried = (StatementTryExcept(tried=tried,
                                handling=handling,
                                public_exc=public_exc,
                                source_ref=source_ref),
             StatementConditional(condition=ExpressionComparisonIs(
                 left=ExpressionTempVariableRef(
                     variable=tmp_handler_indicator_variable.makeReference(
                         provider),
                     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))

    final = StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
        variable=tmp_handler_indicator_variable.makeReference(provider),
        source_ref=source_ref.atInternal()),
                                 tolerant=False,
                                 source_ref=source_ref.atInternal()),

    return StatementsSequence(statements=(StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_handler_indicator_variable.makeReference(provider),
            source_ref=source_ref.atInternal()),
        source=ExpressionConstantRef(constant=True, source_ref=source_ref),
        source_ref=source_ref.atInternal()),
                                          makeTryFinallyStatement(
                                              tried=tried,
                                              final=final,
                                              source_ref=source_ref)),
                              source_ref=source_ref)
def makeTryExceptNoRaise(provider, temp_scope, 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. In order to limit the
    # execution, 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

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

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

        handler.setExceptionBranch(
            makeStatementsSequence(statements=statements,
                                   allow_none=True,
                                   source_ref=source_ref))

    statements = (StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_handler_indicator_variable.makeReference(provider),
            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(provider),
                          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))

    return StatementsSequence(statements=statements, source_ref=source_ref)
def makeTryExceptNoRaise(provider, temp_scope, tried, handling, no_raise,
                         source_ref):
    # This helper executes the core re-formulation of "no_raise" blocks, which
    # are the "else" blocks of "try"/"except" statements. In order to limit the
    # execution, 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.

    # Indicator variable, will end up with C bool type, and need not be released.
    tmp_handler_indicator_variable = provider.allocateTempVariable(
        temp_scope=temp_scope, name="unhandled_indicator", temp_type="bool")

    statements = mergeStatements(
        (
            StatementAssignmentVariable(
                variable=tmp_handler_indicator_variable,
                source=makeConstantRefNode(constant=False,
                                           source_ref=source_ref),
                source_ref=no_raise.getSourceReference(),
            ),
            handling,
        ),
        allow_none=True,
    )

    handling = StatementsSequence(statements=statements, source_ref=source_ref)

    return makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_handler_indicator_variable,
            source=makeConstantRefNode(constant=True, source_ref=source_ref),
            source_ref=source_ref,
        ),
        StatementTry(
            tried=tried,
            except_handler=handling,
            break_handler=None,
            continue_handler=None,
            return_handler=None,
            source_ref=source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=tmp_handler_indicator_variable,
                    source_ref=source_ref),
                right=makeConstantRefNode(constant=True,
                                          source_ref=source_ref),
                source_ref=source_ref,
            ),
            yes_branch=no_raise,
            no_branch=None,
            source_ref=source_ref,
        ),
    )
Exemple #4
0
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope,
                             source_ref):
    """ Wrap the locals and globals arguments for eval and exec.

        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 = ExpressionConstantRef(constant=None,
                                            source_ref=source_ref)

    if globals_node is None:
        globals_node = ExpressionConstantRef(constant=None,
                                             source_ref=source_ref)

    post_statements = [
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=globals_keeper_variable.makeReference(provider),
            source_ref=globals_node.getSourceReference()),
                             tolerant=False,
                             source_ref=source_ref),
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=locals_keeper_variable.makeReference(provider),
            source_ref=locals_node.getSourceReference()),
                             tolerant=False,
                             source_ref=source_ref)
    ]

    # The locals default is dependant on exec_mode, globals or locals.
    locals_default = ExpressionConditional(
        condition=ExpressionComparisonIs(left=ExpressionTempVariableRef(
            variable=globals_keeper_variable.makeReference(provider),
            source_ref=source_ref),
                                         right=ExpressionConstantRef(
                                             constant=None,
                                             source_ref=source_ref),
                                         source_ref=source_ref),
        no_expression=ExpressionTempVariableRef(
            variable=globals_keeper_variable.makeReference(provider),
            source_ref=source_ref),
        yes_expression=ExpressionBuiltinLocals(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.makeReference(provider),
                source_ref=source_ref),
            source=globals_node,
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=locals_keeper_variable.makeReference(provider),
                source_ref=source_ref),
            source=locals_node,
            source_ref=source_ref,
        ),
        StatementConditional(
            condition=ExpressionComparisonIs(left=ExpressionTempVariableRef(
                variable=locals_keeper_variable.makeReference(provider),
                source_ref=source_ref),
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            yes_branch=makeStatementsSequenceFromStatement(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=locals_keeper_variable.makeReference(
                            provider),
                        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.makeReference(provider),
                source_ref=source_ref),
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            yes_branch=makeStatementsSequenceFromStatement(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=globals_keeper_variable.makeReference(
                            provider),
                        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.makeReference(provider),
        source_ref=source_ref
        if globals_node is None else globals_node.getSourceReference()),
            ExpressionTempVariableRef(
                variable=locals_keeper_variable.makeReference(provider),
                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 buildWhileLoopNode(provider, node, source_ref):
    # The while loop is re-formulated according to developer manual. The condition becomes
    # an early condition to break the loop. The else block is taken if a while loop exits
    # normally, i.e. because of condition not being true. We do this by introducing an
    # indicator variable.

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

    if else_block is not None:
        temp_block = StatementTempBlock(source_ref=source_ref)

        tmp_break_indicator_variable = temp_block.getTempVariable(
            "break_indicator")

        statements = (StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator_variable.makeReference(
                    temp_block),
                source_ref=source_ref),
            source=ExpressionConstantRef(constant=True, source_ref=source_ref),
            source_ref=source_ref), StatementBreakLoop(source_ref=source_ref))
    else:
        statements = (StatementBreakLoop(source_ref=source_ref), )

    # The loop body contains a conditional statement at the start that breaks the loop if
    # it fails.
    loop_body = makeStatementsSequence(statements=(StatementConditional(
        condition=buildNode(provider, node.test, source_ref),
        no_branch=StatementsSequence(statements=statements,
                                     source_ref=source_ref),
        yes_branch=None,
        source_ref=source_ref),
                                                   buildStatementsNode(
                                                       provider=provider,
                                                       nodes=node.body,
                                                       source_ref=source_ref)),
                                       allow_none=True,
                                       source_ref=source_ref)

    loop_statement = StatementLoop(body=loop_body, source_ref=source_ref)

    if else_block is None:
        return loop_statement
    else:
        statements = (StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator_variable.makeReference(
                    temp_block),
                source_ref=source_ref),
            source=ExpressionConstantRef(constant=False,
                                         source_ref=source_ref),
            source_ref=source_ref), loop_statement,
                      StatementConditional(condition=ExpressionComparisonIs(
                          left=ExpressionTempVariableRef(
                              variable=tmp_break_indicator_variable.
                              makeReference(temp_block),
                              source_ref=source_ref),
                          right=ExpressionConstantRef(constant=True,
                                                      source_ref=source_ref),
                          source_ref=source_ref),
                                           yes_branch=else_block,
                                           no_branch=None,
                                           source_ref=source_ref))

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

        return temp_block
Exemple #6
0
def _buildWithNode(provider, context_expr, assign_target, body, body_lineno,
                   sync, source_ref):
    # Many details, pylint: disable=too-many-locals
    with_source = buildNode(provider, context_expr, source_ref)

    if Options.isFullCompat():
        source_ref = with_source.getCompatibleSourceReference()

    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,
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        body
    )

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

    if Options.isFullCompat():
        if body:
            deepest = body

            while deepest.getVisitableNodes():
                deepest = deepest.getVisitableNodes()[-1]

            body_lineno = deepest.getCompatibleSourceReference().getLineNumber()

        with_exit_source_ref = source_ref.atLineNumber(body_lineno)
    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 python_version < 270:
        attribute_lookup_class = ExpressionAttributeLookup
    else:
        attribute_lookup_class = ExpressionAttributeLookupSpecial

    enter_value = ExpressionCallEmpty(
        called     = attribute_lookup_class(
            source         = ExpressionTempVariableRef(
                variable   = tmp_source_variable,
                source_ref = source_ref
            ),
            attribute_name = "__enter__" if sync else "__aenter__",
            source_ref     = source_ref
        ),
        source_ref = source_ref
    )

    exit_value_exception = ExpressionCallNoKeywords(
        called     = ExpressionTempVariableRef(
            variable   = tmp_exit_variable,
            source_ref = with_exit_source_ref
        ),
        args       = ExpressionMakeTuple(
            elements   = (
                ExpressionCaughtExceptionTypeRef(
                    source_ref = with_exit_source_ref
                ),
                ExpressionCaughtExceptionValueRef(
                    source_ref = with_exit_source_ref
                ),
                ExpressionCaughtExceptionTracebackRef(
                    source_ref = source_ref
                ),
            ),
            source_ref = source_ref
        ),
        source_ref = with_exit_source_ref
    )

    exit_value_no_exception = ExpressionCallNoKeywords(
        called     = ExpressionTempVariableRef(
            variable   = tmp_exit_variable,
            source_ref = source_ref
        ),
        args       = makeConstantRefNode(
            constant   = (None, None, None),
            source_ref = source_ref
        ),
        source_ref = with_exit_source_ref
    )

    # For "async with", await the entered value and exit value must be awaited.
    if not sync:
        enter_value = ExpressionAsyncWait(
            expression = enter_value,
            source_ref = source_ref
        )
        exit_value_exception = ExpressionAsyncWait(
            expression = exit_value_exception,
            source_ref = source_ref
        )
        exit_value_no_exception = ExpressionAsyncWait(
            expression = exit_value_no_exception,
            source_ref = source_ref
        )

    statements = [
        # First assign the with context to a temporary variable.
        StatementAssignmentVariable(
            variable   = tmp_source_variable,
            source     = with_source,
            source_ref = source_ref
        )
    ]

    attribute_assignments = [
        # Next, assign "__enter__" and "__exit__" attributes to temporary
        # variables.
        StatementAssignmentVariable(
            variable   = tmp_exit_variable,
            source     = attribute_lookup_class(
                source         = ExpressionTempVariableRef(
                    variable   = tmp_source_variable,
                    source_ref = source_ref
                ),
                attribute_name = "__exit__" if sync else "__aexit__",
                source_ref     = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable   = tmp_enter_variable,
            source     = enter_value,
            source_ref = source_ref
        )
    ]

    if python_version >= 360 and sync:
        attribute_assignments.reverse()

    statements += attribute_assignments

    statements.append(
        StatementAssignmentVariable(
            variable   = tmp_indicator_variable,
            source     = makeConstantRefNode(
                constant   = True,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    statements += [
        makeTryFinallyStatement(
            provider   = provider,
            tried      = makeTryExceptSingleHandlerNodeWithPublish(
                provider       = provider,
                tried          = with_body,
                exception_name = "BaseException",
                handler_body   = StatementsSequence(
                    statements = (
                        # Prevents final block from calling __exit__ as
                        # well.
                        StatementAssignmentVariable(
                            variable   = tmp_indicator_variable,
                            source     = makeConstantRefNode(
                                constant   = False,
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        makeConditionalStatement(
                            condition  = exit_value_exception,
                            no_branch  = makeReraiseExceptionStatement(
                                source_ref = with_exit_source_ref
                            ),
                            yes_branch = None,
                            source_ref = with_exit_source_ref
                        ),
                    ),
                    source_ref = source_ref
                ),
                public_exc     = python_version >= 270,
                source_ref     = source_ref
            ),
            final      = StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_indicator_variable,
                        source_ref = source_ref
                    ),
                    right      = makeConstantRefNode(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = makeStatementsSequenceFromStatement(
                    statement = StatementExpressionOnly(
                        expression = exit_value_no_exception,
                        source_ref = source_ref
                    )
                ),
                no_branch  = None,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    ]

    return makeTryFinallyStatement(
        provider   = provider,
        tried      = statements,
        final      = (
            StatementReleaseVariable(
                variable   = tmp_source_variable,
                source_ref = with_exit_source_ref
            ),
            StatementReleaseVariable(
                variable   = tmp_enter_variable,
                source_ref = with_exit_source_ref
            ),
            StatementReleaseVariable(
                variable   = tmp_exit_variable,
                source_ref = with_exit_source_ref
            ),
            StatementReleaseVariable(
                variable   = tmp_indicator_variable,
                source_ref = with_exit_source_ref
            ),
        ),
        source_ref = source_ref
    )
def buildPrintNode(provider, node, source_ref):
    # "print" statements, should only occur with Python2.

    def wrapValue(value):
        if value.isExpressionConstantRef():
            str_value = value.getStrValue()

            if str_value is not None:
                return str_value

        return ExpressionBuiltinStr(value=value,
                                    source_ref=value.getSourceReference())

    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)

    values = [wrapValue(value) for value in values]

    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(
                tried=print_statements,
                final=StatementDelVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_target_variable, source_ref=source_ref),
                    tolerant=False,
                    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 StatementsSequence(statements=statements, source_ref=source_ref)
Exemple #8
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=too-many-locals

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

    # 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,
            )

    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=source_variable,
                                    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=globals_keeper_variable,
            source=globals_value,
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(variable=locals_keeper_variable,
                                    source=locals_value,
                                    source_ref=source_ref),
        StatementAssignmentVariable(
            variable=plain_indicator_variable,
            source=makeConstantRefNode(constant=False, source_ref=source_ref),
            source_ref=source_ref,
        ),
        makeStatementConditional(
            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=globals_keeper_variable,
                    source=ExpressionBuiltinGlobals(source_ref=source_ref),
                    source_ref=source_ref,
                ),
                makeStatementConditional(
                    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=locals_keeper_variable,
                            source=makeExpressionBuiltinLocals(
                                provider=provider, source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                        StatementAssignmentVariable(
                            variable=plain_indicator_variable,
                            source=makeConstantRefNode(constant=True,
                                                       source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                    ),
                    no_branch=None,
                    source_ref=source_ref,
                ),
            ),
            no_branch=makeStatementsSequenceFromStatements(
                makeStatementConditional(
                    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=locals_keeper_variable,
                            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,
        ),
        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=makeStatementConditional(
                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=StatementLocalsDictSync(
                    locals_arg=ExpressionTempVariableRef(
                        variable=locals_keeper_variable,
                        source_ref=source_ref),
                    source_ref=source_ref,
                ),
                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)
def computeBuiltinCall(call_node, called):
    # There is some dispatching for how to output various types of changes,
    # with lots of cases, pylint: disable=R0912

    builtin_name = called.getBuiltinName()

    if builtin_name in _dispatch_dict:
        new_node = _dispatch_dict[builtin_name](call_node)

        # Lets just have this contract to return "None" when no change is meant
        # to be done.
        assert new_node is not call_node
        if new_node is None:
            return call_node, None, None

        # For traces, we are going to ignore side effects, and output traces
        # only based on the basis of it.
        inspect_node = new_node
        if inspect_node.isExpressionSideEffects():
            inspect_node = inspect_node.getExpression()

        if inspect_node.isExpressionBuiltinImport():
            tags    = "new_import"
            message = """\
Replaced dynamic __import__ %s with static module import.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionBuiltin() or \
             inspect_node.isStatementExec():
            tags = "new_builtin"
            message = "Replaced call to built-in '%s' with built-in call '%s'." % (
                builtin_name,
                inspect_node.kind,
            )
        elif inspect_node.isExpressionRaiseException():
            tags = "new_raise"
            message = """\
Replaced call to built-in '%s' with exception raising call.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionOperationUnary():
            tags = "new_expression"
            message = """\
Replaced call to built-in '%s' with unary operation '%s'.""" % (
                inspect_node.kind,
                inspect_node.getOperator()
            )
        elif inspect_node.isExpressionCall():
            tags = "new_expression"
            message = """\
Replaced call to built-in '%s' with call.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionOutlineBody():
            tags = "new_expression"
            message = """\
Replaced call to built-in '%s' with outlined call.""" % builtin_name
        else:

            assert False, (builtin_name, "->", inspect_node)

        # TODO: One day, this should be enabled by default and call either the
        # original built-in or the optimized above one. That should be done,
        # once we can eliminate the condition for most cases.
        if False and isDebug() and not shallMakeModule() and builtin_name:
            source_ref = called.getSourceReference()

            new_node = ExpressionConditional(
                condition      = ExpressionComparisonIs(
                    left       = ExpressionBuiltinRef(
                        builtin_name = builtin_name,
                        source_ref   = source_ref
                    ),
                    right      = ExpressionBuiltinOriginalRef(
                        builtin_name = builtin_name,
                        source_ref   = source_ref
                    ),
                    source_ref = source_ref
                ),
                expression_yes = new_node,
                expression_no  = makeRaiseExceptionReplacementExpression(
                    exception_type  = "RuntimeError",
                    exception_value = "Built-in '%s' cannot be replaced." % (
                        builtin_name
                    ),
                    expression      = call_node
                ),
                source_ref     = source_ref
            )

        assert tags != ""

        return new_node, tags, message
    else:
        if False and isDebug() and builtin_name not in _builtin_white_list:
            warning(
                "Not handling built-in '%s', consider support." % builtin_name
            )

        return call_node, None, None
Exemple #10
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=tmp_target_variable,
            source=makeExpressionImportModuleNameHard(module_name="sys",
                                                      import_name="stdout",
                                                      source_ref=source_ref),
            source_ref=source_ref,
        )

        statements = [
            StatementAssignmentVariable(
                variable=tmp_target_variable,
                source=buildNode(provider=provider,
                                 node=node.dest,
                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
            makeStatementConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionTempVariableRef(
                        variable=tmp_target_variable, source_ref=source_ref),
                    right=ExpressionConstantNoneRef(source_ref=source_ref),
                    source_ref=source_ref,
                ),
                yes_branch=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)
def buildForLoopNode(provider, node, source_ref):
    # The for loop is re-formulated according to developer manual. An iterator
    # is created, and looped until it gives StopIteration. The else block is
    # taken if a for loop exits normally, i.e. because of iterator
    # exhaustion. We do this by introducing an indicator variable.

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

    temp_scope = provider.allocateTempScope("for_loop")

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

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

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

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

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source       = ExpressionConstantRef(
                    constant   = True,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]
    else:
        statements = []

    statements.append(
        StatementBreakLoop(
            source_ref = source_ref
        )
    )

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

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

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

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

    cleanup_statements = [
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_value_variable,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        )
    ]

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

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

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

        statements = (
            makeTryFinallyStatement(
                tried      = statements,
                final      = StatementDelVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_break_indicator,
                        source_ref = source_ref
                    ),
                    tolerant     = False,
                    source_ref   = source_ref
                ),
                source_ref = source_ref
            ),
        )

    return StatementsSequence(
        statements = statements,
        source_ref = source_ref
    )
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, exec_mode,
                             source_ref):
    """ Wrap the locals and globals arguments for eval and exec.

        For eval, this is called from the outside, and when the node tree
        already exists.
    """

    if globals_node is not None:
        global_keeper_variable = provider.allocateTempKeeperVariable()
        tmp_global_assign = ExpressionAssignmentTempKeeper(
            variable=global_keeper_variable.makeReference(provider),
            source=globals_node,
            source_ref=source_ref)

        globals_wrap = ExpressionConditional(
            condition=ExpressionComparisonIs(left=tmp_global_assign,
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            no_expression=ExpressionTempKeeperRef(
                variable=global_keeper_variable.makeReference(provider),
                source_ref=source_ref),
            yes_expression=ExpressionBuiltinGlobals(source_ref=source_ref),
            source_ref=source_ref)
    else:
        globals_wrap = ExpressionBuiltinGlobals(source_ref=source_ref)

    if locals_node is not None:
        local_keeper_variable = provider.allocateTempKeeperVariable()
        tmp_local_assign = ExpressionAssignmentTempKeeper(
            variable=local_keeper_variable.makeReference(provider),
            source=locals_node,
            source_ref=source_ref)

        if exec_mode:
            locals_fallback = ExpressionBuiltinLocals(source_ref=source_ref)
        else:
            locals_fallback = ExpressionConditional(
                condition=ExpressionComparisonIs(left=ExpressionTempKeeperRef(
                    variable=global_keeper_variable.makeReference(provider),
                    source_ref=source_ref),
                                                 right=ExpressionConstantRef(
                                                     constant=None,
                                                     source_ref=source_ref),
                                                 source_ref=source_ref),
                no_expression=ExpressionTempKeeperRef(
                    variable=global_keeper_variable.makeReference(provider),
                    source_ref=source_ref),
                yes_expression=ExpressionBuiltinLocals(source_ref=source_ref),
                source_ref=source_ref)

        locals_wrap = ExpressionConditional(
            condition=ExpressionComparisonIs(left=tmp_local_assign,
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            no_expression=ExpressionTempKeeperRef(
                variable=local_keeper_variable.makeReference(provider),
                source_ref=source_ref),
            yes_expression=locals_fallback,
            source_ref=source_ref)
    else:
        if globals_node is None:
            locals_wrap = ExpressionBuiltinLocals(source_ref=source_ref)
        else:
            locals_wrap = ExpressionTempKeeperRef(
                variable=global_keeper_variable.makeReference(provider),
                source_ref=source_ref)

    return globals_wrap, locals_wrap
def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref):
    # Many details, pylint: disable=too-many-branches,too-many-locals
    with_source = buildNode(provider, context_expr, source_ref)

    if python_version < 0x380 and Options.is_fullcompat:
        source_ref = with_source.getCompatibleSourceReference()

    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"
    )

    # Indicator variable, will end up with C bool type, and need not be released.
    tmp_indicator_variable = provider.allocateTempVariable(
        temp_scope=temp_scope, name="indicator", temp_type="bool"
    )

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

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

    if body and python_version < 0x3A0:
        deepest = body

        while deepest.getVisitableNodes():
            deepest = deepest.getVisitableNodes()[-1]

        if python_version < 0x370:
            body_lineno = deepest.getCompatibleSourceReference().getLineNumber()
        else:
            body_lineno = deepest.getSourceReference().getLineNumber()

        with_exit_source_ref = source_ref.atLineNumber(body_lineno)
    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 python_version < 0x270:
        attribute_lookup_maker = makeExpressionAttributeLookup
    else:
        attribute_lookup_maker = ExpressionAttributeLookupSpecial

    enter_value = ExpressionCallEmpty(
        called=attribute_lookup_maker(
            expression=ExpressionTempVariableRef(
                variable=tmp_source_variable, source_ref=source_ref
            ),
            attribute_name="__enter__" if sync else "__aenter__",
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    exit_value_exception = ExpressionCallNoKeywords(
        called=ExpressionTempVariableRef(
            variable=tmp_exit_variable, source_ref=with_exit_source_ref
        ),
        args=makeExpressionMakeTuple(
            elements=(
                ExpressionCaughtExceptionTypeRef(source_ref=with_exit_source_ref),
                ExpressionCaughtExceptionValueRef(source_ref=with_exit_source_ref),
                ExpressionCaughtExceptionTracebackRef(source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
        source_ref=with_exit_source_ref,
    )

    exit_value_no_exception = ExpressionCallNoKeywords(
        called=ExpressionTempVariableRef(
            variable=tmp_exit_variable, source_ref=source_ref
        ),
        args=makeConstantRefNode(constant=(None, None, None), source_ref=source_ref),
        source_ref=with_exit_source_ref,
    )

    # For "async with", await the entered value and exit value must be awaited.
    if not sync:
        exit_value_exception = ExpressionYieldFromWaitable(
            expression=ExpressionAsyncWaitExit(
                expression=exit_value_exception, source_ref=source_ref
            ),
            source_ref=source_ref,
        )
        exit_value_no_exception = ExpressionYieldFromWaitable(
            ExpressionAsyncWaitExit(
                expression=exit_value_no_exception, source_ref=source_ref
            ),
            source_ref=source_ref,
        )

    # First assign the with context to a temporary variable.
    statements = [
        StatementAssignmentVariable(
            variable=tmp_source_variable, source=with_source, source_ref=source_ref
        )
    ]

    # Before 3.9, __aenter__ is immediately awaited, after we first do __aexit__ lookup.
    if not sync and python_version < 0x390:
        enter_value = ExpressionYieldFromWaitable(
            expression=ExpressionAsyncWaitEnter(
                expression=enter_value, source_ref=source_ref
            ),
            source_ref=source_ref,
        )

    attribute_enter_assignment = StatementAssignmentVariable(
        variable=tmp_enter_variable, source=enter_value, source_ref=source_ref
    )

    attribute_exit_assignment = StatementAssignmentVariable(
        variable=tmp_exit_variable,
        source=attribute_lookup_maker(
            expression=ExpressionTempVariableRef(
                variable=tmp_source_variable, source_ref=source_ref
            ),
            attribute_name="__exit__" if sync else "__aexit__",
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Next, assign "__enter__" and "__exit__" attributes to temporary variables, and
    # depending on Python versions switch the order of these lookups and the order of
    # awaiting enter.
    # Normal "with" statements are enter, exit ordered after 3.6, and "async with"
    # are since 3.9, and since 3.9 the enter is not awaited, until an exit is present.
    if python_version >= 0x390 and not sync:
        enter_await_statement = StatementAssignmentVariable(
            variable=tmp_enter_variable,
            source=ExpressionYieldFromWaitable(
                expression=ExpressionAsyncWaitEnter(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_enter_variable, source_ref=source_ref
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )

        attribute_assignments = (
            attribute_enter_assignment,
            attribute_exit_assignment,
            enter_await_statement,
        )
    elif python_version >= 0x360 and sync:
        attribute_assignments = (attribute_enter_assignment, attribute_exit_assignment)
    else:
        attribute_assignments = (attribute_exit_assignment, attribute_enter_assignment)

    statements.extend(attribute_assignments)

    statements.append(
        StatementAssignmentVariable(
            variable=tmp_indicator_variable,
            source=makeConstantRefNode(constant=True, source_ref=source_ref),
            source_ref=source_ref,
        )
    )

    statements += (
        makeTryFinallyStatement(
            provider=provider,
            tried=makeTryExceptSingleHandlerNodeWithPublish(
                provider=provider,
                tried=with_body,
                exception_name="BaseException",
                handler_body=StatementsSequence(
                    statements=(
                        # Prevents final block from calling __exit__ as
                        # well.
                        StatementAssignmentVariable(
                            variable=tmp_indicator_variable,
                            source=makeConstantRefNode(
                                constant=False, source_ref=source_ref
                            ),
                            source_ref=source_ref,
                        ),
                        makeStatementConditional(
                            condition=exit_value_exception,
                            no_branch=makeReraiseExceptionStatement(
                                source_ref=with_exit_source_ref
                            ),
                            yes_branch=None,
                            source_ref=with_exit_source_ref,
                        ),
                    ),
                    source_ref=source_ref,
                ),
                public_exc=python_version >= 0x270,
                source_ref=source_ref,
            ),
            final=makeStatementConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionTempVariableRef(
                        variable=tmp_indicator_variable, source_ref=source_ref
                    ),
                    right=makeConstantRefNode(constant=True, source_ref=source_ref),
                    source_ref=source_ref,
                ),
                yes_branch=StatementExpressionOnly(
                    expression=exit_value_no_exception, source_ref=source_ref
                ),
                no_branch=None,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
    )

    return makeTryFinallyStatement(
        provider=provider,
        tried=statements,
        final=(
            StatementReleaseVariable(
                variable=tmp_source_variable, source_ref=with_exit_source_ref
            ),
            StatementReleaseVariable(
                variable=tmp_enter_variable, source_ref=with_exit_source_ref
            ),
            StatementReleaseVariable(
                variable=tmp_exit_variable, source_ref=with_exit_source_ref
            ),
        ),
        source_ref=source_ref,
    )
def buildForLoopNode(provider, node, source_ref):
    # The for loop is re-formulated according to developer manual. An iterator is created,
    # and looped until it gives StopIteration. The else block is taken if a for loop exits
    # normally, i.e. because of iterator exhaustion. We do this by introducing an
    # indicator variable.

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

    result = StatementTempBlock(source_ref=source_ref)

    tmp_iter_variable = result.getTempVariable("for_iterator")

    iterate_tmp_block = StatementTempBlock(source_ref=source_ref)

    tmp_value_variable = iterate_tmp_block.getTempVariable("iter_value")

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

    if else_block is not None:
        tmp_break_indicator_variable = result.getTempVariable(
            "break_indicator")

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

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

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

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

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

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

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

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

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable.makeReference(result),
                source_ref=source_ref),
            source=ExpressionBuiltinIter1(
                value=source, source_ref=source.getSourceReference()),
            source_ref=source_ref),
        StatementLoop(body=loop_body, source_ref=source_ref)
    ]

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

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

    return result
Exemple #15
0
    def wrapEvalBuiltin(source, globals, locals, source_ref):
        provider = node.getParentVariableProvider()

        temp_scope = provider.allocateTempScope("eval")

        globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals(
            provider     = provider,
            globals_node = globals,
            locals_node  = locals,
            temp_scope   = temp_scope,
            source_ref   = source_ref
        )

        # The wrapping should not relocate to the "source_ref".
        assert globals is None or \
               globals_ref.getSourceReference() == globals.getSourceReference()
        assert locals is None or \
               locals_ref.getSourceReference() == locals.getSourceReference()

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

        final.setStatements(
            final.getStatements() + (
                StatementDelVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = source_variable.makeReference(
                            provider
                        ),
                        source_ref = source_ref
                    ),
                    tolerant     = True,
                    source_ref   = source_ref
                ),
            )
        )

        strip_choice =  ExpressionConstantRef(
            constant = (" \t",),
            source_ref = source_ref
        )

        if python_version >= 300:
            strip_choice = ExpressionConditional(
                condition = ExpressionComparisonIs(
                    left       = ExpressionBuiltinType1(
                        value      = ExpressionTempVariableRef(
                            variable   = source_variable.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    right      = ExpressionBuiltinRef(
                        builtin_name = "bytes",
                        source_ref   = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_expression = ExpressionConstantRef(
                    constant = (b" \t",),
                    source_ref = source_ref
                ),
                no_expression  = strip_choice,
                source_ref     = source_ref
            )


        # Source needs some special treatment for eval, if it's a string, it
        # must be stripped.
        string_fixup = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = source_variable.makeReference(
                        provider
                    ),
                    source_ref = source_ref
                ),
                source = ExpressionCallNoKeywords(
                    called = ExpressionAttributeLookup(
                        expression     = ExpressionTempVariableRef(
                            variable   = source_variable.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        attribute_name = "strip",
                        source_ref     = source_ref
                    ),
                    args         = strip_choice,
                    source_ref   = source_ref
                ),
                source_ref = source_ref
            )
        ]

        statements = (
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = source_variable.makeReference(
                        provider
                    ),
                    source_ref = source_ref
                ),
                source       = source,
                source_ref   = source_ref,
            ),
            StatementConditional(
                condition = ExpressionOperationNOT(
                    operand    = ExpressionBuiltinIsinstance(
                        cls = ExpressionBuiltinAnonymousRef(
                            builtin_name = "code",
                            source_ref   = source_ref,
                        ),
                        instance = ExpressionTempVariableRef(
                            variable   = source_variable.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = StatementsSequence(
                    statements = string_fixup,
                    source_ref = source_ref
                ),
                no_branch  = None,
                source_ref = source_ref
            )
        )

        tried.setStatements(
            tried.getStatements() + statements
        )

        return ExpressionTryFinally(
            tried      = tried,
            expression = ExpressionBuiltinEval(
                source_code = ExpressionTempVariableRef(
                    variable   = source_variable.makeReference(
                        provider
                    ),
                    source_ref = source_ref
                ),
                globals_arg = globals_ref,
                locals_arg  = locals_ref,
                source_ref  = source_ref
            ),
            final      = final,
            source_ref = source_ref
        )
Exemple #16
0
def computeBuiltinCall(call_node, called):
    builtin_name = called.getBuiltinName()

    if builtin_name in _dispatch_dict:
        new_node = _dispatch_dict[builtin_name](call_node)

        # Lets just have this contract to return "None" when no change is meant
        # to be done.
        assert new_node is not call_node
        if new_node is None:
            return call_node, None, None

        # For traces, we are going to ignore side effects, and output traces
        # only based on the basis of it.
        inspect_node = new_node
        if inspect_node.isExpressionSideEffects():
            inspect_node = inspect_node.getExpression()

        if inspect_node.isExpressionBuiltinImport():
            tags    = "new_import"
            message = """\
Replaced dynamic __import__ %s with static module import.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionBuiltin() or \
             inspect_node.isStatementExec():
            tags = "new_builtin"
            message = "Replaced call to builtin %s with builtin call %s." % (
                builtin_name,
                inspect_node.kind,
            )
        elif inspect_node.isExpressionRaiseException():
            tags = "new_raise"
            message = """\
Replaced call to builtin %s with exception raising call.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionOperationUnary():
            tags = "new_expression"
            message = """\
Replaced call to builtin %s with unary operation %s.""" % (
                inspect_node.kind,
                inspect_node.getOperator()
            )
        elif inspect_node.isExpressionCall():
            tags = "new_expression"
            message = """\
Replaced call to builtin %s with call.""" % (
                inspect_node.kind,
            )
        elif inspect_node.isExpressionTryFinally():
            tags = "new_expression"
            message = """\
Replaced call to builtin %s with try/finally guarded call.""" % (
                inspect_node.getExpression().kind,
            )
        else:

            assert False, ( builtin_name, "->", inspect_node )

        # TODO: One day, this should be enabled by default and call either the
        # original built-in or the optimized above one. That should be done,
        # once we can eliminate the condition for most cases.
        if False and isDebug() and not shallMakeModule() and builtin_name:
            from nuitka.nodes.NodeMakingHelpers import \
              makeRaiseExceptionReplacementExpression

            source_ref = called.getSourceReference()

            new_node = ExpressionConditional(
                condition      = ExpressionComparisonIs(
                    left  = ExpressionBuiltinRef(
                        builtin_name = builtin_name,
                        source_ref   = source_ref
                    ),
                    right = ExpressionBuiltinOriginalRef(
                        builtin_name = builtin_name,
                        source_ref   = source_ref
                    ),
                    source_ref   = source_ref
                ),
                yes_expression = new_node,
                no_expression  = makeRaiseExceptionReplacementExpression(
                    exception_type  = "RuntimeError",
                    exception_value = "Builtin '%s' was overloaded'" % (
                        builtin_name
                    ),
                    expression      = call_node
                ),
                source_ref     = source_ref
            )

        assert tags != ""

        return new_node, tags, message
    else:
        # TODO: Consider giving warnings, whitelisted potentially
        return call_node, None, None
def buildExecNode(provider, node, source_ref):
    # "exec" statements, should only occur with Python2.

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

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

    orig_globals = exec_globals

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

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

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

    if provider.isExpressionFunctionBody():
        provider.markAsExecContaining()

        if orig_globals is None:
            provider.markAsUnqualifiedExecContaining(source_ref)

    temp_scope = provider.allocateTempScope("exec")

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

    if locals_value is None:
        locals_value = ExpressionConstantRef(constant=None,
                                             source_ref=source_ref)

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

    if globals_value is None:
        globals_value = ExpressionConstantRef(constant=None,
                                              source_ref=source_ref)

    source_code = buildNode(provider, body, source_ref)

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

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

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

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

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

    final = makeStatementsSequenceFromStatements(
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=source_variable, source_ref=source_ref),
                             tolerant=True,
                             source_ref=source_ref),
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=globals_keeper_variable, source_ref=source_ref),
                             tolerant=True,
                             source_ref=source_ref),
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=locals_keeper_variable, source_ref=source_ref),
                             tolerant=True,
                             source_ref=source_ref),
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=plain_indicator_variable, source_ref=source_ref),
                             tolerant=True,
                             source_ref=source_ref),
    )

    return StatementTryFinally(tried=tried,
                               final=final,
                               public_exc=False,
                               source_ref=source_ref)
Exemple #18
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=tmp_break_indicator,
                source=makeConstantRefNode(constant=True, source_ref=source_ref),
                source_ref=source_ref,
            ),
            StatementLoopBreak(source_ref=source_ref),
        )
    else:
        statements = (StatementLoopBreak(source_ref=source_ref),)

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

    # The loop body contains a conditional statement at the start that breaks
    # the loop if it fails.
    loop_body = makeStatementsSequence(
        statements=(
            makeStatementConditional(
                condition=ExpressionOperationNOT(
                    operand=buildNode(provider, node.test, source_ref),
                    source_ref=source_ref,
                ),
                yes_branch=StatementsSequence(
                    statements=statements, source_ref=source_ref
                ),
                no_branch=None,
                source_ref=source_ref,
            ),
            loop_statements,
        ),
        allow_none=True,
        source_ref=source_ref,
    )

    loop_statement = StatementLoop(body=loop_body, source_ref=source_ref)

    if else_block is None:
        return loop_statement
    else:
        statements = (
            StatementAssignmentVariable(
                variable=tmp_break_indicator,
                source=makeConstantRefNode(constant=False, source_ref=source_ref),
                source_ref=source_ref,
            ),
            loop_statement,
            makeStatementConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionTempVariableRef(
                        variable=tmp_break_indicator, source_ref=source_ref
                    ),
                    right=makeConstantRefNode(constant=True, source_ref=source_ref),
                    source_ref=source_ref,
                ),
                yes_branch=else_block,
                no_branch=None,
                source_ref=source_ref,
            ),
        )

        statements = (
            makeTryFinallyStatement(
                provider=provider,
                tried=statements,
                final=StatementReleaseVariable(
                    variable=tmp_break_indicator, source_ref=source_ref
                ),
                source_ref=source_ref,
            ),
        )

        return StatementsSequence(
            statements=mergeStatements(statements, False), source_ref=source_ref
        )
Exemple #19
0
def buildTryFinallyNode(provider, build_tried, node, source_ref):

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

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

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

        pushIndicatorVariable(tmp_indicator_var)

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

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

        popIndicatorVariable()

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

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

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

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

        return StatementTryFinally(
            tried      = tried,
            final      = final,
            public_exc = True,
            source_ref = source_ref
        )
def _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,
                                                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, 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, source_ref=source_ref),
            source=attribute_lookup_class(source=ExpressionTempVariableRef(
                variable=tmp_source_variable, source_ref=source_ref),
                                          attribute_name="__exit__",
                                          source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_enter_variable, source_ref=source_ref),
            source=ExpressionCallEmpty(called=attribute_lookup_class(
                source=ExpressionTempVariableRef(variable=tmp_source_variable,
                                                 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, 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,
                                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,
                                    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,
                        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,
                                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, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_enter_variable, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_exit_variable, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_indicator_variable, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
        ),
        source_ref=source_ref)
Exemple #21
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=too-many-locals

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

    # Temporary variables, we need one for the iterator, and one for the current
    # value.
    temp_scope = provider.allocateTempScope("for_loop")

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

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

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

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source       = makeConstantRefNode(
                    constant   = True,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]
    else:
        statements = []

    statements.append(
        StatementLoopBreak(
            source_ref = source_ref
        )
    )

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

    if sync:
        next_node = ExpressionBuiltinNext1(
            value      = ExpressionTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    else:
        next_node = ExpressionAsyncNext(
            value      = ExpressionTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )

    statements = (
        makeTryExceptSingleHandlerNode(
            tried          = StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_value_variable,
                    source_ref = source_ref
                ),
                source       = next_node,
                source_ref   = source_ref
            ),
            exception_name = "StopIteration" if sync else "StopAsyncIteration",
            handler_body   = handler_body,
            source_ref     = source_ref
        ),
        buildAssignmentStatements(
            provider   = provider,
            node       = node.target,
            source     = ExpressionTempVariableRef(
                variable   = tmp_value_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    pushBuildContext("loop_body")
    statements += (
        buildStatementsNode(
            provider   = provider,
            nodes      = node.body,
            source_ref = source_ref
        ),
    )
    popBuildContext()

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

    cleanup_statements = [
        StatementReleaseVariable(
            variable   = tmp_value_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_iter_variable,
            source_ref = source_ref
        )
    ]

    if else_block is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source       = makeConstantRefNode(
                    constant   = False,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]
    else:
        statements = []

    if sync:
        iter_source = ExpressionBuiltinIter1(
            value      = source,
            source_ref = source.getSourceReference()
        )
    else:
        iter_source = ExpressionAsyncIter(
            value      = source,
            source_ref = source.getSourceReference()
        )

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source       = iter_source,
            source_ref   = source_ref
        ),
        makeTryFinallyStatement(
            provider   = provider,
            tried      = StatementLoop(
                body       = loop_body,
                source_ref = source_ref
            ),
            final      = StatementsSequence(
                statements = cleanup_statements,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    ]

    if else_block is not None:
        statements += [
            StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_break_indicator,
                        source_ref = source_ref
                    ),
                    right      = makeConstantRefNode(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = else_block,
                no_branch  = None,
                source_ref = source_ref
            )
        ]

        statements = (
            makeTryFinallyStatement(
                provider   = provider,
                tried      = statements,
                final      = StatementReleaseVariable(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
        )

    return makeStatementsSequenceFromStatements(
        *statements
    )
Exemple #22
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=makeExpressionBuiltinLocals(provider=provider,
                                                   source_ref=source_ref),
        source_ref=source_ref,
    )

    pre_statements = [
        # First assign globals and locals temporary the values given.
        StatementAssignmentVariable(variable=globals_keeper_variable,
                                    source=globals_node,
                                    source_ref=source_ref),
        StatementAssignmentVariable(variable=locals_keeper_variable,
                                    source=locals_node,
                                    source_ref=source_ref),
        makeStatementConditional(
            condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(variable=locals_keeper_variable,
                                               source_ref=source_ref),
                right=ExpressionConstantNoneRef(source_ref=source_ref),
                source_ref=source_ref,
            ),
            yes_branch=StatementAssignmentVariable(
                variable=locals_keeper_variable,
                source=locals_default,
                source_ref=source_ref,
            ),
            no_branch=None,
            source_ref=source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=globals_keeper_variable, source_ref=source_ref),
                right=ExpressionConstantNoneRef(source_ref=source_ref),
                source_ref=source_ref,
            ),
            yes_branch=StatementAssignmentVariable(
                variable=globals_keeper_variable,
                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),
    )
Exemple #23
0
def wrapEvalGlobalsAndLocals(provider, globals, locals, exec_mode, source_ref):
    if globals is not None:
        global_keeper_variable = provider.getTempKeeperVariable()
        tmp_global_assign = ExpressionAssignmentTempKeeper(
            variable=global_keeper_variable.makeReference(provider),
            source=globals,
            source_ref=source_ref)

        globals_wrap = ExpressionConditional(
            condition=ExpressionComparisonIs(left=tmp_global_assign,
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            no_expression=ExpressionTempKeeperRef(
                variable=global_keeper_variable.makeReference(provider),
                source_ref=source_ref),
            yes_expression=ExpressionBuiltinGlobals(source_ref=source_ref),
            source_ref=source_ref)
    else:
        globals_wrap = ExpressionBuiltinGlobals(source_ref=source_ref)

    if locals is not None:
        local_keeper_variable = provider.getTempKeeperVariable()
        tmp_local_assign = ExpressionAssignmentTempKeeper(
            variable=local_keeper_variable.makeReference(provider),
            source=locals,
            source_ref=source_ref)

        if exec_mode:
            locals_fallback = ExpressionBuiltinLocals(source_ref=source_ref)
        else:
            locals_fallback = ExpressionConditional(
                condition=ExpressionComparisonIs(left=ExpressionTempKeeperRef(
                    variable=global_keeper_variable.makeReference(provider),
                    source_ref=source_ref),
                                                 right=ExpressionConstantRef(
                                                     constant=None,
                                                     source_ref=source_ref),
                                                 source_ref=source_ref),
                no_expression=ExpressionTempKeeperRef(
                    variable=global_keeper_variable.makeReference(provider),
                    source_ref=source_ref),
                yes_expression=ExpressionBuiltinLocals(source_ref=source_ref),
                source_ref=source_ref)

        locals_wrap = ExpressionConditional(
            condition=ExpressionComparisonIs(left=tmp_local_assign,
                                             right=ExpressionConstantRef(
                                                 constant=None,
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            no_expression=ExpressionTempKeeperRef(
                variable=local_keeper_variable.makeReference(provider),
                source_ref=source_ref),
            yes_expression=locals_fallback,
            source_ref=source_ref)
    else:
        if globals is None:
            locals_wrap = ExpressionBuiltinLocals(source_ref=source_ref)
        else:
            locals_wrap = ExpressionTempKeeperRef(
                variable=global_keeper_variable.makeReference(provider),
                source_ref=source_ref)

    return globals_wrap, locals_wrap
    def wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref):
        provider = node.getParentVariableProvider()

        outline_body = ExpressionOutlineBody(
            provider=node.getParentVariableProvider(),
            name="eval_call",
            source_ref=source_ref,
        )

        globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals(
            provider=provider,
            globals_node=globals_arg,
            locals_node=locals_arg,
            temp_scope=outline_body.getOutlineTempScope(),
            source_ref=source_ref,
        )

        # The wrapping should not relocate to the "source_ref".
        assert (globals_arg is None or globals_ref.getSourceReference()
                == globals_arg.getSourceReference())
        assert (locals_arg is None or locals_ref.getSourceReference()
                == locals_arg.getSourceReference())

        source_variable = outline_body.allocateTempVariable(temp_scope=None,
                                                            name="source")

        final.setStatements(final.getStatements() + (StatementDelVariable(
            variable=source_variable, tolerant=True, source_ref=source_ref), ))

        strip_choice = makeConstantRefNode(constant=(" \t", ),
                                           source_ref=source_ref)

        if python_version >= 300:
            strip_choice = ExpressionConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionBuiltinType1(
                        value=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref),
                        source_ref=source_ref,
                    ),
                    right=makeExpressionBuiltinRef(builtin_name="bytes",
                                                   source_ref=source_ref),
                    source_ref=source_ref,
                ),
                expression_yes=makeConstantRefNode(constant=(b" \t", ),
                                                   source_ref=source_ref),
                expression_no=strip_choice,
                source_ref=source_ref,
            )

        # Source needs some special treatment for eval, if it's a string, it
        # must be stripped.
        string_fixup = StatementAssignmentVariable(
            variable=source_variable,
            source=makeExpressionCall(
                called=ExpressionAttributeLookup(
                    source=ExpressionTempVariableRef(variable=source_variable,
                                                     source_ref=source_ref),
                    attribute_name="strip",
                    source_ref=source_ref,
                ),
                args=strip_choice,  # This is a tuple
                kw=None,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )

        acceptable_builtin_types = [
            ExpressionBuiltinAnonymousRef(builtin_name="code",
                                          source_ref=source_ref)
        ]

        if python_version >= 270:
            acceptable_builtin_types.append(
                makeExpressionBuiltinRef(builtin_name="memoryview",
                                         source_ref=source_ref))

        statements = (
            StatementAssignmentVariable(variable=source_variable,
                                        source=source,
                                        source_ref=source_ref),
            makeStatementConditional(
                condition=ExpressionOperationNOT(
                    operand=ExpressionBuiltinIsinstance(
                        instance=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref),
                        classes=makeSequenceCreationOrConstant(
                            sequence_kind="tuple",
                            elements=acceptable_builtin_types,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                yes_branch=string_fixup,
                no_branch=None,
                source_ref=source_ref,
            ),
            StatementReturn(
                expression=ExpressionBuiltinEval(
                    source_code=ExpressionTempVariableRef(
                        variable=source_variable, source_ref=source_ref),
                    globals_arg=globals_ref,
                    locals_arg=locals_ref,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
        )

        tried = makeStatementsSequence(statements=(tried, ) + statements,
                                       allow_none=False,
                                       source_ref=source_ref)

        outline_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider=outline_body,
                    tried=tried,
                    final=final,
                    source_ref=source_ref,
                )))

        return outline_body
Exemple #25
0
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")

        # This makes sure, we set the indicator variables for "break",
        # "continue" and "return" exits as well to true, so we can
        # know if an exception occurred or not.
        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.atLineNumber(99)),
                          source_ref=source_ref.atInternal()))

        # Prevent "continue" statements in the final blocks, these have to
        # become "SyntaxError".
        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=(
                StatementReleaseVariable(variable=tmp_indicator_var,
                                         tolerant=False,
                                         source_ref=source_ref.atInternal()),
                StatementReraiseFrameException(
                    source_ref=source_ref.atInternal()),
            ),
                                          source_ref=source_ref.atInternal()),
            no_branch=StatementsSequence(statements=(StatementReleaseVariable(
                variable=tmp_indicator_var,
                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)
Exemple #26
0
def computeBuiltinCall(call_node, called):
    builtin_name = called.getBuiltinName()

    if builtin_name in _dispatch_dict:
        new_node = _dispatch_dict[builtin_name](call_node)

        if new_node is None:
            return call_node, None, None

        inspect_node = new_node

        if inspect_node.isExpressionSideEffects():
            inspect_node = inspect_node.getExpression()

        if inspect_node.isExpressionBuiltinImport():
            tags = "new_import"
            message = "Replaced dynamic builtin import %s with static module import." % inspect_node.kind
        elif inspect_node.isExpressionBuiltin(
        ) or inspect_node.isStatementExec():
            tags = "new_builtin"
            message = "Replaced call to builtin with builtin call %s." % inspect_node.kind
        elif inspect_node.isExpressionRaiseException():
            tags = "new_raise"
            message = "Replaced call to builtin %s with exception raising call." % inspect_node.kind
        elif inspect_node.isExpressionOperationUnary():
            tags = "new_expression"
            message = "Replaced call to builtin %s with unary operation %s." % (
                inspect_node.kind, inspect_node.getOperator())
        else:
            assert False, (builtin_name, "->", inspect_node)

        # TODO: One day, this should be enabled by default and call either the original
        # built-in or the optimized above one. That should be done, once we can eliminate
        # the condition for most cases.
        if False and isDebug() and not shallMakeModule() and builtin_name:
            from nuitka.nodes.ConditionalNodes import ExpressionConditional
            from nuitka.nodes.ComparisonNodes import ExpressionComparisonIs
            from nuitka.nodes.BuiltinRefNodes import (
                ExpressionBuiltinExceptionRef,
                ExpressionBuiltinOriginalRef,
                ExpressionBuiltinRef,
            )
            from nuitka.nodes.ExceptionNodes import ExpressionRaiseException

            source_ref = called.getSourceReference()

            new_node = ExpressionConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionBuiltinRef(builtin_name=builtin_name,
                                              source_ref=source_ref),
                    right=ExpressionBuiltinOriginalRef(
                        builtin_name=builtin_name, source_ref=source_ref),
                    source_ref=source_ref),
                yes_expression=new_node,
                no_expression=makeRaiseExceptionReplacementExpression(
                    exception_type="RuntimeError",
                    exception_value="Builtin '%s' was overloaded'" %
                    builtin_name,
                    expression=call_node),
                source_ref=source_ref)

        return new_node, tags, message
    else:
        # TODO: Consider giving warnings, whitelisted potentially
        return call_node, None, None
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