Ejemplo n.º 1
0
def buildLambdaNode(provider, node, source_ref):
    assert getKind(node) == "Lambda"

    parameters = buildParameterSpec(provider, "<lambda>", node, source_ref)

    function_body = ExpressionFunctionBody(
        provider=provider,
        name="<lambda>",
        doc=None,
        parameters=parameters,
        source_ref=source_ref,
    )

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

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

    if function_body.isGenerator():
        if Utils.python_version < 270:
            tmp_return_value = function_body.allocateTempVariable(
                temp_scope=None, name="yield_return")

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

    body = StatementsFrame(
        statements=mergeStatements((body, )),
        guard_mode="generator" if function_body.isGenerator() else "full",
        var_names=parameters.getCoArgNames(),
        arg_count=parameters.getArgumentCount(),
        kw_only_count=parameters.getKwOnlyParameterCount(),
        has_starlist=parameters.getStarListArgumentName() is not None,
        has_stardict=parameters.getStarDictArgumentName() is not None,
        code_name="<lambda>",
        source_ref=body.getSourceReference())

    body = makeStatementsSequenceFromStatement(statement=body, )

    function_body.setBody(body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    return ExpressionFunctionCreation(function_ref=ExpressionFunctionRef(
        function_body=function_body, source_ref=source_ref),
                                      defaults=defaults,
                                      kw_defaults=kw_defaults,
                                      annotations=annotations,
                                      source_ref=source_ref)
Ejemplo n.º 2
0
def buildParseTree(provider, source_code, source_ref, is_module, is_main):
    # There are a bunch of branches here, mostly to deal with version
    # differences for module default variables. pylint: disable=R0912

    # Workaround: ast.parse cannot cope with some situations where a file is not
    # terminated by a new line.
    if not source_code.endswith('\n'):
        source_code = source_code + '\n'

    try:
        body = ast.parse(source_code, source_ref.getFilename())
    except SyntaxError as e:
        _makeSyntaxErrorCompatible(e)

        raise e

    assert getKind(body) == "Module"

    line_offset = source_ref.getLineNumber() - 1

    if line_offset > 0:
        for created_node in ast.walk(body):
            if hasattr(created_node, "lineno"):
                created_node.lineno += line_offset

    body, doc = extractDocFromBody(body)

    result = buildStatementsNode(
        provider   = provider,
        nodes      = body,
        source_ref = source_ref
    )

    checkFutureImportsOnlyAtStart(body)

    internal_source_ref = source_ref.atInternal()

    statements = []

    if is_module:
        # Add import of "site" module of main programs visibly in the node tree,
        # so recursion and optimization can pick it up, checking its effects.
        if is_main and not sys.flags.no_site:
            statements.append(
                StatementExpressionOnly(
                    expression = ExpressionImportModule(
                        module_name = "site",
                        import_list = (),
                        level       = 0,
                        source_ref  = source_ref,
                    ),
                    source_ref = source_ref
                )
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = doc,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__file__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionModuleFileAttributeRef(
                    source_ref = internal_source_ref,
                ),
                source_ref   = internal_source_ref
            )
        )

        if provider.isPythonPackage():
            # This assigns "__path__" value.
            statements.append(
                createPathAssignment(internal_source_ref)
            )

    if Utils.python_version >= 300:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__cached__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = None,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if Utils.python_version >= 330:
        # For Python3.3, it's set for both packages and non-packages.
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__package__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = provider.getFullName()
                                      if provider.isPythonPackage() else
                                    provider.getPackage(),
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

    needs__initializing__ = not provider.isMainModule() and \
      (Utils.python_version >= 330 and Utils.python_version < 340)

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = True,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )

    # Now the module body if there is any at all.
    if result is not None:
        statements.extend(
            result.getStatements()
        )

    if needs__initializing__:
        # Set "__initializing__" at the end to False
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__initializing__",
                    source_ref    = internal_source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = False,
                    source_ref    = internal_source_ref,
                    user_provided = True
                ),
                source_ref   = internal_source_ref
            )
        )


    if is_module:
        result = makeModuleFrame(
            module     = provider,
            statements = statements,
            source_ref = source_ref
        )

        applyLaterWrappers()

        return result
    else:
        assert False
def buildListContractionNode(provider, node, source_ref):
    # List contractions are dealt with by general code.

    if Utils.python_version < 300:
        temp_scope = provider.allocateTempScope("listcontr")

        outer_iter_var = provider.allocateTempVariable(temp_scope=temp_scope,
                                                       name="listcontr_iter")

        outer_iter_ref = ExpressionTempVariableRef(
            variable=outer_iter_var.makeReference(provider),
            source_ref=source_ref)

        container_tmp = provider.allocateTempVariable(temp_scope=temp_scope,
                                                      name="listcontr_result")

        statements, del_statements = _buildContractionBodyNode(
            provider=provider,
            node=node,
            emit_class=ExpressionListOperationAppend,
            start_value=ExpressionConstantRef(constant=[],
                                              source_ref=source_ref),
            outer_iter_ref=outer_iter_ref,
            container_tmp=container_tmp,
            temp_scope=temp_scope,
            assign_provider=True,
            source_ref=source_ref,
            function_body=provider)

        statements.insert(
            0,
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=outer_iter_var.makeReference(provider),
                    source_ref=source_ref),
                source=ExpressionBuiltinIter1(value=buildNode(
                    provider=provider,
                    node=node.generators[0].iter,
                    source_ref=source_ref),
                                              source_ref=source_ref),
                source_ref=source_ref))

        result = makeTryFinallyExpression(expression=ExpressionTempVariableRef(
            variable=container_tmp.makeReference(provider),
            source_ref=source_ref),
                                          tried=statements,
                                          final=del_statements,
                                          source_ref=source_ref)

        final = StatementsSequence(statements=(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=container_tmp.makeReference(provider),
                source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=outer_iter_var.makeReference(provider),
                source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref),
        ),
                                   source_ref=source_ref)

        wrapTryFinallyLater(node=result, final=final)

        return result

    return _buildContractionNode(
        provider=provider,
        node=node,
        name="<listcontraction>",
        emit_class=ExpressionListOperationAppend,
        start_value=ExpressionConstantRef(constant=[], source_ref=source_ref),
        # Note: For Python3, the list contractions no longer assign to the outer
        # scope.
        assign_provider=Utils.python_version < 300,
        source_ref=source_ref)
Ejemplo n.º 4
0
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,
                    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,
                    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 = StatementReleaseVariable(
        variable   = tmp_handler_indicator_variable,
        tolerant   = False,
        source_ref = source_ref.atInternal()
    ),

    return StatementsSequence(
        statements = (
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_handler_indicator_variable,
                    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
    )
Ejemplo n.º 5
0
def buildImportModulesNode(provider, node, source_ref):
    # Import modules statement. As described in the developer manual, these
    # statements can be treated as several ones.

    import_names   = [
        ( import_desc.name, import_desc.asname )
        for import_desc in
        node.names
    ]

    import_nodes = []

    for import_desc in import_names:
        module_name, local_name = import_desc

        module_topname = module_name.split('.')[0]

        # Note: The "level" of import is influenced by the future absolute
        # imports.
        level = 0 if source_ref.getFutureSpec().isAbsoluteImport() else -1

        if local_name:
            # If is gets a local name, the real name must be used as a
            # temporary value only, being looked up recursively.

            import_node = ExpressionImportModule(
                module_name = module_name,
                import_list = None,
                level       = level,
                source_ref  = source_ref
            )

            for import_name in module_name.split('.')[1:]:
                import_node = ExpressionImportName(
                    module      = import_node,
                    import_name = import_name,
                    source_ref  = source_ref
                )
        else:
            import_node = ExpressionImportModule(
                module_name = module_name,
                import_list = None,
                level       = level,
                source_ref  = source_ref
            )

        # If a name was given, use the one provided, otherwise the import gives
        # the top level package name given for assignment of the imported
        # module.

        import_nodes.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = mangleName(
                                      local_name
                                        if local_name is not None else
                                      module_topname,
                                      provider
                    ),
                    source_ref    = source_ref
                ),
                source       = import_node,
                source_ref   = source_ref
            )
        )

    # Note: Each import is sequential. It will potentially succeed, and the
    # failure of a later one is not changing that one bit . We can therefore
    # have a sequence of imports that only import one thing therefore.
    return makeStatementsSequenceOrStatement(
        statements = import_nodes,
        source_ref = source_ref
    )
