Ejemplo n.º 1
0
def buildFrameNode(provider, nodes, code_object, source_ref):
    # We are not creating empty statement sequences.
    if nodes is None:
        return None

    # Build as list of statements, throw away empty ones, and remove useless
    # nesting.
    statements = buildNodeList(provider, nodes, source_ref, allow_none = True)
    statements = mergeStatements(statements)

    # We are not creating empty statement sequences. Might be empty, because
    # e.g. a global node generates not really a statement, or pass statements.
    if not statements:
        return None

    if provider.isExpressionOutlineFunction():
        provider = provider.getParentVariableProvider()

    if provider.isExpressionFunctionBody() or \
       provider.isExpressionClassBody():
        result = StatementsFrameFunction(
            statements  = statements,
            code_object = code_object,
            source_ref  = source_ref
        )
    elif provider.isExpressionGeneratorObjectBody():
        result = StatementsFrameGenerator(
            statements  = statements,
            code_object = code_object,
            source_ref  = source_ref
        )
    elif provider.isExpressionCoroutineObjectBody():
        result = StatementsFrameCoroutine(
            statements  = statements,
            code_object = code_object,
            source_ref  = source_ref
        )
    elif provider.isExpressionAsyncgenObjectBody():
        result = StatementsFrameAsyncgen(
            statements  = statements,
            code_object = code_object,
            source_ref  = source_ref
        )
    else:
        assert False, provider

    return result
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_freevars=(),
        co_argcount=1,
        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(),
    )

    is_async = any(getattr(qual, "is_async", 0) for qual in node.generators)

    # Some of the newly allowed stuff in 3.7 fails to set the async flag.
    if not is_async and python_version >= 370:
        is_async = detectFunctionBodyKind(nodes=node.generators)[0] in (
            "Asyncgen",
            "Coroutine",
        )

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

        maker_class = ExpressionMakeAsyncgenObject
    else:
        code_body = ExpressionGeneratorObjectBody(
            provider=provider,
            name="<genexpr>",
            code_object=code_object,
            flags=None,
            auto_release=None,
            source_ref=source_ref.atColumnNumber(node.col_offset + 1),
        )

        maker_class = ExpressionMakeGeneratorObject

    function_body.setBody(
        makeStatementsSequenceFromStatements(
            StatementAssignmentVariable(
                variable=iter_tmp,
                source=_makeIteratorCreation(
                    provider=provider,
                    qual=node.generators[0],
                    for_asyncgen=is_async,
                    source_ref=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(
        provider=provider,
        node=node,
        emit_class=ExpressionYield,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=None,
        container_tmp=None,
        function_body=code_body,
        assign_provider=False,
        for_asyncgen=is_async,
        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 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())

    code_body = ExpressionGeneratorObjectBody(provider=provider,
                                              name="<genexpr>",
                                              flags=set(),
                                              source_ref=source_ref)

    function_body.setBody(
        makeStatementsSequenceFromStatements(
            StatementAssignmentVariable(variable=iter_tmp,
                                        source=ExpressionBuiltinIter1(
                                            value=buildNode(
                                                provider=provider,
                                                node=node.generators[0].iter,
                                                source_ref=source_ref),
                                            source_ref=source_ref),
                                        source_ref=source_ref),
            makeTryFinallyStatement(
                provider=function_body,
                tried=StatementReturn(expression=ExpressionMakeGeneratorObject(
                    generator_ref=ExpressionFunctionRef(
                        function_body=code_body, source_ref=source_ref),
                    code_object=code_object,
                    source_ref=source_ref),
                                      source_ref=source_ref),
                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,
    )

    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