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(
                    source=ExpressionImportModuleNameHard(
                        module_name="os",
                        import_name="path",
                        source_ref=source_ref),
                    attribute_name="dirname",
                    source_ref=source_ref),
                args=ExpressionMakeTuple(
                    elements=(ExpressionModuleAttributeFileRef(
                        variable=package.getVariableForReference("__file__"),
                        source_ref=source_ref,
                    ), ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            )
        ]

        if package.canHaveExternalImports():
            parts = package.getFullName().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 = ExpressionMakeList(elements=elements,
                                        source_ref=source_ref)

    return StatementAssignmentVariableName(provider=package,
                                           variable_name="__path__",
                                           source=path_value,
                                           source_ref=source_ref)
Exemplo 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=too-many-branches

    pushFutureSpec()
    if is_module:
        provider.future_spec = getFutureSpec()

    body = parseSourceCodeToAst(source_code=source_code,
                                filename=source_ref.getFilename(),
                                line_offset=source_ref.getLineNumber() - 1)
    body, doc = extractDocFromBody(body)

    if is_module and is_main and python_version >= 360:
        provider.markAsNeedsAnnotationsDictionary()

    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 "no_site" not in Options.getPythonFlags():
            for path_imported_name in getPthImportedPackages():
                statements.append(
                    StatementExpressionOnly(expression=makeAbsoluteImportNode(
                        module_name=path_imported_name,
                        source_ref=source_ref,
                    ),
                                            source_ref=source_ref))

            statements.append(
                StatementExpressionOnly(expression=makeAbsoluteImportNode(
                    module_name="site",
                    source_ref=source_ref,
                ),
                                        source_ref=source_ref))

        statements.append(
            StatementAssignmentVariableName(provider=provider,
                                            variable_name="__doc__",
                                            source=makeConstantRefNode(
                                                constant=doc,
                                                source_ref=internal_source_ref,
                                                user_provided=True),
                                            source_ref=internal_source_ref))

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__file__",
                source=ExpressionModuleAttributeFileRef(
                    module=provider,
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref))

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

    if python_version >= 300:
        statements.append(
            StatementAssignmentVariableName(provider=provider,
                                            variable_name="__cached__",
                                            source=ExpressionConstantNoneRef(
                                                source_ref=internal_source_ref,
                                                user_provided=True),
                                            source_ref=internal_source_ref))

    needs__initializing__ = not provider.isMainModule(
    ) and 300 <= python_version < 340

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariableName(provider=provider,
                                            variable_name="__initializing__",
                                            source=makeConstantRefNode(
                                                constant=True,
                                                source_ref=internal_source_ref,
                                                user_provided=True),
                                            source_ref=internal_source_ref))

    if provider.needsAnnotationsDictionary():
        # Set "__annotations__" on module level to {}
        statements.append(
            StatementAssignmentVariableName(provider=provider,
                                            variable_name="__annotations__",
                                            source=makeConstantRefNode(
                                                constant={},
                                                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(
            StatementAssignmentVariableName(provider=provider,
                                            variable_name="__initializing__",
                                            source=makeConstantRefNode(
                                                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)

        popFutureSpec()

        return result
    else:
        assert False
Exemplo n.º 3
0
def buildParseTree(provider, ast_tree, 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=too-many-branches

    # Maybe one day, we do exec inlining again, that is what this is for,
    # then is_module won't be True, for now it always is.
    pushFutureSpec()
    if is_module:
        provider.setFutureSpec(getFutureSpec())

    body, doc = extractDocFromBody(ast_tree)

    if is_module and is_main and python_version >= 0x360:
        provider.markAsNeedsAnnotationsDictionary()

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

    # After building, we can verify that all future statements were where they
    # belong, namely at the start of the module.
    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 Options.hasPythonFlagNoSite():
            statements.append(
                StatementExpressionOnly(
                    expression=makeExpressionImportModuleFixed(
                        module_name="site", source_ref=source_ref),
                    source_ref=source_ref,
                ))

            for path_imported_name in getPthImportedPackages():
                if isHardModuleWithoutSideEffect(path_imported_name):
                    continue

                statements.append(
                    StatementExpressionOnly(
                        expression=makeExpressionImportModuleFixed(
                            module_name=path_imported_name,
                            source_ref=source_ref),
                        source_ref=source_ref,
                    ))

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__doc__",
                source=makeConstantRefNode(constant=doc,
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__file__",
                source=ExpressionModuleAttributeFileRef(
                    variable=provider.getVariableForReference("__file__"),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ))

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

        if python_version >= 0x340 and not is_main:
            statements += (
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="origin",
                    source=ExpressionModuleAttributeFileRef(
                        variable=provider.getVariableForReference("__file__"),
                        source_ref=internal_source_ref,
                    ),
                    source_ref=internal_source_ref,
                ),
                StatementAssignmentAttribute(
                    expression=ExpressionModuleAttributeSpecRef(
                        variable=provider.getVariableForReference("__spec__"),
                        source_ref=internal_source_ref,
                    ),
                    attribute_name="has_location",
                    source=makeConstantRefNode(True, internal_source_ref),
                    source_ref=internal_source_ref,
                ),
            )

            if provider.isCompiledPythonPackage():
                statements.append(
                    StatementAssignmentAttribute(
                        expression=ExpressionModuleAttributeSpecRef(
                            variable=provider.getVariableForReference(
                                "__spec__"),
                            source_ref=internal_source_ref,
                        ),
                        attribute_name="submodule_search_locations",
                        source=ExpressionVariableNameRef(
                            provider=provider,
                            variable_name="__path__",
                            source_ref=internal_source_ref,
                        ),
                        source_ref=internal_source_ref,
                    ))

    if python_version >= 0x300:
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__cached__",
                source=ExpressionConstantNoneRef(
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ))

    needs__initializing__ = (not provider.isMainModule()
                             and 0x300 <= python_version < 0x340)

    if needs__initializing__:
        # Set "__initializing__" at the beginning to True
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(constant=True,
                                           source_ref=internal_source_ref,
                                           user_provided=True),
                source_ref=internal_source_ref,
            ))

    if provider.needsAnnotationsDictionary():
        # Set "__annotations__" on module level to {}
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__annotations__",
                source=makeConstantRefNode(constant={},
                                           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.subnode_statements)

    if needs__initializing__:
        # Set "__initializing__" at the end to False
        statements.append(
            StatementAssignmentVariableName(
                provider=provider,
                variable_name="__initializing__",
                source=makeConstantRefNode(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)

        popFutureSpec()

        return result
    else:
        assert False
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)