Ejemplo n.º 6
0
def buildClassNode3(provider, node, source_ref):
    # Many variables, due to the huge re-formulation that is going on here,
    # which just has the complexity and optimization checks:
    # pylint: disable=I0021,too-many-branches,too-many-locals,too-many-statements

    # This function is the Python3 special case with special re-formulation as
    # according to developer manual.
    class_statement_nodes, class_doc = extractDocFromBody(node)

    # We need a scope for the temporary variables, and they might be closured.
    temp_scope = provider.allocateTempScope(name="class_creation")

    tmp_class_decl_dict = provider.allocateTempVariable(
        temp_scope=temp_scope, name="class_decl_dict"
    )
    tmp_metaclass = provider.allocateTempVariable(
        temp_scope=temp_scope, name="metaclass"
    )
    tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared")

    class_creation_function = ExpressionClassBody(
        provider=provider, name=node.name, doc=class_doc, source_ref=source_ref
    )

    class_variable = class_creation_function.getVariableForAssignment("__class__")

    class_variable_ref = ExpressionVariableRef(
        variable=class_variable, source_ref=source_ref
    )

    parent_module = provider.getParentModule()

    code_object = CodeObjectSpec(
        co_name=node.name,
        co_kind="Class",
        co_varnames=(),
        co_argcount=0,
        co_posonlyargcount=0,
        co_kwonlyargcount=0,
        co_has_starlist=False,
        co_has_stardict=False,
        co_filename=parent_module.getRunTimeFilename(),
        co_lineno=source_ref.getLineNumber(),
        future_spec=parent_module.getFutureSpec(),
    )

    body = buildFrameNode(
        provider=class_creation_function,
        nodes=class_statement_nodes,
        code_object=code_object,
        source_ref=source_ref,
    )

    source_ref_orig = source_ref

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref

    locals_scope = class_creation_function.getFunctionLocalsScope()

    statements = [
        StatementSetLocals(
            locals_scope=locals_scope,
            new_locals=ExpressionTempVariableRef(
                variable=tmp_prepared, source_ref=source_ref
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariableName(
            provider=class_creation_function,
            variable_name="__module__",
            source=ExpressionModuleAttributeNameRef(
                variable=provider.getParentModule().getVariableForReference("__name__"),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariableName(
                provider=class_creation_function,
                variable_name="__doc__",
                source=makeConstantRefNode(
                    constant=class_doc, source_ref=source_ref, user_provided=True
                ),
                source_ref=source_ref,
            )
        )

    # The "__qualname__" attribute is new in Python 3.3.
    if python_version >= 300:
        qualname = class_creation_function.getFunctionQualname()

        if python_version < 340:
            qualname_ref = makeConstantRefNode(
                constant=qualname, source_ref=source_ref, user_provided=True
            )
        else:
            qualname_ref = ExpressionFunctionQualnameRef(
                function_body=class_creation_function, source_ref=source_ref
            )

        statements.append(
            StatementLocalsDictOperationSet(
                locals_scope=locals_scope,
                variable_name="__qualname__",
                value=qualname_ref,
                source_ref=source_ref,
            )
        )

        if python_version >= 340:
            qualname_assign = statements[-1]

    if python_version >= 360 and class_creation_function.needsAnnotationsDictionary():
        statements.append(
            StatementLocalsDictOperationSet(
                locals_scope=locals_scope,
                variable_name="__annotations__",
                value=makeConstantRefNode(
                    constant={}, source_ref=source_ref, user_provided=True
                ),
                source_ref=source_ref,
            )
        )

    statements.append(body)

    if node.bases:
        tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases")

        if python_version >= 370:
            tmp_bases_orig = provider.allocateTempVariable(
                temp_scope=temp_scope, name="bases_orig"
            )

        def makeBasesRef():
            return ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref)

    else:

        def makeBasesRef():
            return makeConstantRefNode(constant=(), source_ref=source_ref)

    if python_version >= 370 and node.bases:
        statements.append(
            makeStatementConditional(
                condition=makeComparisonExpression(
                    comparator="NotEq",
                    left=ExpressionTempVariableRef(
                        variable=tmp_bases, source_ref=source_ref
                    ),
                    right=ExpressionTempVariableRef(
                        variable=tmp_bases_orig, source_ref=source_ref
                    ),
                    source_ref=source_ref,
                ),
                yes_branch=StatementLocalsDictOperationSet(
                    locals_scope=locals_scope,
                    variable_name="__orig_bases__",
                    value=ExpressionTempVariableRef(
                        variable=tmp_bases_orig, source_ref=source_ref
                    ),
                    source_ref=source_ref,
                ),
                no_branch=None,
                source_ref=source_ref,
            )
        )

    statements += (
        StatementAssignmentVariable(
            variable=class_variable,
            source=makeExpressionCall(
                called=ExpressionTempVariableRef(
                    variable=tmp_metaclass, source_ref=source_ref
                ),
                args=makeSequenceCreationOrConstant(
                    sequence_kind="tuple",
                    elements=(
                        makeConstantRefNode(
                            constant=node.name,
                            source_ref=source_ref,
                            user_provided=True,
                        ),
                        makeBasesRef(),
                        ExpressionBuiltinLocalsRef(
                            locals_scope=locals_scope, source_ref=source_ref
                        ),
                    ),
                    source_ref=source_ref,
                ),
                kw=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict, source_ref=source_ref
                ),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementReturn(expression=class_variable_ref, source_ref=source_ref),
    )

    body = makeStatementsSequenceFromStatement(
        statement=makeTryFinallyStatement(
            provider=class_creation_function,
            tried=mergeStatements(statements, True),
            final=StatementReleaseLocals(
                locals_scope=locals_scope, source_ref=source_ref
            ),
            source_ref=source_ref,
        )
    )

    # The class body is basically a function that implicitly, at the end
    # returns its locals and cannot have other return statements contained.
    class_creation_function.setBody(body)

    # The class body is basically a function that implicitly, at the end
    # returns its created class and cannot have other return statements
    # contained.

    decorated_body = class_creation_function

    for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref):
        decorated_body = makeExpressionCall(
            called=decorator,
            args=ExpressionMakeTuple(elements=(decorated_body,), source_ref=source_ref),
            kw=None,
            source_ref=decorator.getSourceReference(),
        )

    if node.keywords and node.keywords[-1].arg is None:
        keywords = node.keywords[:-1]
    else:
        keywords = node.keywords

    statements = []

    if node.bases:
        statements.append(
            StatementAssignmentVariable(
                variable=tmp_bases if python_version < 370 else tmp_bases_orig,
                source=buildTupleCreationNode(
                    provider=provider, elements=node.bases, source_ref=source_ref
                ),
                source_ref=source_ref,
            )
        )

        if python_version >= 370:
            bases_conversion = ExpressionFunctionCall(
                function=ExpressionFunctionCreation(
                    function_ref=ExpressionFunctionRef(
                        function_body=getClassBasesMroConversionHelper(),
                        source_ref=source_ref,
                    ),
                    defaults=(),
                    kw_defaults=None,
                    annotations=None,
                    source_ref=source_ref,
                ),
                values=(
                    ExpressionTempVariableRef(
                        variable=tmp_bases_orig, source_ref=source_ref
                    ),
                ),
                source_ref=source_ref,
            )

            statements.append(
                StatementAssignmentVariable(
                    variable=tmp_bases, source=bases_conversion, source_ref=source_ref
                )
            )

    statements.append(
        StatementAssignmentVariable(
            variable=tmp_class_decl_dict,
            source=makeDictCreationOrConstant2(
                keys=[keyword.arg for keyword in keywords],
                values=[
                    buildNode(provider, keyword.value, source_ref)
                    for keyword in keywords
                ],
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )
    )

    if node.keywords and node.keywords[-1].arg is None:
        statements.append(
            StatementDictOperationUpdate(
                dict_arg=ExpressionVariableRef(
                    variable=tmp_class_decl_dict, source_ref=source_ref
                ),
                value=buildNode(provider, node.keywords[-1].value, source_ref),
                source_ref=source_ref,
            )
        )

    # Check if there are bases, and if there are, go with the type of the
    # first base class as a metaclass unless it was specified in the class
    # decl dict of course.
    if node.bases:
        unspecified_metaclass_expression = ExpressionBuiltinType1(
            value=ExpressionSubscriptLookup(
                expression=ExpressionTempVariableRef(
                    variable=tmp_bases, source_ref=source_ref
                ),
                subscript=makeConstantRefNode(
                    constant=0, source_ref=source_ref, user_provided=True
                ),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )

        # Might become empty behind our back during conversion, therefore make the
        # check at run time for 3.7 or higher.
        if python_version >= 370:
            unspecified_metaclass_expression = ExpressionConditional(
                condition=ExpressionTempVariableRef(
                    variable=tmp_bases, source_ref=source_ref
                ),
                expression_yes=unspecified_metaclass_expression,
                expression_no=makeExpressionBuiltinRef(
                    builtin_name="type", source_ref=source_ref
                ),
                source_ref=source_ref,
            )
    else:
        unspecified_metaclass_expression = makeExpressionBuiltinRef(
            builtin_name="type", source_ref=source_ref
        )

    call_prepare = StatementAssignmentVariable(
        variable=tmp_prepared,
        source=makeExpressionCall(
            called=ExpressionAttributeLookup(
                expression=ExpressionTempVariableRef(
                    variable=tmp_metaclass, source_ref=source_ref
                ),
                attribute_name="__prepare__",
                source_ref=source_ref,
            ),
            args=ExpressionMakeTuple(
                elements=(
                    makeConstantRefNode(
                        constant=node.name, source_ref=source_ref, user_provided=True
                    ),
                    makeBasesRef(),
                ),
                source_ref=source_ref,
            ),
            kw=ExpressionTempVariableRef(
                variable=tmp_class_decl_dict, source_ref=source_ref
            ),
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    if python_version >= 364:
        call_prepare = makeStatementsSequenceFromStatements(
            call_prepare,
            makeStatementConditional(
                condition=ExpressionAttributeCheck(
                    object_arg=ExpressionTempVariableRef(
                        variable=tmp_prepared, source_ref=source_ref
                    ),
                    attribute_name="__getitem__",
                    source_ref=source_ref,
                ),
                yes_branch=None,
                no_branch=makeRaiseExceptionExpressionFromTemplate(
                    exception_type="TypeError",
                    template="%s.__prepare__() must return a mapping, not %s",
                    template_args=(
                        ExpressionBuiltinGetattr(
                            object_arg=ExpressionTempVariableRef(
                                variable=tmp_metaclass, source_ref=source_ref
                            ),
                            name=makeConstantRefNode(
                                constant="__name__", source_ref=source_ref
                            ),
                            default=makeConstantRefNode(
                                constant="<metaclass>", source_ref=source_ref
                            ),
                            source_ref=source_ref,
                        ),
                        ExpressionAttributeLookup(
                            expression=ExpressionBuiltinType1(
                                value=ExpressionTempVariableRef(
                                    variable=tmp_prepared, source_ref=source_ref
                                ),
                                source_ref=source_ref,
                            ),
                            attribute_name="__name__",
                            source_ref=source_ref,
                        ),
                    ),
                    source_ref=source_ref,
                ).asStatement(),
                source_ref=source_ref,
            ),
        )

    statements += (
        StatementAssignmentVariable(
            variable=tmp_metaclass,
            source=ExpressionSelectMetaclass(
                metaclass=ExpressionConditional(
                    condition=ExpressionDictOperationIn(
                        key=makeConstantRefNode(
                            constant="metaclass",
                            source_ref=source_ref,
                            user_provided=True,
                        ),
                        dict_arg=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict, source_ref=source_ref
                        ),
                        source_ref=source_ref,
                    ),
                    expression_yes=ExpressionDictOperationGet(
                        dict_arg=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict, source_ref=source_ref
                        ),
                        key=makeConstantRefNode(
                            constant="metaclass",
                            source_ref=source_ref,
                            user_provided=True,
                        ),
                        source_ref=source_ref,
                    ),
                    expression_no=unspecified_metaclass_expression,
                    source_ref=source_ref,
                ),
                bases=makeBasesRef(),
                source_ref=source_ref,
            ),
            source_ref=source_ref_orig,
        ),
        makeStatementConditional(
            condition=ExpressionDictOperationIn(
                key=makeConstantRefNode(
                    constant="metaclass", source_ref=source_ref, user_provided=True
                ),
                dict_arg=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict, source_ref=source_ref
                ),
                source_ref=source_ref,
            ),
            no_branch=None,
            yes_branch=StatementDictOperationRemove(
                dict_arg=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict, source_ref=source_ref
                ),
                key=makeConstantRefNode(
                    constant="metaclass", source_ref=source_ref, user_provided=True
                ),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionAttributeCheck(
                object_arg=ExpressionTempVariableRef(
                    variable=tmp_metaclass, source_ref=source_ref
                ),
                attribute_name="__prepare__",
                source_ref=source_ref,
            ),
            yes_branch=call_prepare,
            no_branch=StatementAssignmentVariable(
                variable=tmp_prepared,
                source=makeConstantRefNode(
                    constant={}, source_ref=source_ref, user_provided=True
                ),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariableName(
            provider=provider,
            variable_name=mangleName(node.name, provider),
            source=decorated_body,
            source_ref=source_ref,
        ),
    )

    if python_version >= 340:
        class_creation_function.qualname_setup = node.name, qualname_assign

    final = [tmp_class_decl_dict, tmp_metaclass, tmp_prepared]
    if node.bases:
        final.insert(0, tmp_bases)
        if python_version >= 370:
            final.insert(0, tmp_bases_orig)

    return makeTryFinallyStatement(
        provider=provider,
        tried=statements,
        final=tuple(
            StatementReleaseVariable(variable=variable, source_ref=source_ref)
            for variable in final
        ),
        source_ref=source_ref,
    )
Ejemplo n.º 7
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 buildCallNode(provider, node, source_ref):
    called = buildNode(provider, node.func, source_ref)

    if python_version >= 0x350:
        list_star_arg = None
        dict_star_arg = None

    positional_args = []

    # For Python3.5 compatibility, the error handling with star argument last
    # is the old one, only with a starred argument before that, things use the
    # new unpacking code.
    for node_arg in node.args[:-1]:
        if getKind(node_arg) == "Starred":
            assert python_version >= 0x350
            list_star_arg = buildListUnpacking(provider, node.args, source_ref)
            positional_args = []
            break
    else:
        if node.args and getKind(node.args[-1]) == "Starred":
            assert python_version >= 0x350

            list_star_arg = buildNode(provider, node.args[-1].value, source_ref)
            positional_args = buildNodeList(provider, node.args[:-1], source_ref)
        else:
            positional_args = buildNodeList(provider, node.args, source_ref)

    # Only the values of keyword pairs have a real source ref, and those only
    # really matter, so that makes sense.
    keys = []
    values = []

    for keyword in node.keywords[:-1]:
        if keyword.arg is None:
            assert python_version >= 0x350

            outline_body = ExpressionOutlineBody(
                provider=provider, name="dict_unpacking_call", source_ref=source_ref
            )

            tmp_called = outline_body.allocateTempVariable(
                temp_scope=None, name="called"
            )

            helper_args = [
                ExpressionTempVariableRef(variable=tmp_called, source_ref=source_ref),
                makeExpressionMakeTuple(
                    elements=buildDictionaryUnpackingArgs(
                        provider=provider,
                        keys=(keyword.arg for keyword in node.keywords),
                        values=(keyword.value for keyword in node.keywords),
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
            ]

            dict_star_arg = ExpressionFunctionCall(
                function=ExpressionFunctionCreation(
                    function_ref=ExpressionFunctionRef(
                        function_body=getFunctionCallHelperDictionaryUnpacking(),
                        source_ref=source_ref,
                    ),
                    defaults=(),
                    kw_defaults=None,
                    annotations=None,
                    source_ref=source_ref,
                ),
                values=helper_args,
                source_ref=source_ref,
            )

            outline_body.setChild(
                "body",
                makeStatementsSequenceFromStatements(
                    StatementAssignmentVariable(
                        variable=tmp_called, source=called, source_ref=source_ref
                    ),
                    StatementReturn(
                        expression=_makeCallNode(
                            called=ExpressionTempVariableRef(
                                variable=tmp_called, source_ref=source_ref
                            ),
                            positional_args=positional_args,
                            keys=keys,
                            values=values,
                            list_star_arg=list_star_arg,
                            dict_star_arg=dict_star_arg,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                ),
            )

            return outline_body

    # For Python3.5 compatibility, the error handling with star argument last
    # is the old one, only with a starred argument before that, things use the
    # new unpacking code.

    if node.keywords and node.keywords[-1].arg is None:
        assert python_version >= 0x350

        dict_star_arg = buildNode(provider, node.keywords[-1].value, source_ref)
        keywords = node.keywords[:-1]
    else:
        keywords = node.keywords

    for keyword in keywords:
        keys.append(
            makeConstantRefNode(
                constant=keyword.arg, source_ref=source_ref, user_provided=True
            )
        )
        values.append(buildNode(provider, keyword.value, source_ref))

    if python_version < 0x350:
        list_star_arg = buildNode(provider, node.starargs, source_ref, True)
        dict_star_arg = buildNode(provider, node.kwargs, source_ref, True)

    return _makeCallNode(
        called=called,
        positional_args=positional_args,
        keys=keys,
        values=values,
        list_star_arg=list_star_arg,
        dict_star_arg=dict_star_arg,
        source_ref=source_ref,
    )
Ejemplo n.º 9
0
def buildExecNode(provider, node, source_ref):
    # "exec" statements, should only occur with Python2.

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

    orig_globals = exec_globals

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

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

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

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

        if orig_globals is None:
            provider.markAsUnqualifiedExecContaining(source_ref)

    temp_scope = provider.allocateTempScope("exec")

    globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals(
        provider=provider,
        globals_node=buildNode(provider, exec_globals, source_ref, True),
        locals_node=buildNode(provider, exec_locals, source_ref, True),
        temp_scope=temp_scope,
        source_ref=source_ref)

    source_code = buildNode(provider, body, source_ref)

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

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

    statements = (StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(
            variable=source_variable.makeReference(provider),
            source_ref=source_ref),
        source=source_code,
        source_ref=source_ref,
    ),
                  StatementConditional(condition=ExpressionBuiltinIsinstance(
                      cls=ExpressionBuiltinAnonymousRef(
                          builtin_name="file",
                          source_ref=source_ref,
                      ),
                      instance=ExpressionTempVariableRef(
                          variable=source_variable.makeReference(provider),
                          source_ref=source_ref),
                      source_ref=source_ref),
                                       yes_branch=StatementsSequence(
                                           statements=file_fixup,
                                           source_ref=source_ref),
                                       no_branch=None,
                                       source_ref=source_ref),
                  StatementExec(source_code=ExpressionTempVariableRef(
                      variable=source_variable.makeReference(provider),
                      source_ref=source_ref),
                                globals_arg=globals_ref,
                                locals_arg=locals_ref,
                                source_ref=source_ref))

    tried.setChild("statements", tried.getStatements() + statements)

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

    return StatementTryFinally(tried=tried,
                               final=final,
                               public_exc=False,
                               source_ref=source_ref)
Ejemplo n.º 10
0
def _buildContractionBodyNode(provider, node, emit_class, start_value,
                              container_tmp, iter_tmp, temp_scope,
                              assign_provider, function_body, source_ref):

    # This uses lots of variables and branches. There is no good way
    # around that, and we deal with many cases, due to having generator
    # expressions sharing this code, pylint: disable=too-many-branches,too-many-locals

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.

    tmp_variables = []
    if emit_class is not ExpressionYield:
        tmp_variables.append(iter_tmp)

    if container_tmp is not None:
        tmp_variables.append(container_tmp)

    # First assign the iterator if we are an outline.
    if assign_provider:

        statements = [
            StatementAssignmentVariable(variable=iter_tmp,
                                        source=_makeIteratorCreation(
                                            provider, node.generators[0],
                                            source_ref),
                                        source_ref=source_ref.atInternal())
        ]
    else:
        statements = []

    if start_value is not None:
        statements.append(
            StatementAssignmentVariable(variable=container_tmp,
                                        source=makeConstantRefNode(
                                            constant=start_value,
                                            source_ref=source_ref),
                                        source_ref=source_ref.atInternal()))

    if hasattr(node, "elt"):
        if start_value is not None:
            current_body = emit_class(
                ExpressionTempVariableRef(variable=container_tmp,
                                          source_ref=source_ref),
                buildNode(provider=function_body
                          if not assign_provider else provider,
                          node=node.elt,
                          source_ref=source_ref),
                source_ref=source_ref)
        else:
            assert emit_class is ExpressionYield

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

        current_body = StatementDictOperationSet(
            dict_arg=ExpressionTempVariableRef(variable=container_tmp,
                                               source_ref=source_ref),
            key=buildNode(
                provider=function_body if not assign_provider else provider,
                node=node.key,
                source_ref=source_ref,
            ),
            value=buildNode(
                provider=function_body if not assign_provider else provider,
                node=node.value,
                source_ref=source_ref,
            ),
            source_ref=source_ref)

    if current_body.isExpression():
        current_body = StatementExpressionOnly(expression=current_body,
                                               source_ref=source_ref)

    for count, qual in enumerate(reversed(node.generators)):
        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope=temp_scope, name="iter_value_%d" % count)

        tmp_variables.append(tmp_value_variable)

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.

        if qual is node.generators[0]:
            iterator_ref = makeVariableRefNode(variable=iter_tmp,
                                               source_ref=source_ref)

            tmp_iter_variable = None

            nested_statements = []
        else:
            # First create the iterator and store it, next should be loop body
            value_iterator = _makeIteratorCreation(
                provider=provider if assign_provider else function_body,
                qual=qual,
                source_ref=source_ref)

            tmp_iter_variable = function_body.allocateTempVariable(
                temp_scope=temp_scope, name="contraction_iter_%d" % count)

            tmp_variables.append(tmp_iter_variable)

            nested_statements = [
                StatementAssignmentVariable(variable=tmp_iter_variable,
                                            source=value_iterator,
                                            source_ref=source_ref)
            ]

            iterator_ref = ExpressionTempVariableRef(
                variable=tmp_iter_variable, source_ref=source_ref)

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried=StatementAssignmentVariable(
                    variable=tmp_value_variable,
                    source=_makeIteratorNext(iterator_ref=iterator_ref,
                                             qual=qual,
                                             source_ref=source_ref),
                    source_ref=source_ref),
                exception_name=_getStopIterationName(qual),
                handler_body=StatementLoopBreak(source_ref=source_ref),
                source_ref=source_ref),
            buildAssignmentStatements(
                provider=provider if assign_provider else function_body,
                temp_provider=function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(variable=tmp_value_variable,
                                                 source_ref=source_ref),
                source_ref=source_ref)
        ]

        conditions = buildNodeList(
            provider=provider if assign_provider else function_body,
            nodes=qual.ifs,
            source_ref=source_ref)

        if len(conditions) >= 1:
            loop_statements.append(
                makeStatementConditional(condition=buildAndNode(
                    values=conditions, source_ref=source_ref),
                                         yes_branch=current_body,
                                         no_branch=None,
                                         source_ref=source_ref))
        else:
            loop_statements.append(current_body)

        nested_statements.append(
            StatementLoop(body=StatementsSequence(
                statements=mergeStatements(loop_statements),
                source_ref=source_ref),
                          source_ref=source_ref))

        if tmp_iter_variable is not None:
            nested_statements.append(
                StatementReleaseVariable(variable=tmp_iter_variable,
                                         source_ref=source_ref))

        current_body = StatementsSequence(statements=mergeStatements(
            nested_statements, False),
                                          source_ref=source_ref)

    statements.append(current_body)
    statements = mergeStatements(statements)

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

    return statements, release_statements
Ejemplo n.º 11
0
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          source_ref):
    # The contraction nodes are reformulated to function bodies, with loops as
    # described in the developer manual. They use a lot of temporary names,
    # nested blocks, etc. and so a lot of variable names.

    function_body = ExpressionOutlineFunction(provider=provider,
                                              name=intern(name[1:-1]),
                                              source_ref=source_ref)

    iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0")

    container_tmp = function_body.allocateTempVariable(temp_scope=None,
                                                       name="contraction")

    statements, release_statements = _buildContractionBodyNode(
        function_body=function_body,
        provider=provider,
        node=node,
        emit_class=emit_class,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        assign_provider=False,
        source_ref=source_ref,
    )

    assign_iter_statement = StatementAssignmentVariable(
        source=_makeIteratorCreation(provider, node.generators[0], source_ref),
        variable=iter_tmp,
        source_ref=source_ref)

    statements.append(
        StatementReturn(expression=ExpressionTempVariableRef(
            variable=container_tmp, source_ref=source_ref),
                        source_ref=source_ref))

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    if python_version < 300:
        body = makeStatementsSequenceFromStatements(assign_iter_statement,
                                                    statements)
    else:
        parent_module = provider.getParentModule()

        code_object = CodeObjectSpec(
            co_name=name,
            co_kind="Function",
            co_varnames=(),
            co_argcount=1,
            co_kwonlyargcount=0,
            co_has_starlist=False,
            co_has_stardict=False,
            co_filename=parent_module.getRunTimeFilename(),
            co_lineno=source_ref.getLineNumber(),
            future_spec=parent_module.getFutureSpec())

        body = makeStatementsSequenceFromStatements(
            assign_iter_statement,
            StatementsFrameFunction(statements=mergeStatements(
                statements, False),
                                    code_object=code_object,
                                    source_ref=source_ref))

    function_body.setBody(body)

    return function_body
Ejemplo n.º 12
0
def buildGeneratorExpressionNode(provider, node, source_ref):
    # Generator expressions are dealt with by general code.

    assert getKind(node) == "GeneratorExp"

    function_body = ExpressionOutlineBody(provider=provider,
                                          name="genexpr",
                                          source_ref=source_ref)

    iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0")

    parent_module = provider.getParentModule()

    code_object = CodeObjectSpec(
        co_name="<genexpr>",
        co_kind="Generator",
        co_varnames=(".0", ),
        co_argcount=1,
        co_kwonlyargcount=0,
        co_has_starlist=False,
        co_has_stardict=False,
        co_filename=parent_module.getRunTimeFilename(),
        co_lineno=source_ref.getLineNumber(),
        future_spec=parent_module.getFutureSpec())

    if python_version < 370:
        is_async = any(
            getattr(qual, "is_async", 0) for qual in node.generators)
    else:
        is_async = detectFunctionBodyKind(nodes=[node])[0] in ("Asyncgen",
                                                               "Coroutine")

    if is_async:
        code_body = ExpressionAsyncgenObjectBody(provider=provider,
                                                 name="<genexpr>",
                                                 code_object=code_object,
                                                 flags=set(),
                                                 source_ref=source_ref)

        maker_class = ExpressionMakeAsyncgenObject
    else:
        code_body = ExpressionGeneratorObjectBody(provider=provider,
                                                  name="<genexpr>",
                                                  code_object=code_object,
                                                  flags=set(),
                                                  source_ref=source_ref)

        maker_class = ExpressionMakeGeneratorObject

    function_body.setBody(
        makeStatementsSequenceFromStatements(
            StatementAssignmentVariable(variable=iter_tmp,
                                        source=_makeIteratorCreation(
                                            provider, node.generators[0],
                                            source_ref),
                                        source_ref=source_ref),
            makeTryFinallyStatement(
                provider=function_body,
                tried=StatementReturn(expression=maker_class(
                    ExpressionFunctionRef(function_body=code_body,
                                          source_ref=source_ref),
                    source_ref=source_ref),
                                      source_ref=source_ref),
                final=StatementReleaseVariable(variable=iter_tmp,
                                               source_ref=source_ref),
                source_ref=source_ref)))

    statements, release_statements = _buildContractionBodyNode(
        function_body=code_body,
        provider=provider,
        node=node,
        emit_class=ExpressionYield,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=None,
        container_tmp=None,
        assign_provider=False,
        source_ref=source_ref,
    )

    if is_async:
        statements.append(StatementGeneratorReturnNone(source_ref=source_ref))

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    code_body.setBody(
        makeStatementsSequenceFromStatement(statement=StatementsFrameGenerator(
            statements=mergeStatements(statements, False),
            code_object=code_object,
            source_ref=source_ref)))

    return function_body
def buildLambdaNode(provider, node, source_ref):
    # Many details to deal with, pylint: disable=too-many-locals

    assert getKind(node) == "Lambda"

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

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

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

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

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

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

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

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

    if function_kind == "Generator":
        frame_class = StatementsFrameGenerator
    else:
        frame_class = StatementsFrameFunction

    body = frame_class(
        statements=mergeStatements((body, )),
        code_object=code_object,
        source_ref=body.getSourceReference(),
    )

    body = makeStatementsSequenceFromStatement(statement=body)

    code_body.setBody(body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    return ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=outer_body,
                                           source_ref=source_ref),
        defaults=defaults,
        kw_defaults=kw_defaults,
        annotations=annotations,
        source_ref=source_ref,
    )
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
    def onLeaveNode(self, node):
        if node.isStatementAssignmentVariableName():
            variable_name = node.getVariableName()
            provider = node.provider

            # Classes always assign to locals dictionary except for closure
            # variables taken.
            if self._shouldUseLocalsDict(provider, variable_name):
                if node.subnode_source.isExpressionOperationInplace():
                    temp_scope = provider.allocateTempScope("class_inplace")

                    tmp_variable = provider.allocateTempVariable(
                        temp_scope=temp_scope, name="value"
                    )

                    statements = mergeStatements(
                        statements=(
                            StatementAssignmentVariable(
                                variable=tmp_variable,
                                source=node.subnode_source.getLeft(),
                                source_ref=node.source_ref,
                            ),
                            makeTryFinallyStatement(
                                provider=provider,
                                tried=(
                                    StatementAssignmentVariable(
                                        variable=tmp_variable,
                                        source=makeExpressionOperationBinaryInplace(
                                            left=ExpressionTempVariableRef(
                                                variable=tmp_variable,
                                                source_ref=node.source_ref,
                                            ),
                                            right=node.subnode_source.getRight(),
                                            operator=node.subnode_source.getOperator(),
                                            source_ref=node.source_ref,
                                        ),
                                        source_ref=node.source_ref,
                                    ),
                                    StatementLocalsDictOperationSet(
                                        locals_scope=provider.getLocalsScope(),
                                        variable_name=variable_name,
                                        value=ExpressionTempVariableRef(
                                            variable=tmp_variable,
                                            source_ref=node.source_ref,
                                        ),
                                        source_ref=node.source_ref,
                                    ),
                                ),
                                final=StatementReleaseVariable(
                                    variable=tmp_variable, source_ref=node.source_ref
                                ),
                                source_ref=node.source_ref,
                            ),
                        )
                    )

                    node.parent.replaceStatement(node, statements)

                else:
                    new_node = StatementLocalsDictOperationSet(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=variable_name,
                        value=node.subnode_source,
                        source_ref=node.source_ref,
                    )

                    node.parent.replaceChild(node, new_node)
            else:
                variable = provider.getVariableForAssignment(
                    variable_name=variable_name
                )

                new_node = StatementAssignmentVariable(
                    variable=variable,
                    source=node.subnode_source,
                    source_ref=node.source_ref,
                )

                variable.addVariableUser(provider)

                node.parent.replaceChild(node, new_node)

            del node.parent
            del node.provider
        elif node.isStatementDelVariableName():
            variable_name = node.getVariableName()

            provider = node.provider

            if self._shouldUseLocalsDict(provider, variable_name):
                # Classes always assign to locals dictionary except for closure
                # variables taken.
                new_node = StatementLocalsDictOperationDel(
                    locals_scope=provider.getLocalsScope(),
                    variable_name=variable_name,
                    tolerant=node.tolerant,
                    source_ref=node.source_ref,
                )
            else:
                variable = provider.getVariableForAssignment(
                    variable_name=variable_name
                )

                new_node = StatementDelVariable(
                    variable=variable,
                    tolerant=node.tolerant,
                    source_ref=node.source_ref,
                )

                variable.addVariableUser(provider)

            parent = node.parent
            node.finalize()

            parent.replaceChild(node, new_node)
Ejemplo n.º 16
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))
Ejemplo n.º 17
0
def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref):
    # Many details, pylint: disable=too-many-locals
    with_source = buildNode(provider, context_expr, source_ref)

    if python_version < 380 and 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"
    )

    # 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:
        deepest = body

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

        if python_version < 370:
            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 < 270:
        attribute_lookup_class = ExpressionAttributeLookup
    else:
        attribute_lookup_class = ExpressionAttributeLookupSpecial

    enter_value = ExpressionCallEmpty(
        called=attribute_lookup_class(
            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=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 = ExpressionYieldFromWaitable(
            expression=ExpressionAsyncWaitEnter(
                expression=enter_value, source_ref=source_ref
            ),
            source_ref=source_ref,
        )
        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,
        )

    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(
                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,
        ),
        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,
                        ),
                        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 >= 270,
                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,
    )
