Esempio n. 1
0
def _makeCall(module_name, import_name, attribute_name, source_ref, *args):
    return ExpressionCallNoKeywords(
        called=ExpressionAttributeLookup(
            expression=ExpressionImportModuleNameHard(
                module_name=module_name, import_name=import_name, source_ref=source_ref
            ),
            attribute_name=attribute_name,
            source_ref=source_ref,
        ),
        args=makeExpressionMakeTuple(elements=args, source_ref=source_ref),
        source_ref=source_ref,
    )
Esempio n. 2
0
def buildAssertNode(provider, node, source_ref):
    # Build assert statements. These are re-formulated as described in the
    # developer manual too. They end up as conditional statement with raises of
    # AssertionError exceptions.

    # Underlying assumption:
    #
    # Assert x, y is the same as:
    # if not x:
    #     raise AssertionError, y

    # Therefore assert statements are really just conditional statements with a
    # static raise contained.
    #

    exception_value = buildNode(provider, node.msg, source_ref, True)

    if "no_asserts" in getPythonFlags():
        return None

    if exception_value is not None and python_version >= 0x272:
        exception_value = makeExpressionMakeTuple(elements=(exception_value, ),
                                                  source_ref=source_ref)

    raise_statement = StatementRaiseException(
        exception_type=ExpressionBuiltinExceptionRef(
            exception_name="AssertionError", source_ref=source_ref),
        exception_value=exception_value,
        exception_trace=None,
        exception_cause=None,
        source_ref=source_ref,
    )

    return makeStatementConditional(
        condition=ExpressionOperationNot(operand=buildNode(
            provider, node.test, source_ref),
                                         source_ref=source_ref),
        yes_branch=raise_statement,
        no_branch=None,
        source_ref=source_ref,
    )
def buildDictionaryUnpacking(provider, node, source_ref):
    helper_args = buildDictionaryUnpackingArgs(provider, node.keys,
                                               node.values, source_ref)

    result = ExpressionFunctionCall(
        function=ExpressionFunctionCreation(
            function_ref=ExpressionFunctionRef(
                function_body=getDictUnpackingHelper(), source_ref=source_ref),
            defaults=(),
            kw_defaults=None,
            annotations=None,
            source_ref=source_ref,
        ),
        values=(makeExpressionMakeTuple(helper_args, source_ref), ),
        source_ref=source_ref,
    )

    result.setCompatibleSourceReference(
        helper_args[-1].getCompatibleSourceReference())

    return result
def _buildSetUnpacking(provider, elements, source_ref):
    helper_args = []

    for element in elements:

        # We could be a lot cleverer about the tuples for non-starred
        # arguments, but lets get this to work first. And then rely on
        # future optimization to inline the list unpacking helper in a
        # way that has the same effect.
        if getKind(element) == "Starred":
            helper_args.append(buildNode(provider, element.value, source_ref))
        else:
            helper_args.append(
                makeExpressionMakeTupleOrConstant(
                    elements=(buildNode(provider, element, source_ref), ),
                    user_provided=True,
                    source_ref=source_ref,
                ))

    result = ExpressionFunctionCall(
        function=ExpressionFunctionCreation(
            function_ref=ExpressionFunctionRef(
                function_body=getSetUnpackingHelper(), source_ref=source_ref),
            defaults=(),
            kw_defaults=None,
            annotations=None,
            source_ref=source_ref,
        ),
        values=(makeExpressionMakeTuple(helper_args, source_ref), ),
        source_ref=source_ref,
    )

    result.setCompatibleSourceReference(
        helper_args[-1].getCompatibleSourceReference())

    return result
