def __init__(self, xpath=None, hookspath=None, excludes=None): self.path = [] self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() # RegistryImportDirector is necessary only on Windows. if is_win: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.RegistryImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] else: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes)
def __init__(self, xpath=None, hookspath=None, excludes=None): self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes)
class ImportTrackerModulegraph: """ New import tracker based on module 'modulegraph' for resolving dependencies on Python modules. PyInstaller is not able to handle some cases of resolving dependencies. Rather try use a module for that than trying to fix current implementation. Public api: self.analyze_scripts() self.getwarnings() """ def __init__(self, xpath=None, hookspath=None, excludes=None): self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes) def analyze_script(self, filenames): """ Analyze given scripts and get dependencies on other Python modules. return two lists - python modules and python extensions """ from modulegraph.find_modules import find_modules, parse_mf_results mf = find_modules(filenames, excludes=self.excludes) py_files, extensions = parse_mf_results(mf) return py_files, extensions def getwarnings(self): warnings = self.warnings.keys() for nm, mod in self.modules.items(): if mod: for w in mod.warnings: warnings.append(w + ' - %s (%s)' % (mod.__name__, mod.__file__)) return warnings
class ImportTracker: # really the equivalent of builtin import def __init__(self, xpath=None, hookspath=None, excludes=None): self.path = [] self.warnings = {} if xpath: self.path = xpath self.path.extend(sys.path) self.modules = LogDict() # RegistryImportDirector is necessary only on Windows. if is_win: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.RegistryImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] else: self.metapath = [ PyInstaller.depend.impdirector.BuiltinImportDirector(), PyInstaller.depend.impdirector.PathImportDirector(self.path) ] if hookspath: hooks.__path__.extend(hookspath) if excludes is None: self.excludes = set() else: self.excludes = set(excludes) def analyze_r(self, nm, importernm=None): importer = importernm if importer is None: importer = '__main__' seen = {} nms = self.analyze_one(nm, importernm) nms = map(None, nms, [importer] * len(nms)) i = 0 while i < len(nms): nm, importer = nms[i] if seen.get(nm, 0): del nms[i] mod = self.modules[nm] if mod: mod.xref(importer) else: i = i + 1 seen[nm] = 1 j = i mod = self.modules[nm] if mod: mod.xref(importer) for name, isdelayed, isconditional, level in mod.imports: imptyp = isdelayed * 2 + isconditional newnms = self.analyze_one(name, nm, imptyp, level) newnms = map(None, newnms, [nm] * len(newnms)) nms[j:j] = newnms j = j + len(newnms) return map(lambda a: a[0], nms) def analyze_one(self, nm, importernm=None, imptyp=0, level=-1): """ break the name being imported up so we get: a.b.c -> [a, b, c] ; ..z -> ['', '', z] """ #print '## analyze_one', nm, importernm, imptyp, level if not nm: nm = importernm importernm = None level = 0 nmparts = nm.split('.') if level < 0: # behaviour up to Python 2.4 (and default in Python 2.5) # first see if we could be importing a relative name contexts = [None] if importernm: if self.ispackage(importernm): contexts.insert(0, importernm) else: pkgnm = ".".join(importernm.split(".")[:-1]) if pkgnm: contexts.insert(0, pkgnm) elif level == 0: # absolute import, do not try relative importernm = None contexts = [None] elif level > 0: # relative import, do not try absolute if self.ispackage(importernm): level -= 1 if level > 0: importernm = ".".join(importernm.split('.')[:-level]) contexts = [importernm, None] importernm = None _all = None assert contexts # so contexts is [pkgnm, None] or just [None] if nmparts[-1] == '*': del nmparts[-1] _all = [] nms = [] for context in contexts: ctx = context for i, nm in enumerate(nmparts): if ctx: fqname = ctx + '.' + nm else: fqname = nm mod = self.modules.get(fqname, UNTRIED) if mod is UNTRIED: logger.debug('Analyzing %s', fqname) mod = self.doimport(nm, ctx, fqname) if mod: nms.append(mod.__name__) ctx = fqname else: break else: # no break, point i beyond end i = i + 1 if i: break # now nms is the list of modules that went into sys.modules # just as result of the structure of the name being imported # however, each mod has been scanned and that list is in mod.imports if i < len(nmparts): if ctx: if hasattr(self.modules[ctx], nmparts[i]): return nms if not self.ispackage(ctx): return nms self.warnings["W: no module named %s (%s import by %s)" % (fqname, imptyps[imptyp], importernm or "__main__")] = 1 if fqname in self.modules: del self.modules[fqname] return nms if _all is None: return nms bottommod = self.modules[ctx] if bottommod.ispackage(): for nm in bottommod._all: if not hasattr(bottommod, nm): mod = self.doimport(nm, ctx, ctx + '.' + nm) if mod: nms.append(mod.__name__) else: bottommod.warnings.append("W: name %s not found" % nm) return nms def analyze_script(self, fnm): try: stuff = open(fnm, 'rU').read() + '\n' co = compile(stuff, fnm, 'exec') except SyntaxError, e: logger.exception(e) raise SystemExit(10) mod = depend.modules.PyScript(fnm, co) self.modules['__main__'] = mod return self.analyze_r('__main__')