示例#1
0
    def _readPyPIFile(self):
        """ Read the .pyi file if present and scan for dependencies. """

        if self.used_modules is None:
            pyi_filename = self.getPyIFilename()

            if os.path.exists(pyi_filename):
                pyi_deps = OrderedSet()

                for line in open(pyi_filename):
                    line = line.strip()

                    if line.startswith("import "):
                        imported = line[7:]

                        pyi_deps.add(imported)
                    elif line.startswith("from "):
                        parts = line.split(None, 3)
                        assert parts[0] == "from"
                        assert parts[2] == "import"

                        if parts[1] == "typing":
                            continue

                        pyi_deps.add(parts[1])

                        imported = parts[3]
                        if imported.startswith('('):
                            # No multiline imports please
                            assert imported.endswith(')')
                            imported = imported[1:-1]

                            assert imported

                        if imported == '*':
                            continue

                        for name in imported.split(','):
                            name = name.strip()

                            pyi_deps.add(parts[1] + '.' + name)

                if "typing" in pyi_deps:
                    pyi_deps.discard("typing")

                self.used_modules = tuple(
                    (pyi_dep, None)
                    for pyi_dep in
                    pyi_deps
                )
            else:
                self.used_modules = ()
示例#2
0
    def _readPyPIFile(self):
        """ Read the .pyi file if present and scan for dependencies. """

        if self.used_modules is None:
            pyi_filename = self.getPyIFilename()

            if os.path.exists(pyi_filename):
                pyi_deps = OrderedSet()

                for line in getFileContentByLine(pyi_filename):
                    line = line.strip()

                    if line.startswith("import "):
                        imported = line[7:]

                        pyi_deps.add(imported)
                    elif line.startswith("from "):
                        parts = line.split(None, 3)
                        assert parts[0] == "from"
                        assert parts[2] == "import"

                        if parts[1] == "typing":
                            continue

                        pyi_deps.add(parts[1])

                        imported = parts[3]
                        if imported.startswith("("):
                            # No multiline imports please
                            assert imported.endswith(")")
                            imported = imported[1:-1]

                            assert imported

                        if imported == "*":
                            continue

                        for name in imported.split(","):
                            name = name.strip()

                            pyi_deps.add(parts[1] + "." + name)

                if "typing" in pyi_deps:
                    pyi_deps.discard("typing")

                self.used_modules = tuple((pyi_dep, None) for pyi_dep in pyi_deps)
            else:
                self.used_modules = ()
示例#3
0
    def _readPyPIFile(self):
        """ Read the .pyi file if present and scan for dependencies. """

        # Complex stuff, pylint: disable=too-many-branches,too-many-statements

        if self.used_modules is None:
            pyi_filename = self.getPyIFilename()

            if os.path.exists(pyi_filename):
                pyi_deps = OrderedSet()

                # Flag signalling multiline import handling
                in_import = False
                in_import_part = ""

                for line in getFileContentByLine(pyi_filename):
                    line = line.strip()

                    if not in_import:
                        if line.startswith("import "):
                            imported = line[7:]

                            pyi_deps.add(imported)
                        elif line.startswith("from "):
                            parts = line.split(None, 3)
                            assert parts[0] == "from"
                            assert parts[2] == "import"

                            origin_name = parts[1]

                            if origin_name == "typing":
                                continue

                            if origin_name == ".":
                                origin_name = self.getFullName()

                            # TODO: Might want to add full relative import handling.

                            if origin_name != self.getFullName():
                                pyi_deps.add(origin_name)

                            imported = parts[3]
                            if imported.startswith("("):
                                # Handle multiline imports
                                if not imported.endswith(")"):
                                    in_import = True
                                    imported = imported[1:]
                                    in_import_part = origin_name
                                    assert in_import_part, (
                                        "Multiline part in file %s cannot be empty"
                                        % pyi_filename)
                                else:
                                    in_import = False
                                    imported = imported[1:-1]
                                    assert imported

                            if imported == "*":
                                continue

                            for name in imported.split(","):
                                if name:
                                    name = name.strip()
                                    pyi_deps.add(origin_name + "." + name)

                    else:  # In import
                        imported = line
                        if imported.endswith(")"):
                            imported = imported[0:-1]
                            in_import = False

                        for name in imported.split(","):
                            name = name.strip()
                            if name:
                                pyi_deps.add(in_import_part + "." + name)

                if "typing" in pyi_deps:
                    pyi_deps.discard("typing")
                if "__future__" in pyi_deps:
                    pyi_deps.discard("__future__")

                if self.getFullName() in pyi_deps:
                    pyi_deps.discard(self.getFullName())
                if self.getFullName().getPackageName() in pyi_deps:
                    pyi_deps.discard(self.getFullName().getPackageName())

                self.used_modules = tuple(
                    (pyi_dep, None) for pyi_dep in pyi_deps)
            else:
                self.used_modules = ()
示例#4
0
def _parsePEFileOutput(
    binary_filename,
    scan_dirs,
    is_main_executable,
    source_dir,
    original_dir,
    use_cache,
    update_cache,
):
    # This is complex, as it also includes the caching mechanism
    # pylint: disable=too-many-branches,too-many-locals

    result = OrderedSet()

    if use_cache or update_cache:
        cache_filename = _getCacheFilename(
            dependency_tool="pefile",
            is_main_executable=is_main_executable,
            source_dir=source_dir,
            original_dir=original_dir,
            binary_filename=binary_filename,
        )

        if use_cache:
            with withFileLock():
                if not os.path.exists(cache_filename):
                    use_cache = False

    if use_cache:

        # TODO: We are lazy with the format, pylint: disable=eval-used
        extracted = eval(getFileContents(cache_filename))
    else:
        if Options.isShowProgress():
            info("Analysing dependencies of '%s'." % binary_filename)

        extracted = getPEFileInformation(binary_filename)

    if update_cache:
        with withFileLock():
            with open(cache_filename, "w") as cache_file:
                print(repr(extracted), file=cache_file)

    # Add native system directory based on pe file architecture and os architecture
    # Python 32: system32 = syswow64 = 32 bits systemdirectory
    # Python 64: system32 = 64 bits systemdirectory, syswow64 = 32 bits systemdirectory

    # Get DLL imports from PE file
    for dll_name in extracted["DLLs"]:
        dll_name = dll_name.upper()

        # Try determine DLL path from scan dirs
        for scan_dir in scan_dirs:
            dll_filename = os.path.normcase(
                os.path.abspath(os.path.join(scan_dir, dll_name))
            )

            if os.path.isfile(dll_filename):
                break
        else:
            if dll_name.startswith("API-MS-WIN-") or dll_name.startswith("EXT-MS-WIN-"):
                continue
            # Found via RC_MANIFEST as copied from Python.
            if dll_name == "MSVCR90.DLL":
                continue

            if dll_name.startswith("python") and dll_name.endswith(".dll"):
                dll_filename = os.path.join(
                    os.environ["SYSTEMROOT"],
                    "SysWOW64" if getArchitecture() == "x86_64" else "System32",
                    dll_name,
                )
                dll_filename = os.path.normcase(dll_filename)
            else:
                continue

        if dll_filename not in result:
            result.add(dll_filename)

    # TODO: Shouldn't be here.
    blocked = Plugins.removeDllDependencies(
        dll_filename=binary_filename, dll_filenames=result
    )

    for to_remove in blocked:
        result.discard(to_remove)

    return result