예제 #1
0
    def action(stage_dir, root, path):
        command = [
            sys.executable,
            os.path.join("..", "..", "bin", "nuitka"),
            "--stand",
            "--run",
            "--output-dir=%s" % stage_dir,
            "--remove-output",
        ]

        filename = os.path.join(stage_dir, "importer.py")

        assert path.startswith(root)

        module_name = path[len(root) + 1:]
        module_name = module_name.split(".")[0]
        module_name = module_name.replace(os.path.sep, ".")

        module_name = ModuleName(module_name)

        with openTextFile(filename, "w") as output:
            plugin_names = set(["pylint-warnings", "anti-bloat"])
            if module_name.hasNamespace("PySide2"):
                plugin_names.add("pyside2")
            elif module_name.hasNamespace("PySide6"):
                plugin_names.add("pyside2")
            elif module_name.hasNamespace("PyQt5"):
                plugin_names.add("pyqt5")
            else:
                # TODO: We do not have a noqt plugin yet.
                plugin_names.add("pyqt5")

            for plugin_name in plugin_names:
                output.write("# nuitka-project: --enable-plugin=%s\n" %
                             plugin_name)

            # Make it an error to find unwanted bloat compiled in.
            output.write("# nuitka-project: --noinclude-default-mode=error\n")

            output.write("import " + module_name.asString() + "\n")
            output.write("print('OK.')")

        command += os.environ.get("NUITKA_EXTRA_OPTIONS", "").split()

        command.append(filename)

        if checkSucceedsWithCPython(filename):
            try:
                output = check_output(command).splitlines()
            except Exception:  # only trying to check for no exception, pylint: disable=try-except-raise
                raise
            else:
                assert os.path.exists(filename[:-3] + ".dist")

                binary_filename = os.path.join(
                    filename[:-3] + ".dist",
                    "importer.exe" if os.name == "nt" else "importer",
                )
                loaded_filenames = getRuntimeTraceOfLoadedFiles(
                    logger=test_logger,
                    command=[binary_filename],
                )

                outside_accesses = checkLoadedFileAccesses(
                    loaded_filenames=loaded_filenames, current_dir=os.getcwd())

                if outside_accesses:
                    displayError(None, filename)
                    displayRuntimeTraces(test_logger, binary_filename)

                    test_logger.warning(
                        "Should not access these file(s): '%r'." %
                        outside_accesses)

                    search_mode.onErrorDetected(1)

                if output[-1] != b"OK.":
                    my_print(" ".join(command))
                    my_print(filename)
                    my_print(output)
                    test_logger.sysexit("FAIL.")

                my_print("OK.")

                assert not outside_accesses, outside_accesses

                shutil.rmtree(filename[:-3] + ".dist")
        else:
            my_print("SKIP (does not work with CPython)")
