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 = ()
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 = ()
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 = ()
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