From: Jimmy R. <jr...@us...> - 2006-03-07 08:12:13
|
Update of /cvsroot/py2exe/py2exe/py2exe In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13370/py2exe Modified Files: mf.py Log Message: Fix problems created when including a complete version of modulefinder. Index: mf.py =================================================================== RCS file: /cvsroot/py2exe/py2exe/py2exe/mf.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mf.py 11 Dec 2005 08:36:50 -0000 1.4 --- mf.py 7 Mar 2006 08:12:07 -0000 1.5 *************** *** 18,21 **** --- 18,29 ---- + # !!! NOTE BEFORE INCLUDING IN PYTHON DISTRIBUTION !!! + # To clear up issues caused by the duplication of data structures between + # the real Python modulefinder and this duplicate version, packagePathMap + # and replacePackageMap are imported from the actual modulefinder. This + # should be changed back to the assigments that are commented out below. + # There are also py2exe specific pieces at the bottom of this file. + + # Modulefinder does a good job at simulating Python's, but it can not # handle __path__ modifications packages make at runtime. Therefore there *************** *** 24,28 **** # Note this is a mapping is lists of paths. ! packagePathMap = {} # A Public interface --- 32,37 ---- # Note this is a mapping is lists of paths. ! #~ packagePathMap = {} ! from modulefinder import packagePathMap # A Public interface *************** *** 32,36 **** packagePathMap[packagename] = paths ! replacePackageMap = {} # This ReplacePackage mechanism allows modulefinder to work around the --- 41,46 ---- packagePathMap[packagename] = paths ! #~ replacePackageMap = {} ! from modulefinder import replacePackageMap # This ReplacePackage mechanism allows modulefinder to work around the *************** *** 599,600 **** --- 609,734 ---- except KeyboardInterrupt: print "\n[interrupt]" + + + + # py2exe specific portion - this should be removed before inclusion in the + # Python distribution + + import tempfile + import urllib + + Base = ModuleFinder + del ModuleFinder + + # Much inspired by Toby Dickenson's code: + # http://www.tarind.com/depgraph.html + class ModuleFinder(Base): + def __init__(self, *args, **kw): + self._depgraph = {} + self._types = {} + self._last_caller = None + self._scripts = set() + Base.__init__(self, *args, **kw) + + def run_script(self, pathname): + # Scripts always end in the __main__ module, but we possibly + # have more than one script in py2exe, so we want to keep + # *all* the pathnames. + self._scripts.add(pathname) + Base.run_script(self, pathname) + + def import_hook(self, name, caller=None, fromlist=None): + old_last_caller = self._last_caller + try: + self._last_caller = caller + return Base.import_hook(self,name,caller,fromlist) + finally: + self._last_caller = old_last_caller + + def import_module(self,partnam,fqname,parent): + r = Base.import_module(self,partnam,fqname,parent) + if r is not None and self._last_caller: + self._depgraph.setdefault(self._last_caller.__name__, set()).add(r.__name__) + return r + + def load_module(self, fqname, fp, pathname, (suffix, mode, typ)): + r = Base.load_module(self, fqname, fp, pathname, (suffix, mode, typ)) + if r is not None: + self._types[r.__name__] = typ + return r + + def create_xref(self): + # this code probably needs cleanup + depgraph = {} + importedby = {} + for name, value in self._depgraph.items(): + depgraph[name] = list(value) + for needs in value: + importedby.setdefault(needs, set()).add(name) + + names = self._types.keys() + names.sort() + + fd, htmlfile = tempfile.mkstemp(".html") + ofi = open(htmlfile, "w") + os.close(fd) + print >> ofi, "<html><title>py2exe cross reference for %s</title><body>" % sys.argv[0] + + print >> ofi, "<h1>py2exe cross reference for %s</h1>" % sys.argv[0] + + for name in names: + if self._types[name] in (imp.PY_SOURCE, imp.PKG_DIRECTORY): + print >> ofi, '<a name="%s"><b><tt>%s</tt></b></a>' % (name, name) + if name == "__main__": + for fname in self._scripts: + path = urllib.pathname2url(os.path.abspath(fname)) + print >> ofi, '<a target="code" href="%s" type="text/plain"><tt>%s</tt></a> ' \ + % (path, fname) + print >> ofi, '<br>imports:' + else: + fname = urllib.pathname2url(self.modules[name].__file__) + print >> ofi, '<a target="code" href="%s" type="text/plain"><tt>%s</tt></a><br>imports:' \ + % (fname, self.modules[name].__file__) + else: + fname = self.modules[name].__file__ + if fname: + print >> ofi, '<a name="%s"><b><tt>%s</tt></b></a> <tt>%s</tt><br>imports:' \ + % (name, name, fname) + else: + print >> ofi, '<a name="%s"><b><tt>%s</tt></b></a> <i>%s</i><br>imports:' \ + % (name, name, TYPES[self._types[name]]) + + if name in depgraph: + needs = depgraph[name] + for n in needs: + print >> ofi, '<a href="#%s"><tt>%s</tt></a> ' % (n, n) + print >> ofi, "<br>\n" + + print >> ofi, 'imported by:' + if name in importedby: + for i in importedby[name]: + print >> ofi, '<a href="#%s"><tt>%s</tt></a> ' % (i, i) + + print >> ofi, "<br>\n" + + print >> ofi, "<br>\n" + + print >> ofi, "</body></html>" + ofi.close() + os.startfile(htmlfile) + # how long does it take to start the browser? + import threading + threading.Timer(5, os.remove, args=[htmlfile]) + + + TYPES = {imp.C_BUILTIN: "(builtin module)", + imp.C_EXTENSION: "extension module", + imp.IMP_HOOK: "IMP_HOOK", + imp.PKG_DIRECTORY: "package directory", + imp.PY_CODERESOURCE: "PY_CODERESOURCE", + imp.PY_COMPILED: "compiled python module", + imp.PY_FROZEN: "frozen module", + imp.PY_RESOURCE: "PY_RESOURCE", + imp.PY_SOURCE: "python module", + imp.SEARCH_ERROR: "SEARCH_ERROR" + } |