示例#1
0
    def onModuleEncounter(self, module_filename, module_name, module_kind):
        # Make sure
        if module_name.isBelowNamespace("webview.platforms"):
            if isWin32Windows():
                result = module_name in (
                    "webview.platforms.winforms",
                    "webview.platforms.edgechromium",
                    "webview.platforms.edgehtml",
                    "webview.platforms.mshtml",
                    "webview.platforms.cef",
                )
                reason = "Platforms package of webview used on '%s'." % getOS()
            elif isMacOS():
                result = module_name == "webview.platforms.cocoa"
                reason = "Platforms package of webview used on '%s'." % getOS()
            elif getActiveQtPlugin() is not None:
                result = module_name = "webview.platforms.qt"
                reason = ("Platforms package of webview used due to '%s'." %
                          getActiveQtPlugin())
            else:
                result = module_name = "webview.platforms.gtk"
                reason = (
                    "Platforms package of webview used on '%s' without Qt plugin enabled."
                    % getOS())

            return result, reason
示例#2
0
def _expandProjectArg(arg, filename_arg, for_eval):
    def wrap(value):
        if for_eval:
            return repr(value)
        else:
            return value

    values = {
        "OS": wrap(getOS()),
        "Arch": wrap(getArchitecture()),
        "Flavor": wrap(_getPythonFlavor()),
        "Version": getNuitkaVersion(),
        "Commercial": wrap(getCommercialVersion()),
        "MAIN_DIRECTORY": wrap(os.path.dirname(filename_arg) or "."),
    }

    if isLinux():
        dist_info = getLinuxDistribution()
    else:
        dist_info = "N/A", "N/A", "0"

    values["Linux_Distribution_Name"] = dist_info[0]
    values["Linux_Distribution_Base"] = dist_info[1] or dist_info[0]
    values["Linux_Distribution_Version"] = dist_info[2]

    if getOS() == "Windows":
        values["WindowsRelease"] = getWindowsRelease()

    arg = arg.format(**values)

    return arg
示例#3
0
    def considerExtraDlls(self, dist_dir, module):
        full_name = module.getFullName()

        if full_name == "uuid" and getOS() == "Linux":
            uuid_dll_path = locateDLL("uuid")
            dist_dll_path = os.path.join(dist_dir,
                                         os.path.basename(uuid_dll_path))

            shutil.copy(uuid_dll_path, dist_dll_path)

            return ((uuid_dll_path, dist_dll_path, None), )
        elif full_name == "iptc" and getOS() == "Linux":
            import iptc.util  # pylint: disable=I0021,import-error

            xtwrapper_dll = iptc.util.find_library("xtwrapper")[0]
            xtwrapper_dll_path = xtwrapper_dll._name  # pylint: disable=protected-access

            dist_dll_path = os.path.join(dist_dir,
                                         os.path.basename(xtwrapper_dll_path))

            shutil.copy(xtwrapper_dll_path, dist_dll_path)

            return ((xtwrapper_dll_path, dist_dll_path, None), )

        return ()
示例#4
0
def _getVersionInformationValues():
    # TODO: Might be nice if we could delay version information computation
    # until it's actually used.
    yield getNuitkaVersion()
    yield "Commercial: %s" % getCommercialVersion()
    yield "Python: %s" % sys.version.split("\n", 1)[0]
    yield "Flavor: %s" % _getPythonFlavor()
    yield "Executable: %s" % sys.executable
    yield "OS: %s" % getOS()
    yield "Arch: %s" % getArchitecture()

    if isLinux():
        dist_name, dist_base, dist_version = getLinuxDistribution()

        if dist_base is not None:
            yield "Distribution: %s (based on %s) %s" % (
                dist_name,
                dist_base,
                dist_version,
            )
        else:
            yield "Distribution: %s %s" % (dist_name, dist_version)

    if getOS() == "Windows":
        yield "WindowsRelease: %s" % getWindowsRelease()
示例#5
0
def packDistFolderToOnefile(dist_dir, binary_filename):
    """Pack distribution to onefile, i.e. a single file that is directly executable."""

    if getOS() == "Linux":
        packDistFolderToOnefileLinux(dist_dir, binary_filename)
    elif getOS() == "Windows":
        packDistFolderToOnefileWindows(dist_dir)
    else:
        general.warning("Onefile mode is not yet available on '%s'." % getOS())
示例#6
0
def packDistFolderToOnefile(dist_dir, binary_filename):
    """Pack distribution to onefile, i.e. a single file that is directly executable."""

    if getOS() == "Linux":
        packDistFolderToOnefileLinux(dist_dir, binary_filename)
    elif getOS() == "Windows":
        packDistFolderToOnefileWindows(dist_dir)
    else:
        postprocessing_logger.sysexit(
            "Onefile mode is not yet available on %r." % getOS()
        )
示例#7
0
def packDistFolderToOnefile(dist_dir, binary_filename):
    """Pack distribution to onefile, i.e. a single file that is directly executable."""

    onefile_output_filename = getResultFullpath(onefile=True)

    if getOS() == "Windows" or Options.isExperimental("onefile-bootstrap"):
        packDistFolderToOnefileBootstrap(onefile_output_filename, dist_dir)
    elif getOS() == "Linux":
        packDistFolderToOnefileLinux(onefile_output_filename, dist_dir, binary_filename)
    else:
        postprocessing_logger.sysexit(
            "Onefile mode is not yet available on %r." % getOS()
        )

    Plugins.onOnefileFinished(onefile_output_filename)
示例#8
0
def shallUseStaticLibPython():
    """*bool* = "--static-libpython=yes|auto"

    Notes:
        Currently only Anaconda on non-Windows can do this and MSYS2.
    """

    if options.static_libpython == "auto":
        if isWin32Windows() and os.path.exists(
                os.path.join(sys.prefix, "etc/config.site")):
            return True

        # For Anaconda default to trying static lib python library, which
        # normally is just not available or if it is even unusable.
        if (os.path.exists(os.path.join(sys.prefix, "conda-meta"))
                and not isWin32Windows() and not getOS() == "Darwin"):
            return True

        options.static_libpython = "no"

        if getSystemStaticLibPythonPath() is not None:
            Tracing.options_logger.info(
                "Detected static libpython as existing, consider using '--static-libpython=yes'."
            )

    return options.static_libpython == "yes"
示例#9
0
def _cleanupClangFormat(filename):
    """ Call clang-format on a given filename to format C code.

    Args:
        filename: What file to re-format.
    """

    # Using global here, as this is really a singleton, in
    # the form of a module, pylint: disable=global-statement
    global warned_clang_format

    clang_format_path = getExecutablePath("clang-format-7")

    # Extra ball on Windows, check default installation PATH too.
    if not clang_format_path and getOS() == "Windows":
        with withEnvironmentPathAdded(
                "PATH",
                r"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\Llvm\8.0.0\bin",
        ):
            with withEnvironmentPathAdded("PATH",
                                          r"C:\Program Files\LLVM\bin"):
                clang_format_path = getExecutablePath("clang-format")

    if clang_format_path:
        subprocess.call([
            clang_format_path,
            "-i",
            "-style={BasedOnStyle: llvm, IndentWidth: 4, ColumnLimit: 120}",
            filename,
        ])
    else:
        if not warned_clang_format:

            warning("Need to install LLVM for C files format.")
            warned_clang_format = True