Ejemplo n.º 18
0
def _buildClassNode2(provider, node, source_ref):
    class_statements, class_doc = extractDocFromBody(node)

    # This function is the Python2 special case with special re-formulation as
    # according to developer manual.

    function_body = ExpressionFunctionBody(
        provider   = provider,
        is_class   = True,
        parameters = make_class_parameters,
        name       = node.name,
        doc        = class_doc,
        source_ref = source_ref
    )

    body = buildStatementsNode(
        provider   = function_body,
        nodes      = class_statements,
        frame      = True,
        source_ref = source_ref
    )

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref.atInternal()

    # The class body is basically a function that implicitly, at the end
    # returns its locals and cannot have other return statements contained, and
    # starts out with a variables "__module__" and potentially "__doc__" set.
    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__module__",
                source_ref    = source_ref
            ),
            source       = ExpressionConstantRef(
                constant      = provider.getParentModule().getFullName(),
                source_ref    = source_ref,
                user_provided = True
            ),
            source_ref   = source_ref.atInternal()
        )
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = class_doc,
                    source_ref    = source_ref,
                    user_provided = True
                ),
                source_ref   = source_ref.atInternal()
            )
        )

    statements += [
        body,
        StatementReturn(
            expression = ExpressionBuiltinLocals(
                source_ref = source_ref
            ),
            source_ref = source_ref.atInternal()
        )
    ]

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

    # The class body is basically a function that implicitly, at the end
    # returns its locals and cannot have other return statements contained.

    function_body.setBody(body)

    temp_scope = provider.allocateTempScope("class_creation")

    tmp_bases = provider.allocateTempVariable(temp_scope, "bases")
    tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict")
    tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass")
    tmp_class = provider.allocateTempVariable(temp_scope, "class")

    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                elements      = buildNodeList(
                    provider, node.bases, source_ref
                ),
                source_ref    = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict,
                source_ref = source_ref
            ),
            source       =   ExpressionFunctionCall(
                function   = ExpressionFunctionCreation(
                    function_ref = ExpressionFunctionRef(
                        function_body = function_body,
                        source_ref    = source_ref
                    ),
                    defaults     = (),
                    kw_defaults  = None,
                    annotations  = None,
                    source_ref   = source_ref
                ),
                values     = (),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition      =  ExpressionComparison(
                    comparator = "In",
                    left       = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    right      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_expression = ExpressionDictOperationGet(
                    dicte      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict,
                        source_ref = source_ref
                    ),
                    key        = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression  = ExpressionSelectMetaclass(
                    metaclass  = None,
                    bases      = ExpressionTempVariableRef(
                        variable   = tmp_bases,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref     = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class,
                source_ref = source_ref
            ),
            source       = ExpressionCallNoKeywords(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass,
                    source_ref = source_ref
                ),
                args       = ExpressionMakeTuple(
                    elements   = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_class_dict,
                            source_ref = source_ref
                        )
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
    ]

    for decorator in buildNodeList(
            provider,
            reversed(node.decorator_list),
            source_ref
        ):
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_class,
                    source_ref = source_ref
                ),
                source       = ExpressionCallNoKeywords(
                    called     = decorator,
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionTempVariableRef(
                                variable   = tmp_class,
                                source_ref = source_ref
                            ),
                        ),
                        source_ref = source_ref
                    ),
                    source_ref = decorator.getSourceReference()
                ),
                source_ref   = decorator.getSourceReference()
            )
        )

    statements.append(
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = node.name,
                source_ref    = source_ref
            ),
            source       = ExpressionTempVariableRef(
                variable   = tmp_class,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        )
    )

    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