Esempio n. 5
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=(),
        ),
        inline_const_args=False,  # TODO: Allow this.
    )

    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(
            expression=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=makeExpressionMakeTuple(
                        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=ExpressionConditionalAnd(
                left=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,
                ),
                right=ExpressionBuiltinIssubclass(
                    cls=ExpressionTempVariableRef(
                        variable=tmp_item_variable,
                        source_ref=internal_source_ref),
                    classes=makeConstantRefNode(
                        constant=type, source_ref=internal_source_ref),
                    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(loop_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.setChild(
        "body",
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )),
    )

    return result
Esempio 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_locals_scope = class_creation_function.getLocalsScope()

    # Only local variable, for provision to methods.
    class_variable = class_locals_scope.getLocalVariable(
        owner=class_creation_function, variable_name="__class__")
    class_locals_scope.registerProvidedVariable(class_variable)

    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_freevars=(),
        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.getLocalsScope()

    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 Python3.
    qualname = class_creation_function.getFunctionQualname()

    if python_version < 0x340:
        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 >= 0x340:
        qualname_assign = statements[-1]

    if python_version >= 0x360 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 >= 0x370:
            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 >= 0x370 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=makeExpressionMakeTuple(
                    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.setChild("body", 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=makeExpressionMakeTuple(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 < 0x370 else tmp_bases_orig,
                source=_buildBasesTupleCreationNode(provider=provider,
                                                    elements=node.bases,
                                                    source_ref=source_ref),
                source_ref=source_ref,
            ))

        if python_version >= 0x370:
            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 >= 0x370:
            unspecified_metaclass_expression = ExpressionConditional(
                condition=ExpressionTempVariableRef(variable=tmp_bases,
                                                    source_ref=source_ref),
                expression_yes=unspecified_metaclass_expression,
                expression_no=makeExpressionBuiltinTypeRef(
                    builtin_name="type", source_ref=source_ref),
                source_ref=source_ref,
            )
    else:
        unspecified_metaclass_expression = makeExpressionBuiltinTypeRef(
            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=makeExpressionMakeTuple(
                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 >= 0x364:
        call_prepare = makeStatementsSequenceFromStatements(
            call_prepare,
            makeStatementConditional(
                condition=ExpressionAttributeCheck(
                    expression=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(
                            expression=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(
                expression=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 >= 0x340:
        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 >= 0x370:
            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,
    )
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,
    )
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

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

    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=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,
        ),
        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=(makeBinaryOperationNode(
                        operator="Mod",
                        left=makeConstantRefNode(
                            constant="""\
'%s' object is not a mapping""",
                            source_ref=internal_source_ref,
                            user_provided=True,
                        ),
                        right=makeExpressionMakeTuple(
                            elements=(ExpressionAttributeLookup(
                                expression=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=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=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
Esempio n. 9
0
def createPathAssignment(package, source_ref):
    if Options.getFileReferenceMode() == "original":
        path_value = makeConstantRefNode(
            constant=[os.path.dirname(source_ref.getFilename())],
            source_ref=source_ref,
            user_provided=True,
        )
    else:
        elements = [
            ExpressionCallNoKeywords(
                called=ExpressionAttributeLookup(
                    expression=ExpressionImportModuleNameHard(
                        module_name="os", import_name="path", source_ref=source_ref
                    ),
                    attribute_name="dirname",
                    source_ref=source_ref,
                ),
                args=makeExpressionMakeTuple(
                    elements=(
                        ExpressionModuleAttributeFileRef(
                            variable=package.getVariableForReference("__file__"),
                            source_ref=source_ref,
                        ),
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            )
        ]

        if package.canHaveExternalImports():
            parts = package.getFullName().asString().split(".")

            for count in range(len(parts)):
                path_part = _makeCall(
                    "os",
                    "environ",
                    "get",
                    source_ref,
                    makeConstantRefNode(
                        constant="NUITKA_PACKAGE_%s" % "_".join(parts[: count + 1]),
                        source_ref=source_ref,
                    ),
                    makeConstantRefNode(constant="/notexist", source_ref=source_ref),
                )

                if parts[count + 1 :]:
                    path_part = _makeCall(
                        "os",
                        "path",
                        "join",
                        source_ref,
                        path_part,
                        makeConstantRefNode(
                            constant=os.path.join(*parts[count + 1 :]),
                            source_ref=source_ref,
                        ),
                    )

                elements.append(path_part)

        path_value = makeExpressionMakeList(elements=elements, source_ref=source_ref)

    return StatementAssignmentVariableName(
        provider=package,
        variable_name="__path__",
        source=path_value,
        source_ref=source_ref,
    )
Esempio n. 10
0
def buildClassNode2(provider, node, source_ref):
    # This function is the Python2 special case with special re-formulation as
    # according to developer manual, and it's very detailed, pylint: disable=too-many-locals
    class_statement_nodes, class_doc = extractDocFromBody(node)

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

    parent_module = provider.getParentModule()

    code_object = CodeObjectSpec(
        co_name=node.name,
        co_kind="Class",
        co_varnames=(),
        co_freevars=(),
        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=function_body,
        nodes=class_statement_nodes,
        code_object=code_object,
        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()

    locals_scope = function_body.getLocalsScope()

    # 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 = [
        StatementSetLocalsDictionary(locals_scope=locals_scope,
                                     source_ref=source_ref),
        StatementAssignmentVariableName(
            provider=function_body,
            variable_name="__module__",
            source=ExpressionModuleAttributeNameRef(
                variable=provider.getParentModule().getVariableForReference(
                    "__name__"),
                source_ref=source_ref,
            ),
            source_ref=source_ref.atInternal(),
        ),
    ]

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

    statements += (
        body,
        StatementReturn(
            expression=ExpressionBuiltinLocalsRef(locals_scope=locals_scope,
                                                  source_ref=source_ref),
            source_ref=source_ref,
        ),
    )

    body = makeStatementsSequenceFromStatement(
        statement=makeTryFinallyStatement(
            provider=function_body,
            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.

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

    select_metaclass = ExpressionOutlineBody(provider=provider,
                                             name="select_metaclass",
                                             body=None,
                                             source_ref=source_ref)

    if node.bases:
        tmp_base = select_metaclass.allocateTempVariable(temp_scope=None,
                                                         name="base")

        statements = (
            StatementAssignmentVariable(
                variable=tmp_base,
                source=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,
            ),
            makeTryFinallyStatement(
                provider,
                tried=StatementTry(
                    tried=makeStatementsSequenceFromStatement(
                        statement=StatementReturn(
                            expression=ExpressionAttributeLookup(
                                expression=ExpressionTempVariableRef(
                                    variable=tmp_base, source_ref=source_ref),
                                attribute_name="__class__",
                                source_ref=source_ref,
                            ),
                            source_ref=source_ref,
                        )),
                    except_handler=makeStatementsSequenceFromStatement(
                        statement=StatementReturn(
                            expression=ExpressionBuiltinType1(
                                value=ExpressionTempVariableRef(
                                    variable=tmp_base, source_ref=source_ref),
                                source_ref=source_ref,
                            ),
                            source_ref=source_ref,
                        )),
                    break_handler=None,
                    continue_handler=None,
                    return_handler=None,
                    source_ref=source_ref,
                ),
                final=StatementReleaseVariable(variable=tmp_base,
                                               source_ref=source_ref),
                source_ref=source_ref,
                public_exc=False,
            ),
        )
    else:
        statements = (
            StatementTry(
                tried=makeStatementsSequenceFromStatement(
                    statement=StatementReturn(
                        # TODO: Should avoid checking __builtins__ for this.
                        expression=ExpressionVariableNameRef(
                            variable_name="__metaclass__",
                            provider=parent_module,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    )),
                except_handler=makeStatementsSequenceFromStatement(
                    statement=StatementReturn(
                        expression=ExpressionBuiltinAnonymousRef(
                            builtin_name="classobj", source_ref=source_ref),
                        source_ref=source_ref,
                    )),
                break_handler=None,
                continue_handler=None,
                return_handler=None,
                source_ref=source_ref,
            ), )

    select_metaclass.setBody(
        makeStatementsSequence(statements=statements,
                               allow_none=False,
                               source_ref=source_ref))

    statements = [
        StatementAssignmentVariable(
            variable=tmp_bases,
            source=makeExpressionMakeTupleOrConstant(
                elements=buildNodeList(provider=provider,
                                       nodes=node.bases,
                                       source_ref=source_ref),
                user_provided=True,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(variable=tmp_class_dict,
                                    source=function_body,
                                    source_ref=source_ref),
        StatementAssignmentVariable(
            variable=tmp_metaclass,
            source=ExpressionConditional(
                condition=ExpressionDictOperationIn(
                    key=makeConstantRefNode(
                        constant="__metaclass__",
                        source_ref=source_ref,
                        user_provided=True,
                    ),
                    dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict,
                                                       source_ref=source_ref),
                    source_ref=source_ref,
                ),
                expression_yes=ExpressionDictOperationGet(
                    dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict,
                                                       source_ref=source_ref),
                    key=makeConstantRefNode(
                        constant="__metaclass__",
                        source_ref=source_ref,
                        user_provided=True,
                    ),
                    source_ref=source_ref,
                ),
                expression_no=select_metaclass,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_class,
            source=makeExpressionCall(
                called=ExpressionTempVariableRef(variable=tmp_metaclass,
                                                 source_ref=source_ref),
                args=makeExpressionMakeTuple(
                    elements=(
                        makeConstantRefNode(
                            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,
                ),
                kw=None,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
    ]

    for decorator in buildNodeList(provider, reversed(node.decorator_list),
                                   source_ref):
        statements.append(
            StatementAssignmentVariable(
                variable=tmp_class,
                source=makeExpressionCall(
                    called=decorator,
                    args=makeExpressionMakeTuple(
                        elements=(ExpressionTempVariableRef(
                            variable=tmp_class, source_ref=source_ref), ),
                        source_ref=source_ref,
                    ),
                    kw=None,
                    source_ref=decorator.getSourceReference(),
                ),
                source_ref=decorator.getSourceReference(),
            ))

    statements.append(
        StatementAssignmentVariableName(
            provider=provider,
            variable_name=mangleName(node.name, provider),
            source=ExpressionTempVariableRef(variable=tmp_class,
                                             source_ref=source_ref),
            source_ref=source_ref,
        ))

    final = (
        StatementReleaseVariable(variable=tmp_class, source_ref=source_ref),
        StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref),
        StatementReleaseVariable(variable=tmp_class_dict,
                                 source_ref=source_ref),
        StatementReleaseVariable(variable=tmp_metaclass,
                                 source_ref=source_ref),
    )

    return makeTryFinallyStatement(provider=function_body,
                                   tried=statements,
                                   final=final,
                                   source_ref=source_ref)
Esempio n. 11
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.is_fullcompat:
        source_ref = with_source.getCompatibleSourceReference()

    temp_scope = provider.allocateTempScope("with")

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

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

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

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

    if body:
        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=makeExpressionMakeTuple(
            elements=(
                ExpressionCaughtExceptionTypeRef(
                    source_ref=with_exit_source_ref),
                ExpressionCaughtExceptionValueRef(
                    source_ref=with_exit_source_ref),
                ExpressionCaughtExceptionTracebackRef(source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
        source_ref=with_exit_source_ref,
    )

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

    # For "async with", await the entered value and exit value must be awaited.
    if not sync:
        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,
    )
def getNameSpacePathExpression(package, source_ref):
    """Create the __path__ expression for a package."""

    reference_mode = Options.getFileReferenceMode()

    if reference_mode == "original":
        return makeConstantRefNode(
            constant=[package.getCompileTimeDirectory()],
            source_ref=source_ref,
        )
    elif reference_mode == "frozen":
        return makeConstantRefNode(
            constant=[],
            source_ref=source_ref,
        )
    else:
        elements = [
            ExpressionCallNoKeywords(
                called=makeExpressionAttributeLookup(
                    expression=makeExpressionImportModuleNameHard(
                        module_name="os", import_name="path", source_ref=source_ref
                    ),
                    attribute_name="dirname",
                    source_ref=source_ref,
                ),
                args=makeExpressionMakeTuple(
                    elements=(
                        ExpressionModuleAttributeFileRef(
                            variable=package.getVariableForReference("__file__"),
                            source_ref=source_ref,
                        ),
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            )
        ]

        if package.canHaveExternalImports():
            parts = package.getFullName().asString().split(".")

            for count in range(len(parts)):
                path_part = _makeCall(
                    "os",
                    "environ",
                    "get",
                    source_ref,
                    makeConstantRefNode(
                        constant="NUITKA_PACKAGE_%s" % "_".join(parts[: count + 1]),
                        source_ref=source_ref,
                    ),
                    makeConstantRefNode(constant="/notexist", source_ref=source_ref),
                )

                if parts[count + 1 :]:
                    path_part = _makeCall(
                        "os",
                        "path",
                        "join",
                        source_ref,
                        path_part,
                        makeConstantRefNode(
                            constant=os.path.join(*parts[count + 1 :]),
                            source_ref=source_ref,
                        ),
                    )

                elements.append(path_part)

        return makeExpressionMakeList(elements=elements, source_ref=source_ref)