示例#10
0
def _cleanupClangFormat(filename):
    # Using global here, as this is really a singleton, in
    # the form of a module, pylint: disable=global-statement
    global warned_clang_format

    clang_format_path = getExecutablePath("clang-format")

    # Extra ball on Windows, check default installation PATH too.
    if not clang_format_path and getOS() == "Windows":
        with withEnvironmentPathAdded("PATH", r"C:\Program Files\LLVM\bin"):
            clang_format_path = getExecutablePath("clang-format")

    if clang_format_path:
        subprocess.call(
            [
                clang_format_path,
                "-i",
                "-style={BasedOnStyle: llvm, IndentWidth: 4, ColumnLimit: 120}",
                filename,
            ]
        )
    else:
        if not warned_clang_format:

            warning("Need to install LLVM for C files format.")
            warned_clang_format = True
示例#11
0
def _runOnefileScons(quiet):

    source_dir = OutputDirectories.getSourceDirectoryPath(onefile=True)
    SconsInterface.cleanSconsDirectory(source_dir)

    asBoolStr = SconsInterface.asBoolStr

    options = {
        "result_name": OutputDirectories.getResultBasepath(onefile=True),
        "result_exe": OutputDirectories.getResultFullpath(onefile=True),
        "source_dir": source_dir,
        "debug_mode": asBoolStr(Options.is_debug),
        "unstripped_mode": asBoolStr(Options.isUnstripped()),
        "experimental": ",".join(Options.getExperimentalIndications()),
        "trace_mode": asBoolStr(Options.shallTraceExecution()),
        "target_arch": getArchitecture(),
        "python_prefix": sys.prefix,
        "nuitka_src": SconsInterface.getSconsDataPath(),
        "compiled_exe": OutputDirectories.getResultFullpath(onefile=False),
    }

    SconsInterface.setCommonOptions(options)

    onefile_env_values = {}

    if Options.isWindowsOnefileTempDirMode() or getOS() != "Windows":
        onefile_env_values["ONEFILE_TEMP_SPEC"] = Options.getWindowsOnefileTempDirSpec(
            use_default=True
        )
    else:
        # Merge version information if possible, to avoid collisions, or deep nesting
        # in file system.
        product_version = version_resources["ProductVersion"]
        file_version = version_resources["FileVersion"]

        if product_version != file_version:
            effective_version = "%s-%s" % (product_version, file_version)
        else:
            effective_version = file_version

        onefile_env_values["ONEFILE_COMPANY"] = version_resources["CompanyName"]
        onefile_env_values["ONEFILE_PRODUCT"] = version_resources["ProductName"]
        onefile_env_values["ONEFILE_VERSION"] = effective_version

    with withEnvironmentVarsOverriden(onefile_env_values):
        result = SconsInterface.runScons(
            options=options, quiet=quiet, scons_filename="WindowsOnefile.scons"
        )

    # Exit if compilation failed.
    if not result:
        scons_logger.sysexit("Error, one file bootstrap build for Windows failed.")

    if Options.isRemoveBuildDir():
        general.info("Removing onefile build directory %r." % source_dir)

        removeDirectory(path=source_dir, ignore_errors=False)
        assert not os.path.exists(source_dir)
    else:
        general.info("Keeping onefile build directory %r." % source_dir)
示例#12
0
def getResultFullpath(onefile):
    """Get the final output binary result full path."""

    result = getResultBasepath(onefile=onefile)

    if Options.shallMakeModule():
        result += getSharedLibrarySuffix(preferred=True)
    else:
        output_filename = Options.getOutputFilename()

        if Options.isOnefileMode() and output_filename is not None:
            if onefile:
                result = output_filename
            else:
                result = os.path.join(
                    getStandaloneDirectoryPath(),
                    os.path.basename(output_filename),
                )
        elif output_filename is not None:
            result = output_filename
        elif getOS() == "Windows":
            result += ".exe"
        elif (not Options.isStandaloneMode()
              or onefile and not Options.shallCreateAppBundle()):
            result += ".bin"

    return result
示例#13
0
def getNumpyCoreBinaries(module):
    """Return any binaries in numpy/core and/or numpy/.libs.

    Notes:
        This covers the special cases like MKL binaries.

    Returns:
        tuple of abspaths of binaries.
    """
    numpy_dir = module.getCompileTimeDirectory()
    numpy_core_dir = os.path.join(numpy_dir, "core")
    base_prefix = getSystemPrefixPath()

    binaries = []

    # first look in numpy/.libs for binaries
    libdir = os.path.join(numpy_dir,
                          ".libs" if getOS() != "Darwin" else ".dylibs")
    suffix_start = len(libdir) + 1
    if os.path.isdir(libdir):
        dlls_pkg = os.listdir(libdir)
        binaries += [[os.path.join(libdir, f), suffix_start] for f in dlls_pkg]

    # then look for libraries in numpy.core package path
    # should already return the MKL files in ordinary cases

    re_anylib = re.compile(r"\w+\.(?:dll|so|dylib)", re.IGNORECASE)

    dlls_pkg = [f for f in os.listdir(numpy_core_dir) if re_anylib.match(f)]
    binaries += [[os.path.join(numpy_core_dir, f), suffix_start]
                 for f in dlls_pkg]

    # Also look for MKL libraries in folder "above" numpy.
    # This should meet the layout of Anaconda installs.

    if isWin32Windows():
        lib_dir = os.path.join(base_prefix, "Library", "bin")
        suffix_start = len(lib_dir) + 1
    else:
        lib_dir = os.path.join(base_prefix, "lib")
        suffix_start = len(lib_dir) + 1

    if not os.path.isdir(lib_dir):
        return binaries

    re_mkllib = re.compile(r"^(?:lib)?mkl\w+\.(?:dll|so|dylib)", re.IGNORECASE)

    for f in os.listdir(lib_dir):
        if isWin32Windows():
            if not (f.startswith(
                ("libi", "libm", "mkl")) and f.endswith(".dll")):
                continue
        else:
            if not re_mkllib.match(f):
                continue

        binaries.append([os.path.join(lib_dir, f), suffix_start])

    return binaries
示例#14
0
def checkOnefileReadiness(assume_yes_for_downloads):
    if getOS() == "Linux":
        app_image_path = _getAppImageToolPath(
            for_operation=False, assume_yes_for_downloads=assume_yes_for_downloads
        )

        return app_image_path is not None
    else:
        return hasOnefileSupportedOS()