Ejemplo n.º 19
0
def getClassBasesMroConversionHelper():
    helper_name = "_mro_entries_conversion"

    result = makeInternalHelperFunctionBody(
        name=helper_name,
        parameters=ParameterSpec(
            ps_name=helper_name,
            ps_normal_args=("bases",),
            ps_pos_only_args=(),
            ps_list_star_arg=None,
            ps_dict_star_arg=None,
            ps_default_count=0,
            ps_kw_only_args=(),
        ),
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "list")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "base")

    args_variable = result.getVariableForAssignment(variable_name="bases")

    non_type_case = makeStatementConditional(
        condition=ExpressionAttributeCheck(
            object_arg=ExpressionTempVariableRef(
                variable=tmp_item_variable, source_ref=internal_source_ref
            ),
            attribute_name="__mro_entries__",
            source_ref=internal_source_ref,
        ),
        yes_branch=StatementExpressionOnly(
            expression=ExpressionListOperationExtend(
                list_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable, source_ref=internal_source_ref
                ),
                value=makeExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_item_variable, source_ref=internal_source_ref
                        ),
                        attribute_name="__mro_entries__",
                        source_ref=internal_source_ref,
                    ),
                    args=ExpressionMakeTuple(
                        elements=(
                            ExpressionVariableRef(
                                variable=args_variable, source_ref=internal_source_ref
                            ),
                        ),
                        source_ref=internal_source_ref,
                    ),
                    kw=None,
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        no_branch=StatementListOperationAppend(
            list_arg=ExpressionTempVariableRef(
                variable=tmp_result_variable, source_ref=internal_source_ref
            ),
            value=ExpressionTempVariableRef(
                variable=tmp_item_variable, source_ref=internal_source_ref
            ),
            source_ref=internal_source_ref,
        ),
        source_ref=internal_source_ref,
    )

    type_case = StatementListOperationAppend(
        list_arg=ExpressionTempVariableRef(
            variable=tmp_result_variable, source_ref=internal_source_ref
        ),
        value=ExpressionTempVariableRef(
            variable=tmp_item_variable, source_ref=internal_source_ref
        ),
        source_ref=internal_source_ref,
    )

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable=tmp_item_variable,
                source=ExpressionBuiltinNext1(
                    value=ExpressionTempVariableRef(
                        variable=tmp_iter_variable, source_ref=internal_source_ref
                    ),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionBuiltinIsinstance(
                instance=ExpressionTempVariableRef(
                    variable=tmp_item_variable, source_ref=internal_source_ref
                ),
                classes=makeConstantRefNode(
                    constant=type, source_ref=internal_source_ref
                ),
                source_ref=internal_source_ref,
            ),
            yes_branch=type_case,
            no_branch=non_type_case,
            source_ref=internal_source_ref,
        ),
    )

    final = (
        StatementReleaseVariable(
            variable=args_variable, source_ref=internal_source_ref
        ),
        StatementReleaseVariable(
            variable=tmp_result_variable, source_ref=internal_source_ref
        ),
        StatementReleaseVariable(
            variable=tmp_iter_variable, source_ref=internal_source_ref
        ),
        StatementReleaseVariable(
            variable=tmp_item_variable, source_ref=internal_source_ref
        ),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_iter_variable,
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(
                    variable=args_variable, source_ref=internal_source_ref
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_result_variable,
            source=makeConstantRefNode(constant=[], source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionBuiltinTuple(
                value=ExpressionTempVariableRef(
                    variable=tmp_result_variable, source_ref=internal_source_ref
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )
        )
    )

    return result
Ejemplo n.º 20
0
def _buildClassNode3(provider, node, source_ref):
    # Many variables, due to the huge re-formulation that is going on here,
    # which just has the complexity, pylint: disable=R0914

    # This function is the Python3 special case with special re-formulation as
    # according to developer manual.
    class_statements, class_doc = extractDocFromBody(node)

    # We need a scope for the temporary variables, and they might be closured.
    temp_scope = provider.allocateTempScope(
        name          = "class_creation",
        allow_closure = True
    )

    tmp_bases = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "bases"
    )
    tmp_class_decl_dict = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "class_decl_dict"
    )
    tmp_metaclass = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "metaclass"
    )
    tmp_prepared = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "prepared"
    )

    class_creation_function = ExpressionFunctionBody(
        provider   = provider,
        is_class   = True,
        parameters = make_class_parameters,
        name       = node.name,
        doc        = class_doc,
        source_ref = source_ref
    )

    # Hack: This allows some APIs to work although this is not yet officially a
    # child yet.
    class_creation_function.parent = provider

    body = buildStatementsNode(
        provider   = class_creation_function,
        nodes      = class_statements,
        frame      = True,
        source_ref = source_ref
    )

    source_ref_orig = source_ref

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref

    module_variable = class_creation_function.getVariableForAssignment(
        "__module__"
    )

    statements = [
        StatementSetLocals(
            new_locals = ExpressionTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__module__",
                variable      = module_variable,
                source_ref    = source_ref
            ),
            source       = ExpressionConstantRef(
                constant      = provider.getParentModule().getFullName(),
                source_ref    = source_ref,
                user_provided = True
            ),
            source_ref   = source_ref
        )
    ]

    if class_doc is not None:
        doc_variable = class_creation_function.getVariableForAssignment(
            "__doc__"
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    variable      = doc_variable,
                    source_ref    = source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = class_doc,
                    source_ref    = source_ref,
                    user_provided = True
                ),
                source_ref   = source_ref
            )
        )

    # The "__qualname__" attribute is new in Python 3.3.
    if Utils.python_version >= 330:
        qualname = class_creation_function.getFunctionQualname()
        qualname_variable = class_creation_function.getVariableForAssignment(
            "__qualname__"
        )

        if Utils.python_version < 340:
            qualname_ref = ExpressionConstantRef(
                constant      = qualname,
                source_ref    = source_ref,
                user_provided = True
            )
        else:
            qualname_ref = ExpressionFunctionQualnameRef(
                function_body = class_creation_function,
                source_ref    = source_ref,
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__qualname__",
                    variable      = qualname_variable,
                    source_ref    = source_ref
                ),
                source       = qualname_ref,
                source_ref   = source_ref
            )
        )

        if Utils.python_version >= 340:
            qualname_assign = statements[-1]

    if Utils.python_version >= 340 and False: # TODO: Temporarily reverted:
        tmp_class = class_creation_function.allocateTempVariable(
            temp_scope = None,
            name       = "__class__"
        )

        class_target_variable_ref = ExpressionTargetTempVariableRef(
            variable   = tmp_class,
            source_ref = source_ref
        )
        class_variable_ref = ExpressionTempVariableRef(
            variable   = tmp_class,
            source_ref = source_ref
        )
    else:
        class_variable = class_creation_function.getVariableForAssignment(
            "__class__"
        )

        class_target_variable_ref = ExpressionTargetVariableRef(
            variable_name = "__class__",
            variable      = class_variable,
            source_ref    = source_ref
        )
        class_variable_ref = ExpressionVariableRef(
            variable_name = "__class__",
            variable      = class_variable,
            source_ref    = source_ref
        )

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref = class_target_variable_ref,
            source       = ExpressionCall(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass,
                    source_ref = source_ref
                ),
                args       = makeSequenceCreationOrConstant(
                    sequence_kind = "tuple",
                    elements      = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        ExpressionBuiltinLocals(
                            source_ref = source_ref
                        )
                    ),
                    source_ref    = source_ref
                ),
                kw         = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementReturn(
            expression = class_variable_ref,
            source_ref = source_ref
        )
    ]

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

    # The class body is basically a function that implicitly, at the end
    # returns its locals and cannot have other return statements contained.

    class_creation_function.setBody(body)

    # The class body is basically a function that implicitly, at the end
    # returns its created class and cannot have other return statements
    # contained.

    decorated_body = ExpressionFunctionCall(
        function   = ExpressionFunctionCreation(
            function_ref = ExpressionFunctionRef(
                function_body = class_creation_function,
                source_ref    = source_ref
            ),
            defaults     = (),
            kw_defaults  = None,
            annotations  = None,
            source_ref   = source_ref
        ),
        values     = (),
        source_ref = source_ref
    )

    for decorator in buildNodeList(
            provider,
            reversed(node.decorator_list),
            source_ref
        ):
        decorated_body = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements   = (
                    decorated_body,
                ),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )

    statements = (
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                elements      = buildNodeList(
                    provider, node.bases, source_ref
                ),
                source_ref    = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict,
                source_ref = source_ref
            ),
            source       = makeDictCreationOrConstant(
                keys       = [
                    ExpressionConstantRef(
                        constant      = keyword.arg,
                        source_ref    = source_ref,
                        user_provided = True
                    )
                    for keyword in
                    node.keywords
                ],
                values     = [
                    buildNode(provider, keyword.value, source_ref)
                    for keyword in
                    node.keywords
                ],
                lazy_order = False,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            source       = ExpressionSelectMetaclass(
                metaclass  = ExpressionConditional(
                    condition      = ExpressionComparison(
                        comparator = "In",
                        left       = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        right      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_expression = ExpressionDictOperationGet(
                        dicte      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict,
                            source_ref = source_ref
                        ),
                        key        = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        source_ref = source_ref
                    ),
                    no_expression  = ExpressionConditional(
                        condition      = ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        no_expression  = ExpressionBuiltinRef(
                            builtin_name = "type",
                            source_ref   = source_ref
                        ),
                        yes_expression = ExpressionBuiltinType1(
                            value      = ExpressionSubscriptLookup(
                                subscribed = ExpressionTempVariableRef(
                                    variable   = tmp_bases,
                                    source_ref = source_ref
                                ),
                                subscript  = ExpressionConstantRef(
                                    constant      = 0,
                                    source_ref    = source_ref,
                                    user_provided = True
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref     = source_ref
                    ),
                    source_ref     = source_ref
                ),
                bases      = ExpressionTempVariableRef(
                    variable   = tmp_bases,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref_orig
        ),
        StatementConditional(
            condition  = ExpressionComparison(
                comparator = "In",
                left       = ExpressionConstantRef(
                    constant      = "metaclass",
                    source_ref    = source_ref,
                    user_provided = True
                ),
                right      = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            no_branch  = None,
            yes_branch = makeStatementsSequenceFromStatement(
                statement = StatementDictOperationRemove(
                    dicte      = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict,
                        source_ref = source_ref
                    ),
                    key        = ExpressionConstantRef(
                        constant      = "metaclass",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition      = ExpressionBuiltinHasattr(
                    object     = ExpressionTempVariableRef(
                        variable   = tmp_metaclass,
                        source_ref = source_ref
                    ),
                    name       = ExpressionConstantRef(
                        constant      = "__prepare__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression  = ExpressionConstantRef(
                    constant      = {},
                    source_ref    = source_ref,
                    user_provided = True
                ),
                yes_expression = ExpressionCall(
                    called     = ExpressionAttributeLookup(
                        source         = ExpressionTempVariableRef(
                            variable   = tmp_metaclass,
                            source_ref = source_ref
                        ),
                        attribute_name = "__prepare__",
                        source_ref     = source_ref
                    ),
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionConstantRef(
                                constant      = node.name,
                                source_ref    = source_ref,
                                user_provided = True
                            ),
                            ExpressionTempVariableRef(
                                variable   = tmp_bases,
                                source_ref = source_ref
                            )
                        ),
                        source_ref = source_ref
                    ),
                    kw         = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref     = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = node.name,
                source_ref    = source_ref
            ),
            source       = decorated_body,
            source_ref   = source_ref
        ),
    )

    if Utils.python_version >= 340:
        class_assign = statements[-1]

        # assert False, class_creation_function
        class_creation_function.qualname_setup = class_assign, qualname_assign



    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
Ejemplo n.º 21
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
        )
Ejemplo n.º 22
0
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source,
                                         source_ref):
    # This is using many variable names on purpose, so as to give names to the
    # unpacked detail values, and has many branches due to the many cases
    # dealt with, pylint: disable=too-many-branches,too-many-locals,too-many-statements

    if kind == "Name":
        return StatementAssignmentVariableName(
            provider=provider,
            variable_name=detail,
            source=source,
            source_ref=source_ref,
        )
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        return StatementAssignmentAttribute(
            expression=lookup_source,
            attribute_name=attribute_name,
            source=source,
            source_ref=source_ref,
        )
    elif kind == "Subscript":
        subscribed, subscript = detail

        return StatementAssignmentSubscript(
            expression=subscribed,
            subscript=subscript,
            source=source,
            source_ref=source_ref,
        )
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        # For Python3 there is no slicing operation, this is always done
        # with subscript using a slice object. For Python2, it is only done
        # if no "step" is provided.
        use_sliceobj = python_version >= 300

        if use_sliceobj:
            return StatementAssignmentSubscript(
                expression=lookup_source,
                source=source,
                subscript=ExpressionBuiltinSlice(start=lower,
                                                 stop=upper,
                                                 step=None,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            )

        else:
            return StatementAssignmentSlice(
                expression=lookup_source,
                lower=lower,
                upper=upper,
                source=source,
                source_ref=source_ref,
            )
    elif kind == "Tuple":
        temp_scope = provider.allocateTempScope("tuple_unpack")

        source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope,
                                                        name="source_iter")

        element_vars = [
            provider.allocateTempVariable(temp_scope=temp_scope,
                                          name="element_%d" %
                                          (element_index + 1))
            for element_index in range(len(detail))
        ]

        starred_list_var = None
        starred_index = None

        statements = []

        for element_index, element in enumerate(detail):
            if element[0] == "Starred":
                if starred_index is not None:
                    raiseSyntaxError(
                        "two starred expressions in assignment",
                        source_ref.atColumnNumber(0),
                    )

                starred_index = element_index

        for element_index, element in enumerate(detail):
            element_var = element_vars[element_index]

            if starred_list_var is not None:
                statements.insert(
                    starred_index + 1,
                    StatementAssignmentVariable(
                        variable=element_var,
                        source=ExpressionListOperationPop(
                            list_arg=ExpressionTempVariableRef(
                                variable=starred_list_var,
                                source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                )
            elif element[0] != "Starred":
                statements.append(
                    StatementAssignmentVariable(
                        variable=element_var,
                        source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=source_iter_var,
                                source_ref=source_ref),
                            count=element_index + 1,
                            expected=starred_index or len(detail),
                            starred=starred_index is not None,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ))
            else:
                assert starred_index == element_index
                starred_list_var = element_var

                statements.append(
                    StatementAssignmentVariable(
                        variable=element_var,
                        source=ExpressionBuiltinList(
                            value=ExpressionTempVariableRef(
                                variable=source_iter_var,
                                source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ))

        if starred_list_var is None:
            statements.append(
                StatementSpecialUnpackCheck(
                    iterator=ExpressionTempVariableRef(
                        variable=source_iter_var, source_ref=source_ref),
                    count=len(detail),
                    source_ref=source_ref,
                ))
        else:
            statements.insert(
                starred_index + 1,
                makeStatementConditional(
                    condition=makeComparisonExpression(
                        comparator="Lt",
                        left=ExpressionBuiltinLen(
                            value=ExpressionTempVariableRef(
                                variable=starred_list_var,
                                source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                        right=makeConstantRefNode(
                            constant=len(statements) - starred_index - 1,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                    yes_branch=makeRaiseExceptionExpressionFromTemplate(
                        exception_type="ValueError",
                        template="""\
not enough values to unpack (expected at least %d, got %%d)""" %
                        (len(statements) - 1),
                        template_args=makeBinaryOperationNode(
                            operator="Add",
                            left=ExpressionBuiltinLen(
                                value=ExpressionTempVariableRef(
                                    variable=starred_list_var,
                                    source_ref=source_ref),
                                source_ref=source_ref,
                            ),
                            right=makeConstantRefNode(constant=starred_index,
                                                      source_ref=source_ref),
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ).asStatement(),
                    no_branch=None,
                    source_ref=source_ref,
                ),
            )

        if python_version >= 370:
            iter_creation_class = ExpressionBuiltinIterForUnpack
        else:
            iter_creation_class = ExpressionBuiltinIter1

        statements = [
            StatementAssignmentVariable(
                variable=source_iter_var,
                source=iter_creation_class(value=source,
                                           source_ref=source_ref),
                source_ref=source_ref,
            ),
            makeTryFinallyStatement(
                provider=provider,
                tried=statements,
                final=(StatementReleaseVariable(variable=source_iter_var,
                                                source_ref=source_ref), ),
                source_ref=source_ref,
            ),
        ]

        # When all is done, copy over to the actual assignment targets, starred
        # or not makes no difference here anymore.
        for element_index, element in enumerate(detail):
            if element[0] == "Starred":
                element = element[1]

            element_var = element_vars[element_index]

            statements.append(
                buildAssignmentStatementsFromDecoded(
                    provider=provider,
                    kind=element[0],
                    detail=element[1],
                    source=ExpressionTempVariableRef(variable=element_var,
                                                     source_ref=source_ref),
                    source_ref=source_ref,
                ))

            # Need to release temporary variables right after successful
            # usage.
            statements.append(
                StatementDelVariable(variable=element_var,
                                     tolerant=True,
                                     source_ref=source_ref))

        final_statements = []

        for element_var in element_vars:
            final_statements.append(
                StatementReleaseVariable(variable=element_var,
                                         source_ref=source_ref))

        return makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=final_statements,
            source_ref=source_ref,
        )
    elif kind == "Starred":
        raiseSyntaxError(
            "starred assignment target must be in a list or tuple",
            source_ref.atColumnNumber(0),
        )
    else:
        assert False, (kind, source_ref, detail)
Ejemplo n.º 23
0
    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_ref = ExpressionTargetTempVariableRef(
                        variable   = source_variable,
                        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,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    right      = ExpressionBuiltinRef(
                        builtin_name = "bytes",
                        source_ref   = source_ref
                    ),
                    source_ref = source_ref
                ),
                expression_yes = ExpressionConstantRef(
                    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_ref = ExpressionTargetTempVariableRef(
                    variable   = source_variable,
                    source_ref = source_ref
                ),
                source       = ExpressionCallNoKeywords(
                    called     = ExpressionAttributeLookup(
                        source         = ExpressionTempVariableRef(
                            variable   = source_variable,
                            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,
                    source_ref = source_ref
                ),
                source       = source,
                source_ref   = source_ref,
            ),
            StatementConditional(
                condition  = ExpressionOperationNOT(
                    operand    = ExpressionBuiltinIsinstance(
                        instance   = ExpressionTempVariableRef(
                            variable   = source_variable,
                            source_ref = source_ref
                        ),
                        classes    = ExpressionBuiltinAnonymousRef(
                            builtin_name = "code",
                            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
            ),
            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
Ejemplo n.º 24
0
def _buildInplaceAssignSubscriptNode(
    provider,
    subscribed,
    subscript,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    operator,
    expression,
    source_ref,
):
    # First assign the subscribed value to a temporary variable.
    preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1,
                                                   source=subscribed,
                                                   source_ref=source_ref)
    # Second assign the subscript value to a temporary variable
    statements = (
        StatementAssignmentVariable(variable=tmp_variable2,
                                    source=subscript,
                                    source_ref=source_ref),
        StatementAssignmentVariable(
            variable=tmp_variable3,
            source=ExpressionSubscriptLookup(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                                    source_ref=source_ref),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_variable3,
            source=makeExpressionOperationBinaryInplace(
                operator=operator,
                left=ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref),
                right=expression,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentSubscript(
            expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                 source_ref=source_ref),
            subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                                source_ref=source_ref),
            source=ExpressionTempVariableRef(variable=tmp_variable3,
                                             source_ref=source_ref),
            source_ref=source_ref,
        ),
    )

    return (
        preserve_to_tmp1,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=(
                StatementReleaseVariable(variable=tmp_variable1,
                                         source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable2,
                                         source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable3,
                                         source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
    )
Ejemplo n.º 25
0
def buildReturnNode(provider, node, source_ref):
    if not provider.isExpressionFunctionBody() or \
       provider.isClassDictCreation():
        SyntaxErrors.raiseSyntaxError(
            "'return' outside function",
            source_ref,
            None if Utils.python_version < 300 else (
                node.col_offset
                  if provider.isPythonModule() else
                node.col_offset+4
            )
        )

    expression = buildNode(provider, node.value, source_ref, allow_none = True)

    if expression is None:
        expression = ExpressionConstantRef(
            constant      = None,
            source_ref    = source_ref,
            user_provided = True
        )

    # Indicate exceptions to potentially try/finally structures.
    indicator_statements = makeTryFinallyIndicatorStatements(
        is_loop_exit = False,
        source_ref   = source_ref
    )

    if indicator_statements and expression.mayRaiseException(BaseException):
        tmp_variable = provider.allocateTempVariable(
            temp_scope = provider.allocateTempScope("return"),
            name       = "value"
        )

        statements = [
                StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable,
                    source_ref = expression.getSourceReference()
                ),
                source       = expression,
                source_ref   = source_ref
            )
        ] + indicator_statements + [
            StatementReturn(
                expression = ExpressionTempVariableRef(
                    variable   = tmp_variable,
                    source_ref = expression.getSourceReference()
                ),
                source_ref = source_ref
            )
        ]

        return makeTryFinallyStatement(
            tried      = statements,
            final      = StatementReleaseVariable(
                variable   = tmp_variable,
                tolerant   = True,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    else:
        return makeStatementsSequenceOrStatement(
            statements = indicator_statements + [
                StatementReturn(
                    expression = expression,
                    source_ref = source_ref
                )
            ],
            source_ref = source_ref
        )
Ejemplo n.º 26
0
def _buildInplaceAssignSliceNode(
    provider,
    lookup_source,
    lower,
    upper,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    tmp_variable4,
    operator,
    expression,
    source_ref,
):

    # Due to the 3 inputs, which we need to also put into temporary variables,
    # there are too many variables here, but they are needed.
    # pylint: disable=too-many-locals

    # First assign the target value, lower and upper to temporary variables.
    copy_to_tmp = StatementAssignmentVariable(variable=tmp_variable1,
                                              source=lookup_source,
                                              source_ref=source_ref)

    final_statements = [
        StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref)
    ]
    statements = []

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(variable=tmp_variable2,
                                        source=lower,
                                        source_ref=source_ref))
        final_statements.append(
            StatementReleaseVariable(variable=tmp_variable2,
                                     source_ref=source_ref))

        lower_ref1 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
        lower_ref2 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(variable=tmp_variable3,
                                        source=upper,
                                        source_ref=source_ref))
        final_statements.append(
            StatementReleaseVariable(variable=tmp_variable3,
                                     source_ref=source_ref))

        upper_ref1 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
        upper_ref2 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    use_sliceobj = python_version >= 300

    # Second assign the in-place result over the original value.
    if use_sliceobj:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSubscriptLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    subscript=ExpressionBuiltinSlice(
                        start=lower_ref2,
                        stop=upper_ref2,
                        step=None,
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSubscript(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=ExpressionBuiltinSlice(start=lower_ref1,
                                                 stop=upper_ref1,
                                                 step=None,
                                                 source_ref=source_ref),
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )
    else:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSliceLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    lower=lower_ref2,
                    upper=upper_ref2,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSlice(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                lower=lower_ref1,
                upper=upper_ref1,
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )

    final_statements.append(
        StatementReleaseVariable(variable=tmp_variable4,
                                 source_ref=source_ref))

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=final_statements,
            source_ref=source_ref,
        ),
    )
def _buildContractionBodyNode(provider, node, emit_class, start_value,
                              container_tmp, outer_iter_ref, temp_scope,
                              assign_provider, source_ref, function_body):

    if start_value is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp.makeReference(function_body),
                    source_ref=source_ref),
                source=start_value,
                source_ref=source_ref.atInternal())
        ]

        if assign_provider:
            tmp_variables = []
        else:
            tmp_variables = [container_tmp]
    else:
        statements = []
        tmp_variables = []

    if hasattr(node, "elt"):
        if start_value is not None:
            current_body = emit_class(ExpressionTempVariableRef(
                variable=container_tmp.makeReference(function_body),
                source_ref=source_ref),
                                      buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
        else:
            assert emit_class is ExpressionYield

            function_body.markAsGenerator()

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

        current_body = emit_class(ExpressionTempVariableRef(
            variable=container_tmp.makeReference(function_body),
            source_ref=source_ref),
                                  key=buildNode(
                                      provider=function_body,
                                      node=node.key,
                                      source_ref=source_ref,
                                  ),
                                  value=buildNode(
                                      provider=function_body,
                                      node=node.value,
                                      source_ref=source_ref,
                                  ),
                                  source_ref=source_ref)

    current_body = StatementExpressionOnly(expression=current_body,
                                           source_ref=source_ref)

    for count, qual in enumerate(reversed(node.generators)):
        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope=temp_scope, name="iter_value_%d" % count)

        tmp_variables.append(tmp_value_variable)

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.
        if qual is node.generators[0]:

            def makeIteratorRef():
                return outer_iter_ref.makeCloneAt(source_ref)

            tmp_iter_variable = None

            nested_statements = []
        else:
            # First create the iterator and store it, next should be loop body
            value_iterator = ExpressionBuiltinIter1(value=buildNode(
                provider=function_body, node=qual.iter, source_ref=source_ref),
                                                    source_ref=source_ref)

            tmp_iter_variable = function_body.allocateTempVariable(
                temp_scope=temp_scope, name="contraction_iter_%d" % count)

            tmp_variables.append(tmp_iter_variable)

            nested_statements = [
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_iter_variable.makeReference(
                            function_body),
                        source_ref=source_ref),
                    source=value_iterator,
                    source_ref=source_ref)
            ]

            def makeIteratorRef():
                return ExpressionTempVariableRef(
                    variable=tmp_iter_variable.makeReference(function_body),
                    source_ref=source_ref)

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried=makeStatementsSequenceFromStatement(
                    statement=StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=tmp_value_variable.makeReference(
                                function_body),
                            source_ref=source_ref),
                        source=ExpressionBuiltinNext1(value=makeIteratorRef(),
                                                      source_ref=source_ref),
                        source_ref=source_ref)),
                exception_name="StopIteration",
                handler_body=makeStatementsSequenceFromStatement(
                    statement=StatementBreakLoop(
                        source_ref=source_ref.atInternal())),
                public_exc=False,
                source_ref=source_ref),
            buildAssignmentStatements(
                provider=provider if assign_provider else function_body,
                temp_provider=function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(
                    variable=tmp_value_variable.makeReference(function_body),
                    source_ref=source_ref),
                source_ref=source_ref)
        ]

        conditions = buildNodeList(provider=function_body,
                                   nodes=qual.ifs,
                                   source_ref=source_ref)

        if len(conditions) == 1:
            loop_statements.append(
                StatementConditional(
                    condition=conditions[0],
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        elif len(conditions) > 1:
            loop_statements.append(
                StatementConditional(
                    condition=buildAndNode(provider=function_body,
                                           values=conditions,
                                           source_ref=source_ref),
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        else:
            loop_statements.append(current_body)

        nested_statements.append(
            StatementLoop(body=StatementsSequence(
                statements=mergeStatements(loop_statements),
                source_ref=source_ref),
                          source_ref=source_ref))

        if tmp_iter_variable is not None:
            nested_statements.append(
                StatementDelVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_iter_variable.makeReference(
                            function_body),
                        source_ref=source_ref),
                    tolerant=False,
                    source_ref=source_ref))

        current_body = StatementsSequence(statements=nested_statements,
                                          source_ref=source_ref)

    statements.append(current_body)
    statements = mergeStatements(statements)

    if emit_class is ExpressionYield:
        statements.insert(0, StatementGeneratorEntry(source_ref=source_ref))

    del_statements = []
    for tmp_variable in tmp_variables:
        del_statements.append(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable.makeReference(function_body),
                source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref.atInternal()))

    return statements, del_statements
Ejemplo n.º 28
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

    result = ExpressionFunctionBody(provider=getInternalModule(),
                                    name=helper_name,
                                    doc=None,
                                    parameters=ParameterSpec(
                                        name=helper_name,
                                        normal_args=(),
                                        list_star_arg="args",
                                        dict_star_arg=None,
                                        default_count=0,
                                        kw_only_args=()),
                                    flags=set(),
                                    source_ref=internal_source_ref)

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "dict")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_item_variable,
                    source_ref=internal_source_ref),
                source=ExpressionBuiltinNext1(value=ExpressionTempVariableRef(
                    variable=tmp_iter_variable,
                    source_ref=internal_source_ref),
                                              source_ref=internal_source_ref),
                source_ref=internal_source_ref),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref),
        makeTryExceptSingleHandlerNode(
            tried=StatementDictOperationUpdate(
                dict_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                value=ExpressionTempVariableRef(
                    variable=tmp_item_variable,
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref),
            exception_name="AttributeError",
            handler_body=StatementRaiseException(
                exception_type=ExpressionBuiltinMakeException(
                    exception_name="TypeError",
                    args=(ExpressionOperationBinary(
                        operator="Mod",
                        left=ExpressionConstantRef(
                            constant="""\
'%s' object is not a mapping""",
                            source_ref=internal_source_ref,
                            user_provided=True),
                        right=ExpressionMakeTuple(
                            elements=(ExpressionAttributeLookup(
                                source=ExpressionBuiltinType1(
                                    value=ExpressionTempVariableRef(
                                        variable=tmp_item_variable,
                                        source_ref=internal_source_ref),
                                    source_ref=internal_source_ref),
                                attribute_name="__name__",
                                source_ref=internal_source_ref), ),
                            source_ref=internal_source_ref),
                        source_ref=internal_source_ref), ),
                    source_ref=internal_source_ref),
                exception_value=None,
                exception_trace=None,
                exception_cause=None,
                source_ref=internal_source_ref),
            source_ref=internal_source_ref))

    args_variable = result.getVariableForAssignment(variable_name="args")

    final = (
        StatementReleaseVariable(variable=tmp_result_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_iter_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_item_variable,
                                 source_ref=internal_source_ref),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable, source_ref=internal_source_ref),
            source=ExpressionBuiltinIter1(value=ExpressionVariableRef(
                variable_name="args",
                variable=args_variable,
                source_ref=internal_source_ref),
                                          source_ref=internal_source_ref),
            source_ref=internal_source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_result_variable, source_ref=internal_source_ref),
            source=ExpressionConstantRef(constant={},
                                         source_ref=internal_source_ref),
            source_ref=internal_source_ref),
        StatementLoop(body=loop_body, source_ref=internal_source_ref),
        StatementReturn(expression=ExpressionTempVariableRef(
            variable=tmp_result_variable, source_ref=internal_source_ref),
                        source_ref=internal_source_ref))

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(provider=result,
                                    tried=tried,
                                    final=final,
                                    source_ref=internal_source_ref)))

    return result