예제 #2
0
def findModule(importing, module_name, parent_package, level, warn):
    """Find a module with given package name as parent.

    The package name can be None of course. Level is the same
    as with "__import__" built-in. Warnings are optional.

    Returns:
        Returns a triple of package name the module is in, filename of
        it, which can be a directory for packages, and the location
        method used.
    """
    # We have many branches here, because there are a lot of cases to try.
    # pylint: disable=too-many-branches

    assert type(module_name) is ModuleName, module_name

    if _debug_module_finding:
        print("findModule: Enter to search %r in package %r level %s." %
              (module_name, parent_package, level))

    # Do not allow star imports to get here. We just won't find modules with
    # that name, but it would be wasteful.
    assert module_name != "*"

    tried_names = []

    if level > 1:
        # TODO: Should give a warning and return not found if the levels
        # exceed the package name.
        if parent_package is not None:
            # TODO: This should be done with the API instead.
            parent_package = ModuleName(".".join(
                parent_package.asString().split(".")[:-level + 1]))

            if parent_package == "":
                parent_package = None
        else:
            return None, None, "not-found"

    # Try relative imports first if we have a parent package.
    if level != 0 and parent_package is not None:
        if module_name:
            full_name = ModuleName(parent_package + "." + module_name)
        else:
            full_name = ModuleName(parent_package)

        full_name = normalizePackageName(full_name)
        tried_names.append(full_name)

        try:
            module_filename = _findModule(module_name=full_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                print(
                    "findModule: Relative imported module '%s' as '%s' in filename '%s':"
                    % (module_name, full_name, module_filename))

            return full_name.getPackageName(), module_filename, "relative"

    if level <= 1 and module_name != "":
        module_name = normalizePackageName(module_name)
        tried_names.append(module_name)

        package_name = module_name.getPackageName()

        # Built-in module names must not be searched any further.
        if module_name in sys.builtin_module_names:
            if _debug_module_finding:
                print(
                    "findModule: Absolute imported module '%s' in as built-in':"
                    % (module_name, ))
            return package_name, None, "built-in"

        try:
            module_filename = _findModule(module_name=module_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                print(
                    "findModule: Found absolute imported module '%s' in filename '%s':"
                    % (module_name, module_filename))

            return package_name, module_filename, "absolute"

    if warn:
        warnAbout(
            importing=importing,
            module_name=module_name,
            parent_package=parent_package,
            tried_names=tried_names,
            level=level,
        )

    return None, None, "not-found"
예제 #3
0
def decideModuleTree(filename, package, is_shlib, is_top, is_main):
    # Many variables, branches, due to the many cases
    # pylint: disable=too-many-branches,too-many-locals,too-many-statements

    assert package is None or type(package) is ModuleName
    assert filename is not None

    if is_main and os.path.isdir(filename):
        source_filename = os.path.join(filename, "__main__.py")

        if not os.path.isfile(source_filename):
            sys.stderr.write("%s: can't find '__main__' module in '%s'\n" %
                             (os.path.basename(sys.argv[0]), filename))
            sys.exit(2)

        filename = source_filename

        main_added = True
    else:
        main_added = False

    if os.path.isfile(filename):
        source_filename = filename

        source_ref = SourceCodeReferences.fromFilename(filename=filename)

        if is_main:
            module_name = ModuleName("__main__")
        else:
            # Derive module name from filename.
            module_name = os.path.basename(filename)
            if is_shlib:
                module_name = module_name.split(".")[0]
            elif module_name.endswith(".py"):
                module_name = module_name[:-3]

            if "." in module_name:
                sys.stderr.write(
                    "Error, '%s' is not a proper python module name.\n" %
                    (module_name))

                sys.exit(2)

            module_name = ModuleName.makeModuleNameInPackage(
                module_name, package)

        if is_shlib:
            result = PythonShlibModule(module_name=module_name,
                                       source_ref=source_ref)
            source_code = None
        else:
            source_code = readSourceCodeFromFilename(
                module_name=module_name, source_filename=source_filename)

            if is_main:
                result = PythonMainModule(
                    main_added=main_added,
                    mode=decideCompilationMode(False, module_name, source_ref),
                    future_spec=None,
                    source_ref=source_ref,
                )

                checkPythonVersionFromCode(source_code)
            else:
                mode = decideCompilationMode(is_top, module_name, source_ref)

                if (mode == "bytecode" and not is_top
                        and hasCachedImportedModulesNames(
                            module_name, source_code)):

                    optimization_logger.info("%r is included as bytecode." %
                                             (module_name.asString()))
                    result = UncompiledPythonModule(
                        module_name=module_name,
                        filename=filename,
                        bytecode=demoteSourceCodeToBytecode(
                            module_name=module_name,
                            source_code=source_code,
                            filename=filename,
                        ),
                        source_ref=source_ref,
                        user_provided=False,
                        technical=False,
                    )

                    used_modules = OrderedSet()

                    for used_module_name in getCachedImportedModulesNames(
                            module_name=module_name, source_code=source_code):
                        (
                            _module_package,
                            module_filename,
                            _finding,
                        ) = Importing.findModule(
                            importing=result,
                            module_name=used_module_name,
                            parent_package=None,
                            level=-1,
                            warn=False,
                        )

                        used_modules.add((used_module_name,
                                          os.path.relpath(module_filename)))

                    result.setUsedModules(used_modules)

                    # Not used anymore
                    source_code = None
                else:
                    result = CompiledPythonModule(
                        module_name=module_name,
                        is_top=is_top,
                        mode=mode,
                        future_spec=None,
                        source_ref=source_ref,
                    )

    elif Importing.isPackageDir(filename):
        if is_top:
            module_name = splitPath(filename)[-1]
        else:
            module_name = os.path.basename(filename)

        module_name = ModuleName.makeModuleNameInPackage(module_name, package)

        source_filename = os.path.join(filename, "__init__.py")

        if not os.path.isfile(source_filename):
            source_ref, result = createNamespacePackage(
                module_name=module_name,
                is_top=is_top,
                module_relpath=filename)
            source_filename = None
            source_code = None
        else:
            source_ref = SourceCodeReferences.fromFilename(
                filename=os.path.abspath(source_filename))

            result = CompiledPythonPackage(
                module_name=module_name,
                is_top=is_top,
                mode=decideCompilationMode(is_top, module_name, source_ref),
                future_spec=None,
                source_ref=source_ref,
            )

            source_code = readSourceCodeFromFilename(
                module_name=module_name, source_filename=source_filename)
    else:
        sys.stderr.write("%s: can't open file '%s'.\n" %
                         (os.path.basename(sys.argv[0]), filename))
        sys.exit(2)

    return result, source_ref, source_code