def checkPythonVersionFromCode(source_code):
    # There is a lot of cases to consider, pylint: disable=too-many-branches

    shebang = getShebangFromSource(source_code)

    if shebang is not None:
        binary, _args = parseShebang(shebang)

        if getOS() != "Windows":
            try:
                if os.path.samefile(sys.executable, binary):
                    return True
            except OSError:  # Might not exist
                pass

        basename = os.path.basename(binary)

        # Not sure if we should do that.
        if basename == "python":
            result = python_version < 0x300
        elif basename == "python3":
            result = python_version > 0x300
        elif basename == "python2":
            result = python_version < 0x300
        elif basename == "python2.7":
            result = python_version < 0x300
        elif basename == "python2.6":
            result = python_version < 0x270
        elif basename == "python3.2":
            result = 0x330 > python_version >= 0x300
        elif basename == "python3.3":
            result = 0x340 > python_version >= 0x330
        elif basename == "python3.4":
            result = 0x350 > python_version >= 0x340
        elif basename == "python3.5":
            result = 0x360 > python_version >= 0x350
        elif basename == "python3.6":
            result = 0x370 > python_version >= 0x360
        elif basename == "python3.7":
            result = 0x380 > python_version >= 0x370
        elif basename == "python3.8":
            result = 0x390 > python_version >= 0x380
        elif basename == "python3.9":
            result = 0x3A0 > python_version >= 0x390
        else:
            result = None

        if result is False:
            general.sysexit("""\
The program you compiled wants to be run with: %s.

Nuitka is currently running with Python version '%s', which seems to not
match that. Nuitka cannot guess the Python version of your source code. You
therefore might want to specify: '%s -m nuitka'.

That will make use the correct Python version for Nuitka.
""" % (shebang, python_version_str, binary))
示例#16
0
def checkPythonVersionFromCode(source_code):
    # There is a lot of cases to consider, pylint: disable=too-many-branches

    shebang = getShebangFromSource(source_code)

    if shebang is not None:
        binary, _args = parseShebang(shebang)

        if getOS() != "Windows":
            try:
                if os.path.samefile(sys.executable, binary):
                    return True
            except OSError:  # Might not exist
                pass

        basename = os.path.basename(binary)

        # Not sure if we should do that.
        if basename == "python":
            result = python_version < 300
        elif basename == "python3":
            result = python_version > 300
        elif basename == "python2":
            result = python_version < 300
        elif basename == "python2.7":
            result = python_version < 300
        elif basename == "python2.6":
            result = python_version < 270
        elif basename == "python3.2":
            result = 330 > python_version >= 300
        elif basename == "python3.3":
            result = 340 > python_version >= 330
        elif basename == "python3.4":
            result = 350 > python_version >= 340
        elif basename == "python3.5":
            result = 360 > python_version >= 350
        elif basename == "python3.6":
            result = 370 > python_version >= 360
        else:
            result = None

        if result is False:
            sys.exit(
                """\
The program you compiled wants to be run with: %s.

Nuitka is currently running with Python version '%s', which seems to not
match that. Nuitka cannot guess the Python version of your source code. You
therefore might want to specify: '%s -m nuitka'.

That will make use the correct Python version for Nuitka.
"""
                % (shebang, python_version_str, binary)
            )
示例#17
0
def relpath(path):
    """ Relative path, if possible. """

    try:
        return os.path.relpath(path)
    except ValueError:
        # On Windows, paths on different devices prevent it to work. Use that
        # full path then.
        if getOS() == "Windows":
            return os.path.abspath(path)
        raise
示例#18
0
    def considerExtraDlls(self, dist_dir, module):
        full_name = module.getFullName()

        if getOS() == "Linux" and full_name == "uuid":
            uuid_dll_path = locateDLL("uuid")
            dist_dll_path = joinpath(dist_dir, basename(uuid_dll_path))

            shutil.copy(uuid_dll_path, dist_dir)

            return ((dist_dll_path, None), )

        return ()
示例#19
0
def _pickCompressor():
    if Options.isExperimental("zstd"):
        try:
            from zstd import ZSTD_compress  # pylint: disable=I0021,import-error
        except ImportError:
            general.warning(
                "Onefile mode cannot compress without 'zstd' module on '%s'." % getOS()
            )
        else:
            return b"Y", lambda data: ZSTD_compress(data, 9, getJobLimit())
    else:
        return b"X", lambda data: data
示例#20
0
def _getCcacheGuessedPaths(python_prefix):
    if isWin32Windows():
        # Search the compiling Python, the Scons Python (likely the same, but not necessarily)
        # and then Anaconda, if an environment variable present from activated, or installed in
        # CI like Github actions.
        for python_dir in _getPythonDirCandidates(python_prefix):
            yield os.path.join(python_dir, "bin", "ccache.exe")
            yield os.path.join(python_dir, "scripts", "ccache.exe")

    elif getOS() == "Darwin":
        # For macOS, we might find Homebrew ccache installed but not in PATH.
        yield "/usr/local/opt/ccache"
示例#21
0
    def considerExtraDlls(self, dist_dir, module):
        full_name = module.getFullName()

        if full_name == "uuid" and getOS() == "Linux":
            uuid_dll_path = locateDLL("uuid")
            dist_dll_path = os.path.join(dist_dir, os.path.basename(uuid_dll_path))

            shutil.copy(uuid_dll_path, dist_dll_path)

            return ((uuid_dll_path, dist_dll_path, None),)

        return ()
示例#22
0
def packDistFolderToOnefileWindows(dist_dir):
    general.warning("Onefile mode is experimental on '%s'." % getOS())

    postprocessing_logger.info(
        "Creating single file from dist folder, this may take a while.")

    onefile_output_filename = getResultFullpath(onefile=True)

    # First need to create the bootstrap binary for unpacking.
    _runOnefileScons(quiet=not Options.isShowScons())

    # Make sure to copy the resources from the created binary to the bootstrap binary, these
    # are icons and version information.
    copyResourcesFromFileToFile(
        source_filename=getResultFullpath(onefile=False),
        target_filename=onefile_output_filename,
        resource_kinds=(RT_ICON, RT_GROUP_ICON, RT_VERSION),
    )

    # Now need to append to payload it, potentially compressing it.
    compression_indicator, compressor = _pickCompressor()

    with open(onefile_output_filename, "ab") as output_file:
        # Seeking to end of file seems necessary on Python2 at least, maybe it's
        # just that tell reports wrong value initially.
        output_file.seek(0, 2)

        start_pos = output_file.tell()

        output_file.write(b"KA" + compression_indicator)

        # Move the binary to start immediately to the start position
        start_binary = getResultFullpath(onefile=False)
        file_list = getFileList(dist_dir)
        file_list.remove(start_binary)
        file_list.insert(0, start_binary)

        for filename_full in file_list:
            filename_relative = os.path.relpath(filename_full, dist_dir)
            filename_encoded = filename_relative.encode("utf-16le") + b"\0\0"

            output_file.write(filename_encoded)

            with open(filename_full, "rb") as input_file:
                compressed = compressor(input_file.read())

                output_file.write(struct.pack("Q", len(compressed)))
                output_file.write(compressed)

        # Using empty filename as a terminator.
        output_file.write(b"\0\0")

        output_file.write(struct.pack("Q", start_pos))