Ejemplo n.º 29
0
def _buildWithNode(provider, context_expr, assign_target, body, source_ref):
    with_source = buildNode(provider, context_expr, source_ref)

    temp_scope = provider.allocateTempScope("with")

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

    statements = (buildAssignmentStatements(provider=provider,
                                            node=assign_target,
                                            allow_none=True,
                                            source=ExpressionTempVariableRef(
                                                variable=tmp_enter_variable,
                                                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)
Ejemplo n.º 30
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,
        ),
        StatementConditional(condition=ExpressionComparisonIs(
            left=ExpressionTempVariableRef(variable=locals_keeper_variable,
                                           source_ref=source_ref),
            right=ExpressionConstantNoneRef(source_ref=source_ref),
            source_ref=source_ref),
                             yes_branch=makeStatementsSequenceFromStatement(
                                 StatementAssignmentVariable(
                                     variable=locals_keeper_variable,
                                     source=locals_default,
                                     source_ref=source_ref,
                                 )),
                             no_branch=None,
                             source_ref=source_ref),
        StatementConditional(condition=ExpressionComparisonIs(
            left=ExpressionTempVariableRef(variable=globals_keeper_variable,
                                           source_ref=source_ref),
            right=ExpressionConstantNoneRef(source_ref=source_ref),
            source_ref=source_ref),
                             yes_branch=makeStatementsSequenceFromStatement(
                                 StatementAssignmentVariable(
                                     variable=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))