示例#23
0
def autoformat(filename, abort=False):
    filename = os.path.normpath(filename)

    my_print("Consider", filename, end=": ")

    old_code = getFileContents(filename)

    is_python = _isPythonFile(filename)

    is_c = filename.endswith((".c", ".h"))

    # Some parts of Nuitka must not be re-formatted with black or clang-format
    # as they have different intentions.
    if _shouldNotFormatCode(filename):
        is_python = is_c = False

    # Work on a temporary copy
    tmp_filename = filename + ".tmp"
    shutil.copy(filename, tmp_filename)

    try:
        if is_python:
            _cleanupPyLintComments(tmp_filename, abort)
            _cleanupImportSortOrder(tmp_filename)

        if is_python:
            black_call = _getPythonBinaryCall("black")

            subprocess.call(black_call + ["-q", tmp_filename])
        elif is_c:
            _cleanupClangFormat(filename)
        else:
            _cleanupTrailingWhitespace(tmp_filename)

        if getOS() == "Windows":
            _cleanupWindowsNewlines(tmp_filename)

        changed = False
        if old_code != getFileContents(tmp_filename):
            my_print("Updated.")

            renameFile(tmp_filename, filename)

            changed = True
        else:
            my_print("OK.")

        return changed
    finally:
        if os.path.exists(tmp_filename):
            os.unlink(tmp_filename)
示例#24
0
    def getImplicitImports(self, module):
        # Dealing with OpenGL is a bit detailed, pylint: disable=too-many-branches
        if module.getFullName() == "OpenGL":
            opengl_infos = self.queryRuntimeInformationSingle(
                setup_codes="import OpenGL.plugins",
                value=
                "[(f.name, f.import_path) for f in OpenGL.plugins.FormatHandler.all()]",
            )

            # TODO: Filter by name.
            for _name, import_path in opengl_infos:
                yield ModuleName(import_path).getPackageName()

            for line in getFileContentByLine(module.getCompileTimeFilename()):
                if line.startswith("PlatformPlugin("):
                    os_part, plugin_name_part = line[15:-1].split(",")
                    os_part = os_part.strip("' ")
                    plugin_name_part = plugin_name_part.strip(") '")
                    plugin_name_part = plugin_name_part[:plugin_name_part.
                                                        rfind(".")]

                    if os_part == "nt":
                        if getOS() == "Windows":
                            yield plugin_name_part
                    elif os_part.startswith("linux"):
                        if isLinux():
                            yield plugin_name_part
                    elif os_part.startswith("darwin"):
                        if isMacOS():
                            yield plugin_name_part
                    elif os_part.startswith(("posix", "osmesa", "egl")):
                        if getOS() != "Windows":
                            yield plugin_name_part
                    else:
                        self.sysexit(
                            "Undetected OS, please report bug for '%s'." %
                            os_part)
示例#25
0
def checkPythonVersionFromCode(source_code):
    # There is a lot of cases to consider, pylint: disable=R0912

    shebang = getShebangFromSource(source_code)

    if shebang is not None:
        binary, _args = parseShebang(shebang)

        if getOS() != "Windows":
            try:
                if os.path.samefile(sys.executable, binary):
                    return True
            except OSError:  # Might not exist
                pass

        basename = os.path.basename(binary)

        # Not sure if we should do that.
        if basename == "python":
            result = python_version < 300
        elif basename == "python3":
            result = python_version > 300
        elif basename == "python2":
            result = python_version < 300
        elif basename == "python2.7":
            result = python_version < 300
        elif basename == "python2.6":
            result = python_version < 270
        elif basename == "python3.2":
            result = python_version < 330 and python_version >= 300
        elif basename == "python3.3":
            result = python_version < 340 and python_version >= 330
        elif basename == "python3.4":
            result = python_version < 350 and python_version >= 340
        elif basename == "python3.5":
            result = python_version < 360 and python_version >= 350
        elif basename == "python3.6":
            result = python_version < 370 and python_version >= 360
        else:
            result = None

        if result is False and Options.getIntendedPythonVersion() is None:
            sys.exit("""\
The program you compiled wants to be run with: %s.

Nuitka is currently running with Python version '%s', which seems to not
match that. Nuitka cannot guess the Python version of your source code. You
therefore might want to specify '--python-version=' to make it clear.
""" % (shebang, python_version_str))
示例#26
0
def shallUseStaticLibPython():
    """*bool* = derived from `sys.prefix` and `os.name`

    Notes:
        Currently only Anaconda on non-Windows can do this.
    """

    if isWin32Windows() and os.path.exists(
            os.path.join(sys.prefix, "etc/config.site")):
        return True

    # For Anaconda default to trying static lib python library, which
    # normally is just not available or if it is even unusable.
    return (os.path.exists(os.path.join(sys.prefix, "conda-meta"))
            and not isWin32Windows() and not getOS() == "Darwin")
示例#27
0
def getIconPaths():
    """*list of str*, values of "--windows-icon-from-ico" and "--linux-onefile-icon """

    result = options.icon_path

    # Check if Linux icon requirement is met.
    if getOS() == "Linux" and not result and isOnefileMode():
        default_icon = "/usr/share/pixmaps/python.xpm"
        if os.path.exists(default_icon):
            result.append(default_icon)
        else:
            Tracing.general.sysexit("""\
Error, the default icon %r does not exist, making --linux-onefile-icon required."""
                                    % default_icon)

    return result
示例#28
0
def getResultFullpath():
    """Get the final output binary result full path."""

    result = getResultBasepath()

    if Options.shallMakeModule():
        result += getSharedLibrarySuffix(preferred=True)
    else:
        if Options.getOutputFilename() is not None:
            result = Options.getOutputFilename()
        elif getOS() == "Windows":
            result += ".exe"
        elif not Options.isStandaloneMode():
            result += ".bin"

    return result
示例#29
0
def commentArgs():
    default_reference_mode = ("runtime" if shallMakeModule()
                              or isStandaloneMode() else "original")

    if getFileReferenceMode() is None:
        options.file_reference_mode = default_reference_mode
    else:
        if options.file_reference_mode != default_reference_mode:
            Tracing.options_logger.warning(
                "Using non-default file reference mode %r rather than %r may cause runtime issues."
                % (getFileReferenceMode(), default_reference_mode))
        else:
            Tracing.options_logger.info(
                "Using default file reference mode %r need not be specified." %
                default_reference_mode)

    if getOS() != "Windows":
        if (getWindowsIconExecutablePath() or shallAskForWindowsAdminRights()
                or shallAskForWindowsUIAccessRights()
                or getWindowsCompanyName() or getWindowsProductName()
                or getWindowsProductVersion() or getWindowsFileVersion()):
            Tracing.options_logger.warning(
                "Using Windows specific options has no effect.")

    if isOnefileMode():
        standalone_mode = "onefile"
    elif isStandaloneMode():
        standalone_mode = "standalone"
    else:
        standalone_mode = None

    if options.recurse_all and standalone_mode:
        if standalone_mode:
            Tracing.options_logger.info(
                "Recursing all is the default for %s mode and need not be specified."
                % standalone_mode)

    if options.recurse_none and standalone_mode:
        if standalone_mode:
            Tracing.options_logger.warning(
                "Recursing none is unlikely to work for %s mode and should not be specified."
                % standalone_mode)
示例#30
0
def getStandardLibraryPaths():
    """ Get the standard library paths.

    """

    # Using the function object to cache its result, avoiding global variable
    # usage.
    if not hasattr(getStandardLibraryPaths, "result"):
        os_filename = os.__file__
        if os_filename.endswith(".pyc"):
            os_filename = os_filename[:-1]

        os_path = os.path.normcase(os.path.dirname(os_filename))

        stdlib_paths = set([os_path])

        # Happens for virtualenv situation, some modules will come from the link
        # this points to.
        if os.path.islink(os_filename):
            os_filename = os.readlink(os_filename)
            stdlib_paths.add(os.path.normcase(os.path.dirname(os_filename)))

        # Another possibility is "orig-prefix.txt" file near the os.py, which
        # points to the original install.
        orig_prefix_filename = os.path.join(os_path, "orig-prefix.txt")

        if os.path.isfile(orig_prefix_filename):
            # Scan upwards, until we find a "bin" folder, with "activate" to
            # locate the structural path to be added. We do not know for sure
            # if there is a sub-directory under "lib" to use or not. So we try
            # to detect it.
            search = os_path
            lib_part = ""

            while os.path.splitdrive(search)[1] not in (os.path.sep, ""):
                if os.path.isfile(os.path.join(
                        search, "bin/activate")) or os.path.isfile(
                            os.path.join(search, "scripts/activate")):
                    break

                lib_part = os.path.join(os.path.basename(search), lib_part)

                search = os.path.dirname(search)

            assert search and lib_part

            with open(orig_prefix_filename) as f:
                stdlib_paths.add(
                    os.path.normcase(os.path.join(f.read(), lib_part)))

        # And yet another possibility, for macOS Homebrew created virtualenv
        # at least is a link ".Python", which points to the original install.
        python_link_filename = os.path.join(os_path, "..", ".Python")
        if os.path.islink(python_link_filename):
            stdlib_paths.add(
                os.path.normcase(
                    os.path.join(os.readlink(python_link_filename), "lib")))

        for stdlib_path in set(stdlib_paths):
            candidate = os.path.join(stdlib_path, "lib-tk")

            if os.path.isdir(candidate):
                stdlib_paths.add(candidate)

        if getOS() == "Windows":
            import _ctypes

            stdlib_paths.add(os.path.dirname(_ctypes.__file__))

        getStandardLibraryPaths.result = [
            os.path.normcase(os.path.normpath(stdlib_path))
            for stdlib_path in stdlib_paths
        ]

    return getStandardLibraryPaths.result
示例#31
0
    def getImplicitImports(self, module):
        # Many variables, branches, due to the many cases, pylint: disable=too-many-branches,too-many-statements
        full_name = module.getFullName()

        if module.isPythonShlibModule():
            for used_module in module.getUsedModules():
                yield used_module[0], False

        # TODO: Move this out to some kind of configuration format.
        elements = full_name.split(".")

        if elements[0] in ("PyQt4", "PyQt5"):
            if python_version < 300:
                yield "atexit", True

            # These are alternatives now:
            # TODO: One day it should avoid including both.
            yield "sip", False
            if elements[0] == "PyQt5":
                yield "PyQt5.sip", False

            child = elements[1] if len(elements) > 1 else None

            if child in (
                "QtGui",
                "QtAssistant",
                "QtDBus",
                "QtDeclarative",
                "QtSql",
                "QtDesigner",
                "QtHelp",
                "QtNetwork",
                "QtScript",
                "QtQml",
                "QtScriptTools",
                "QtSvg",
                "QtTest",
                "QtWebKit",
                "QtOpenGL",
                "QtXml",
                "QtXmlPatterns",
                "QtPrintSupport",
                "QtNfc",
                "QtWebKitWidgets",
                "QtBluetooth",
                "QtMultimediaWidgets",
                "QtQuick",
                "QtWebChannel",
                "QtWebSockets",
                "QtX11Extras",
                "_QOpenGLFunctions_2_0",
                "_QOpenGLFunctions_2_1",
                "_QOpenGLFunctions_4_1_Core",
            ):
                yield elements[0] + ".QtCore", True

            if child in (
                "QtDeclarative",
                "QtWebKit",
                "QtXmlPatterns",
                "QtQml",
                "QtPrintSupport",
                "QtWebKitWidgets",
                "QtMultimedia",
                "QtMultimediaWidgets",
                "QtQuick",
                "QtQuickWidgets",
                "QtWebSockets",
            ):
                yield elements[0] + ".QtNetwork", True

            if child == "QtScriptTools":
                yield elements[0] + ".QtScript", True

            if child in (
                "QtWidgets",
                "QtDeclarative",
                "QtDesigner",
                "QtHelp",
                "QtScriptTools",
                "QtSvg",
                "QtTest",
                "QtWebKit",
                "QtPrintSupport",
                "QtWebKitWidgets",
                "QtMultimedia",
                "QtMultimediaWidgets",
                "QtOpenGL",
                "QtQuick",
                "QtQuickWidgets",
                "QtSql",
                "_QOpenGLFunctions_2_0",
                "_QOpenGLFunctions_2_1",
                "_QOpenGLFunctions_4_1_Core",
            ):
                yield elements[0] + ".QtGui", True

            if full_name in (
                "PyQt5.QtDesigner",
                "PyQt5.QtHelp",
                "PyQt5.QtTest",
                "PyQt5.QtPrintSupport",
                "PyQt5.QtSvg",
                "PyQt5.QtOpenGL",
                "PyQt5.QtWebKitWidgets",
                "PyQt5.QtMultimediaWidgets",
                "PyQt5.QtQuickWidgets",
                "PyQt5.QtSql",
            ):
                yield "PyQt5.QtWidgets", True

            if full_name in ("PyQt5.QtPrintSupport",):
                yield "PyQt5.QtSvg", True

            if full_name in ("PyQt5.QtWebKitWidgets",):
                yield "PyQt5.QtWebKit", True
                yield "PyQt5.QtPrintSupport", True

            if full_name in ("PyQt5.QtMultimediaWidgets",):
                yield "PyQt5.QtMultimedia", True

            if full_name in ("PyQt5.QtQuick", "PyQt5.QtQuickWidgets"):
                yield "PyQt5.QtQml", True

            if full_name in ("PyQt5.QtQuickWidgets", "PyQt5.QtQml"):
                yield "PyQt5.QtQuick", True

            if full_name == "PyQt5.Qt":
                yield "PyQt5.QtCore", True
                yield "PyQt5.QtDBus", True
                yield "PyQt5.QtGui", True
                yield "PyQt5.QtNetwork", True
                yield "PyQt5.QtNetworkAuth", False
                yield "PyQt5.QtSensors", False
                yield "PyQt5.QtSerialPort", False
                yield "PyQt5.QtMultimedia", True
                yield "PyQt5.QtQml", False
                yield "PyQt5.QtWidgets", True
        elif full_name == "sip" and python_version < 300:
            yield "enum", False
        elif full_name == "PySide.QtDeclarative":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtHelp":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtOpenGL":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtScriptTools":
            yield "PySide.QtScript", True
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtSql":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtSvg":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtTest":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtUiTools":
            yield "PySide.QtGui", True
            yield "PySide.QtXml", True
        elif full_name == "PySide.QtWebKit":
            yield "PySide.QtGui", True
        elif full_name == "PySide.phonon":
            yield "PySide.QtGui", True
        elif full_name == "lxml.etree":
            yield "gzip", True
            yield "lxml._elementpath", True
        elif full_name == "gtk._gtk":
            yield "pangocairo", True
            yield "pango", True
            yield "cairo", True
            yield "gio", True
            yield "atk", True
        elif full_name == "atk":
            yield "gobject", True
        elif full_name == "gtkunixprint":
            yield "gobject", True
            yield "cairo", True
            yield "gtk", True
        elif full_name == "pango":
            yield "gobject", True
        elif full_name == "pangocairo":
            yield "pango", True
            yield "cairo", True
        elif full_name == "reportlab.rl_config":
            yield "reportlab.rl_settings", True
        elif full_name == "socket":
            yield "_socket", False
        elif full_name == "ctypes":
            yield "_ctypes", True
        elif full_name == "gi._gi":
            yield "gi._error", True
        elif full_name == "gi._gi_cairo":
            yield "cairo", True
        elif full_name == "cairo._cairo":
            yield "gi._gobject", False
        elif full_name in ("Tkinter", "tkinter"):
            yield "_tkinter", False
        elif full_name in (
            "cryptography.hazmat.bindings._openssl",
            "cryptography.hazmat.bindings._constant_time",
            "cryptography.hazmat.bindings._padding",
        ):
            yield "_cffi_backend", True
        elif full_name.startswith("cryptography._Cryptography_cffi_"):
            yield "_cffi_backend", True
        elif full_name == "bcrypt._bcrypt":
            yield "_cffi_backend", True
        elif full_name == "nacl._sodium":
            yield "_cffi_backend", True
        elif full_name == "_dbus_glib_bindings":
            yield "_dbus_bindings", True
        elif full_name == "_mysql":
            yield "_mysql_exceptions", True
        elif full_name == "lxml.objectify":
            yield "lxml.etree", True
        elif full_name == "_yaml":
            yield "yaml", True
        elif full_name == "apt_inst":
            yield "apt_pkg", True
        elif full_name == "numpy.core":
            yield "numpy.core._dtype_ctypes", False
        elif full_name == "scipy.special":
            yield "scipy.special._ufuncs_cxx", False
        elif full_name == "scipy.linalg":
            yield "scipy.linalg.cython_blas", False
            yield "scipy.linalg.cython_lapack", False
        elif full_name == "PIL._imagingtk":
            yield "PIL._tkinter_finder", True
        elif full_name == "pkg_resources.extern":
            if self.pkg_utils_externals is None:
                for line in getFileContentByLine(module.getCompileTimeFilename()):
                    if line.startswith("names"):
                        line = line.split("=")[-1].strip()
                        parts = line.split(",")

                        self.pkg_utils_externals = [part.strip("' ") for part in parts]

                        break
                else:
                    self.pkg_utils_externals = ()

            for pkg_util_external in self.pkg_utils_externals:
                yield "pkg_resources._vendor." + pkg_util_external, False
        elif full_name == "pkg_resources._vendor.packaging":
            yield "pkg_resources._vendor.packaging.version", True
            yield "pkg_resources._vendor.packaging.specifiers", True
            yield "pkg_resources._vendor.packaging.requirements", True
        elif full_name == "uvloop.loop":
            yield "uvloop._noop", True
        elif full_name == "fitz.fitz":
            yield "fitz._fitz", True
        elif full_name == "pandas._libs":
            yield "pandas._libs.tslibs.np_datetime", False
            yield "pandas._libs.tslibs.nattype", False
        elif full_name == "pandas.core.window":
            yield "pandas._libs.skiplist", False
        elif full_name == "zmq.backend":
            yield "zmq.backend.cython", True
        elif full_name == "OpenGL":
            if self.opengl_plugins is None:
                self.opengl_plugins = []

                for line in getFileContentByLine(module.getCompileTimeFilename()):
                    if line.startswith("PlatformPlugin("):
                        os_part, plugin_name_part = line[15:-1].split(",")
                        os_part = os_part.strip("' ")
                        plugin_name_part = plugin_name_part.strip(") '")
                        plugin_name_part = plugin_name_part[
                            : plugin_name_part.rfind(".")
                        ]
                        if os_part == "nt":
                            if getOS() == "Windows":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith("linux"):
                            if getOS() == "Linux":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith("darwin"):
                            if getOS() == "Darwin":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith(("posix", "osmesa", "egl")):
                            if getOS() != "Windows":
                                self.opengl_plugins.append(plugin_name_part)
                        else:
                            assert False, os_part

            for opengl_plugin in self.opengl_plugins:
                yield opengl_plugin, True
        elif full_name == "Cryptodome.Util._raw_api":
            for module_name in (
                "_raw_aes",
                "_raw_aesni",
                "_raw_arc2",
                "_raw_blowfish",
                "_raw_cast",
                "_raw_cbc",
                "_raw_cfb",
                "_raw_ctr",
                "_raw_des",
                "_raw_des3",
                "_raw_ecb",
                "_raw_ocb",
                "_raw_ofb",
            ):
                yield "Cryptodome.Cipher." + module_name, True
        elif full_name == "Cryptodome.Util.strxor":
            yield "Cryptodome.Util._strxor", True
        elif full_name == "Cryptodome.Util._cpu_features":
            yield "Cryptodome.Util._cpuid_c", True
        elif full_name == "Cryptodome.Hash.BLAKE2s":
            yield "Cryptodome.Hash._BLAKE2s", True
        elif full_name == "Cryptodome.Hash.SHA1":
            yield "Cryptodome.Hash._SHA1", True
        elif full_name == "Cryptodome.Hash.SHA256":
            yield "Cryptodome.Hash._SHA256", True
        elif full_name == "Cryptodome.Hash.MD5":
            yield "Cryptodome.Hash._MD5", True
        elif full_name == "Cryptodome.Protocol.KDF":
            yield "Cryptodome.Cipher._Salsa20", True
            yield "Cryptodome.Protocol._scrypt", True
        elif full_name == "Cryptodome.Cipher._mode_gcm":
            yield "Cryptodome.Hash._ghash_portable", True
        elif full_name == "pycparser.c_parser":
            yield "pycparser.yacctab", True
            yield "pycparser.lextab", True
示例#32
0
def main():
    goHome()

    parser = OptionParser()

    parser.add_option(
        "--upload",
        action="store_true",
        dest="upload",
        default=False,
        help="""\
Upload to http://nuitka.net/apidoc requires access rights and is done by the
official servers automatically only. Without this, create the local html folder
only.

Default is %default.""",
    )

    options, _positional_args = parser.parse_args()

    shutil.rmtree("html", ignore_errors=True)

    doxygen_path = getExecutablePath("doxygen")

    # Extra ball on Windows, check default installation PATH too.
    if not doxygen_path and getOS() == "Windows":
        with withEnvironmentPathAdded("PATH", r"C:\Program Files\Doxygen\bin"):
            doxygen_path = getExecutablePath("doxygen")

    if not doxygen_path:
        sys.exit("Error, need to install Doxygen and add it to PATH for this to work.")

    try:
        import doxypypy  # @UnusedImport pylint: disable=I0021,unused-import,unused-variable
    except ImportError:
        sys.exit("Error, needs to install doxypypy into this Python.")

    with withTemporaryFile(suffix=".doxyfile", delete=False) as doxy_file:
        doxy_config = getFileContents("doc/Doxyfile.template")

        with withTemporaryFile(
            suffix=".bat" if getOS() == "Windows" else ".sh", delete=False
        ) as doxy_batch_file:
            if getOS() == "Windows":
                doxy_batch_file.write(
                    "%s -m doxypypy.doxypypy -a -c %%1" % sys.executable
                )
            else:
                doxy_batch_file.write(
                    "#!/bin/sh\nexec '%s' -m doxypypy.doxypypy -a -c $1"
                    % sys.executable
                )

        doxy_batch_filename = doxy_batch_file.name

        doxy_config = doxy_config.replace("%DOXYPYPY%", doxy_batch_filename)
        doxy_file.write(doxy_config)

        doxy_filename = doxy_file.name

    print("Running doxygen:")
    try:
        subprocess.check_call([doxygen_path, doxy_filename])
    finally:
        os.unlink(doxy_filename)
        os.unlink(doxy_batch_filename)

    # Update the repository on the web site.
    if options.upload:
        assert (
            os.system(
                "rsync -avz --delete html/ --chown www-data [email protected]:/var/www/apidoc/"
            )
            == 0
        )

    print("Finished.")
示例#33
0
def getStandardLibraryPaths():
    """ Get the standard library paths.

    """

    # Using the function object to cache its result, avoiding global variable
    # usage.
    if not hasattr(getStandardLibraryPaths, "result"):
        os_filename = os.__file__
        if os_filename.endswith(".pyc"):
            os_filename = os_filename[:-1]

        os_path = os.path.normcase(os.path.dirname(os_filename))

        stdlib_paths = set([os_path])

        # Happens for virtualenv situation, some modules will come from the link
        # this points to.
        if os.path.islink(os_filename):
            os_filename = os.readlink(os_filename)  # @UndefinedVariable
            stdlib_paths.add(os.path.normcase(os.path.dirname(os_filename)))

        # Another possibility is "orig-prefix.txt" file near the os.py, which
        # points to the original install.
        orig_prefix_filename = os.path.join(os_path, "orig-prefix.txt")

        if os.path.isfile(orig_prefix_filename):
            # Scan upwards, until we find a "bin" folder, with "activate" to
            # locate the structural path to be added. We do not know for sure
            # if there is a sub-directory under "lib" to use or not. So we try
            # to detect it.
            search = os_path
            lib_part = ""

            while os.path.splitdrive(search)[1] not in (os.path.sep, ""):
                if os.path.isfile(
                    os.path.join(search, "bin/activate")
                ) or os.path.isfile(os.path.join(search, "scripts/activate")):
                    break

                lib_part = os.path.join(os.path.basename(search), lib_part)

                search = os.path.dirname(search)

            assert search and lib_part

            with open(orig_prefix_filename) as f:
                stdlib_paths.add(os.path.normcase(os.path.join(f.read(), lib_part)))

        # And yet another possibility, for macOS Homebrew created virtualenv
        # at least is a link ".Python", which points to the original install.
        python_link_filename = os.path.join(os_path, "..", ".Python")
        if os.path.islink(python_link_filename):
            stdlib_paths.add(
                os.path.normcase(
                    os.path.join(
                        os.readlink(python_link_filename), "lib"  # @UndefinedVariable
                    )
                )
            )

        for stdlib_path in set(stdlib_paths):
            candidate = os.path.join(stdlib_path, "lib-tk")

            if os.path.isdir(candidate):
                stdlib_paths.add(candidate)

        if getOS() == "Windows":
            import _ctypes

            stdlib_paths.add(os.path.dirname(_ctypes.__file__))

        getStandardLibraryPaths.result = [
            os.path.normcase(os.path.normpath(stdlib_path))
            for stdlib_path in stdlib_paths
        ]

    return getStandardLibraryPaths.result
示例#34
0
parser.add_option_group(codegen_group)

output_group = OptionGroup(parser, "Output choices")

output_group.add_option(
    "-o",
    action="store",
    dest="output_filename",
    metavar="FILENAME",
    default=None,
    help="""\
Specify how the executable should be named. For extension modules there is no
choice, also not for standalone mode and using it will be an error. This may
include path information that needs to exist though. Defaults to '%s' on this
platform.
""" % "<program_name>" + (".exe" if getOS() == "Windows" else ".bin"),
)

output_group.add_option(
    "--output-dir",
    action="store",
    dest="output_dir",
    metavar="DIRECTORY",
    default="",
    help="""\
Specify where intermediate and final output files should be put. The DIRECTORY
will be populated with C files, object files, etc.
Defaults to current directory.
""",
)
示例#35
0
    def getImplicitImports(self, module):
        # Many variables, branches, due to the many cases, pylint: disable=too-many-branches,too-many-statements
        full_name = module.getFullName()

        if module.isPythonShlibModule():
            for used_module in module.getUsedModules():
                yield used_module[0], False

        # TODO: Move this out to some kind of configuration format.
        elements = full_name.split('.')

        if elements[0] in ("PyQt4", "PyQt5"):
            if python_version < 300:
                yield "atexit", True

            # These are alternatives now:
            # TODO: One day it should avoid including both.
            yield "sip", False
            if elements[0] == "PyQt5":
                yield "PyQt5.sip", False

            child = elements[1] if len(elements) > 1 else None

            if child in ("QtGui", "QtAssistant", "QtDBus", "QtDeclarative",
                         "QtSql", "QtDesigner", "QtHelp", "QtNetwork",
                         "QtScript", "QtQml", "QtScriptTools", "QtSvg",
                         "QtTest", "QtWebKit", "QtOpenGL", "QtXml",
                         "QtXmlPatterns", "QtPrintSupport", "QtNfc",
                         "QtWebKitWidgets", "QtBluetooth",
                         "QtMultimediaWidgets", "QtQuick", "QtWebChannel",
                         "QtWebSockets", "QtX11Extras",
                         "_QOpenGLFunctions_2_0", "_QOpenGLFunctions_2_1",
                         "_QOpenGLFunctions_4_1_Core"):
                yield elements[0] + ".QtCore", True

            if child in ("QtDeclarative", "QtWebKit", "QtXmlPatterns", "QtQml",
                         "QtPrintSupport", "QtWebKitWidgets", "QtMultimedia",
                         "QtMultimediaWidgets", "QtQuick", "QtQuickWidgets",
                         "QtWebSockets"):
                yield elements[0] + ".QtNetwork", True

            if child == "QtScriptTools":
                yield elements[0] + ".QtScript", True

            if child in ("QtWidgets", "QtDeclarative", "QtDesigner", "QtHelp",
                         "QtScriptTools", "QtSvg", "QtTest", "QtWebKit",
                         "QtPrintSupport", "QtWebKitWidgets", "QtMultimedia",
                         "QtMultimediaWidgets", "QtOpenGL", "QtQuick",
                         "QtQuickWidgets", "QtSql", "_QOpenGLFunctions_2_0",
                         "_QOpenGLFunctions_2_1",
                         "_QOpenGLFunctions_4_1_Core"):
                yield elements[0] + ".QtGui", True

            if full_name in ("PyQt5.QtDesigner", "PyQt5.QtHelp",
                             "PyQt5.QtTest", "PyQt5.QtPrintSupport",
                             "PyQt5.QtSvg", "PyQt5.QtOpenGL",
                             "PyQt5.QtWebKitWidgets",
                             "PyQt5.QtMultimediaWidgets",
                             "PyQt5.QtQuickWidgets", "PyQt5.QtSql"):
                yield "PyQt5.QtWidgets", True

            if full_name in ("PyQt5.QtPrintSupport", ):
                yield "PyQt5.QtSvg", True

            if full_name in ("PyQt5.QtWebKitWidgets", ):
                yield "PyQt5.QtWebKit", True
                yield "PyQt5.QtPrintSupport", True

            if full_name in ("PyQt5.QtMultimediaWidgets", ):
                yield "PyQt5.QtMultimedia", True

            if full_name in ("PyQt5.QtQuick", "PyQt5.QtQuickWidgets"):
                yield "PyQt5.QtQml", True

            if full_name in ("PyQt5.QtQuickWidgets", "PyQt5.QtQml"):
                yield "PyQt5.QtQuick", True

            if full_name == "PyQt5.Qt":
                yield "PyQt5.QtCore", True
                yield "PyQt5.QtDBus", True
                yield "PyQt5.QtGui", True
                yield "PyQt5.QtNetwork", True
                yield "PyQt5.QtNetworkAuth", False
                yield "PyQt5.QtSensors", False
                yield "PyQt5.QtSerialPort", False
                yield "PyQt5.QtMultimedia", True
                yield "PyQt5.QtQml", False
                yield "PyQt5.QtWidgets", True
        elif full_name == "sip" and python_version < 300:
            yield "enum", False
        elif full_name == "PySide.QtDeclarative":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtHelp":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtOpenGL":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtScriptTools":
            yield "PySide.QtScript", True
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtSql":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtSvg":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtTest":
            yield "PySide.QtGui", True
        elif full_name == "PySide.QtUiTools":
            yield "PySide.QtGui", True
            yield "PySide.QtXml", True
        elif full_name == "PySide.QtWebKit":
            yield "PySide.QtGui", True
        elif full_name == "PySide.phonon":
            yield "PySide.QtGui", True
        elif full_name == "lxml.etree":
            yield "gzip", True
            yield "lxml._elementpath", True
        elif full_name == "gtk._gtk":
            yield "pangocairo", True
            yield "pango", True
            yield "cairo", True
            yield "gio", True
            yield "atk", True
        elif full_name == "atk":
            yield "gobject", True
        elif full_name == "gtkunixprint":
            yield "gobject", True
            yield "cairo", True
            yield "gtk", True
        elif full_name == "pango":
            yield "gobject", True
        elif full_name == "pangocairo":
            yield "pango", True
            yield "cairo", True
        elif full_name == "reportlab.rl_config":
            yield "reportlab.rl_settings", True
        elif full_name == "socket":
            yield "_socket", False
        elif full_name == "ctypes":
            yield "_ctypes", True
        elif full_name == "gi._gi":
            yield "gi._error", True
        elif full_name == "gi._gi_cairo":
            yield "cairo", True
        elif full_name == "cairo._cairo":
            yield "gi._gobject", False
        elif full_name in ("Tkinter", "tkinter"):
            yield "_tkinter", False
        elif full_name in ("cryptography.hazmat.bindings._openssl",
                           "cryptography.hazmat.bindings._constant_time",
                           "cryptography.hazmat.bindings._padding"):
            yield "_cffi_backend", True
        elif full_name.startswith("cryptography._Cryptography_cffi_"):
            yield "_cffi_backend", True
        elif full_name == "bcrypt._bcrypt":
            yield "_cffi_backend", True
        elif full_name == "nacl._sodium":
            yield "_cffi_backend", True
        elif full_name == "_dbus_glib_bindings":
            yield "_dbus_bindings", True
        elif full_name == "_mysql":
            yield "_mysql_exceptions", True
        elif full_name == "lxml.objectify":
            yield "lxml.etree", True
        elif full_name == "_yaml":
            yield "yaml", True
        elif full_name == "apt_inst":
            yield "apt_pkg", True
        elif full_name == "PIL._imagingtk":
            yield "PIL._tkinter_finder", True
        elif full_name == "pkg_resources.extern":
            if self.pkg_utils_externals is None:
                for line in open(module.getCompileTimeFilename()):
                    if line.startswith("names"):
                        line = line.split('=')[-1].strip()
                        parts = line.split(',')

                        self.pkg_utils_externals = [
                            part.strip("' ") for part in parts
                        ]

                        break
                else:
                    self.pkg_utils_externals = ()

            for pkg_util_external in self.pkg_utils_externals:
                yield "pkg_resources._vendor." + pkg_util_external, False
        elif full_name == "pkg_resources._vendor.packaging":
            yield "pkg_resources._vendor.packaging.version", True
            yield "pkg_resources._vendor.packaging.specifiers", True
            yield "pkg_resources._vendor.packaging.requirements", True
        elif full_name == "uvloop.loop":
            yield "uvloop._noop", True
        elif full_name == "fitz.fitz":
            yield "fitz._fitz", True
        elif full_name == "pandas._libs":
            yield "pandas._libs.tslibs.np_datetime", False
            yield "pandas._libs.tslibs.nattype", False
        elif full_name == "pandas.core.window":
            yield "pandas._libs.skiplist", False
        elif full_name == "zmq.backend":
            yield "zmq.backend.cython", True
        elif full_name == "OpenGL":
            if self.opengl_plugins is None:
                self.opengl_plugins = []

                for line in open(module.getCompileTimeFilename()):
                    if line.startswith("PlatformPlugin("):
                        os_part, plugin_name_part = line[15:-1].split(',')
                        os_part = os_part.strip("' ")
                        plugin_name_part = plugin_name_part.strip(") '")
                        plugin_name_part = plugin_name_part[:plugin_name_part.
                                                            rfind('.')]
                        if os_part == "nt":
                            if getOS() == "Windows":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith("linux"):
                            if getOS() == "Linux":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith("darwin"):
                            if getOS() == "MacOS":
                                self.opengl_plugins.append(plugin_name_part)
                        elif os_part.startswith(("posix", "osmesa", "egl")):
                            if getOS() != "Windows":
                                self.opengl_plugins.append(plugin_name_part)
                        else:
                            assert False, os_part

            for opengl_plugin in self.opengl_plugins:
                yield opengl_plugin, True