[pypy-svn] r19099 - pypy/dist/pypy/tool

mwh at codespeak.net mwh at codespeak.net
Fri Oct 28 10:44:39 CEST 2005


Author: mwh
Date: Fri Oct 28 10:44:37 2005
New Revision: 19099

Modified:
   pypy/dist/pypy/tool/importfun.py
Log:
check in of html generation code, and probably assorted other stuff too.


Modified: pypy/dist/pypy/tool/importfun.py
==============================================================================
--- pypy/dist/pypy/tool/importfun.py	(original)
+++ pypy/dist/pypy/tool/importfun.py	Fri Oct 28 10:44:37 2005
@@ -3,8 +3,8 @@
 import dis
 import imp
 import os
-from sys import path, prefix
 import __builtin__
+import time
 
 """
 so design goal:
@@ -138,7 +138,7 @@
         self.importers = []
     def import_(self, modname):
         if modname not in self._imports:
-            if modname not in self.system.modules:
+            if recursive and modname not in self.system.modules:
                 self.system.pendingmodules[modname] = None
             self._imports[modname] = {}
         return self._imports[modname]
@@ -275,7 +275,7 @@
                     else:
                         storename = codeob.co_names[oparg]
 
-                        
+
                     if mod:
                         scope.modvars[storename] = submod
                     else:
@@ -333,61 +333,47 @@
         process(r, c, Scope(scope))
 
 def process_module(dottedname, system):
-    path = find_from_dotted_name(dottedname)
+    if dottedname.endswith('.py'):
+        path = dottedname
+        dottedname = path.lstrip('./').rstrip()[:-3].replace('/', '.')
+    else:
+        path = find_from_dotted_name(dottedname)
+
     ispackage = False
     if os.path.isdir(path):
         ispackage = True
         path += '/__init__.py'
-    code = compile(open(path, "U").read(), '', 'exec')
     r = Module(dottedname, system)
     r.ispackage = ispackage
 
+    if dottedname in system.modules:
+        return system.modules[dottedname]
+
     try:
+        code = compile(open(path, "U").read(), path, 'exec')
         process(r, code, r.toplevelscope, True)
-    except ImportError, e:
+    except (ImportError, AssertionError, SyntaxError), e:
         print "failed!", e
     else:
-        assert dottedname not in system.pendingmodules
+        if dottedname in system.pendingmodules:
+            print
+            del system.pendingmodules[dottedname]
 
         system.modules[dottedname] = r
 
     return r
 
-a = 1
-
 def find_from_dotted_name(modname):
     path = None
     for part in modname.split('.'):
-        path = [imp.find_module(part, path)[1]]
+        try:
+            path = [imp.find_module(part, path)[1]]
+        except ImportError:
+            print modname
+            raise
     return path[0]
 
-def main(path):
-    system = System()
-    system.pendingmodules[path] = None
-    while system.pendingmodules:
-        path, d = system.pendingmodules.popitem()
-        print '\r', len(system.pendingmodules), path, '        ',
-        sys.stdout.flush()
-        if not path.startswith('pypy.') or path == 'pypy._cache':
-            continue
-        process_module(path, system)
-
-    # strip out non-pypy imports
-##     for name, mod in system.modules.iteritems():
-##         for n in mod._imports.copy():
-##             if not n.startswith('pypy.') or n == 'pypy._cache':
-##                 del mod._imports[n]
-
-    # record importer information
-#    for name, mod in system.modules.iteritems():
-#        for n in mod._imports:
-#            system.modules[n].importers.append(name)
-
-    unuseds = {}
-
-    print
-    print '------'
-
+def report_unused_symbols(system):
     for name, mod in sorted(system.modules.iteritems()):
         printed = False
         if not 'pypy.' in name or '_cache' in name:
@@ -422,7 +408,205 @@
                 printed = True
             for k, v in u.iteritems():
                 print '   ', k, v
-                    
+
+def find_cycles(system):
+    from pypy.tool.algo import graphlib
+    vertices = dict.fromkeys(system.modules)
+    edges = {}
+    for m in system.modules:
+        edges[m] = []
+        for n in system.modules[m]._imports:
+            edges[m].append(graphlib.Edge(m, n))
+    cycles = []
+    for component in graphlib.strong_components(vertices, edges):
+        random_vertex = component.iterkeys().next()
+        cycles.extend(graphlib.all_cycles(random_vertex, component, edges))
+
+    ncycles = []
+    for cycle in cycles:
+        packs = {}
+        for edge in cycle:
+            package = edge.source.rsplit('.', 1)[0]
+            packs[package] = True
+        if len(packs) > 1:
+            ncycles.append(cycle)
+    cycles = ncycles
+
+    for cycle in cycles:
+        l = len(cycle[0].source)
+        print cycle[0].source, '->', cycle[0].target
+        for edge in cycle[1:]:
+            print ' '*l, '->', edge.target
+    print len(cycles), 'inter-package cycles'
+
+def summary(system):
+    mcount = float(len(system.modules))
+    importcount = 0
+    importstars = 0
+    importstarusage = 0
+    defcount = 0
+    importedcount = 0
+    for m in system.modules:
+        m = system.modules[m]
+        defcount += len(m.definitions)
+        importedcount += len(m.importers)
+        importcount += len(m._imports)
+        for n in m._imports:
+            if '*' in m._imports[n]:
+                importstars += 1
+                importstarusage += len([o for (o, v) in m._imports[n].iteritems() if v == True])
+    print
+    print 'the average module'
+    print 'was imported %.2f times'%(importedcount/mcount)
+    print 'imported %.2f other modules'%(importcount/mcount)
+    print 'defined %.2f names'%(defcount/mcount)
+    print
+    print 'there were %d import *s'%(importstars)
+    print 'the average one produced %.2f names that were actually used'\
+          %((1.0*importstarusage)/importstars)
+
+def not_imported(system):
+    for m, M in sorted(system.modules.iteritems()):
+        if not M.importers and 'test' not in m and '__init__' not in m:
+            print m
+
+def import_stars(system):
+    for m in sorted(system.modules):
+        m = system.modules[m]
+        for n in sorted(m._imports):
+            if '*' in m._imports[n]:
+                print m.name, 'imports * from', n
+                used = [o for (o, v) in m._imports[n].iteritems() if v == True and o != '*']
+                print len(used), 'out of', len(m._imports[n]) - 1, 'names are used'
+                print '    ', ', '.join(sorted(used))
+
+def find_varargs_users(system):
+    for m in sorted(system.modules):
+        m = system.modules[m]
+        if 'pypy.interpreter.pycode' in m._imports:
+            if m._imports['pypy.interpreter.pycode'].get('CO_VARARGS') == True:
+                print m.name
+
+
+def html_for_module(module):
+    from py.xml import html
+    out = open('importfunhtml/%s.html'%module.name, 'w')
+    head = [html.title(module.name)]
+    body = [html.h1(module.name)]
+    body.append(html.p('This module defines these names:'))
+    listbody = []
+    for d in module.definitions:
+        if not d.startswith('_'):
+            listbody.append(html.li(
+                html.a(d, href=module.name+'-'+d+'.html')))
+    body.append(html.ul(listbody))
+    body.append(html.p('This module imports the following:'))
+    listbody1 = []
+    for n in sorted(module._imports):
+        if n in module.system.modules:
+            listbody2 = [html.a(n, href=n+'.html')]
+        else:
+            listbody2 = [n]
+        listbody3 = []
+        for o in sorted(module._imports[n]):
+            if module._imports[n][o] == True:
+                if n in module.system.modules:
+                    listbody3.append(
+                        html.li(html.a(o, href=n+'-'+o+'.html')))
+                else:
+                    listbody3.append(html.li(o))
+        if listbody3:
+            listbody2.append(html.ul(listbody3))
+        listbody1.append(html.li(listbody2))
+    body.append(html.ul(listbody1))
+    body.append(html.p('This module is imported by the following:'))
+    listbody1 = []
+    for n in module.importers:
+        licontents = [html.a(n, href=n+'.html')]
+        contents = []
+        for o in sorted(module.system.modules[n]._imports[module.name]):
+            contents.append(html.li(html.a(o, href=module.name+'-'+o+'.html')))
+        if contents:
+            licontents.append(html.ul(contents))
+        listbody1.append(html.li(licontents))
+    body.append(html.ul(listbody1))
+
+    out.write(html.html(head, body).unicode())
+
+    for d in module.definitions:
+        out = open('importfunhtml/%s-%s.html'%(module.name, d), 'w')
+        head = [html.title(module.name + '.' + d)]
+        body = [html.h1([html.a(module.name, href=module.name+'.html'), '.' + d])]
+
+        contents = []
+
+        for n in module.importers:
+            if module.system.modules[n]._imports[module.name].get(d) == True:
+                contents.append(html.li(html.a(n, href=n+'.html')))
+
+        if contents:
+            body.append(html.p('This name is used in'))
+            body.append(html.ul(contents))
+        else:
+            body.append(html.p('This name is not used outside the module.'))
+        
+        out.write(html.html(head, body).unicode())
+
+def make_html_report(system):
+    if os.path.isdir('importfunhtml'):
+        os.system('rm -rf importfunhtml')
+    os.mkdir('importfunhtml')
+    for m in system.modules.itervalues():
+        html_for_module(m)
+
+def main(*paths):
+    system = System()
+
+    for path in paths:
+        system.pendingmodules[path] = None
+
+    T = time.time()
+
+    while system.pendingmodules:
+        path, d = system.pendingmodules.popitem()
+        print '\r', len(system.pendingmodules), path, '        ',
+        sys.stdout.flush()
+        if '._cache' in path or '/_cache' in path:
+            continue
+        if '/' not in path and not path.startswith('pypy.'):
+            continue
+        process_module(path, system)
+
+    print
+    print 'analysed', len(system.modules), 'modules in %.2f seconds'%(time.time() - T)
+    print '------'
+
+    # record importer information
+    for name, mod in system.modules.iteritems():
+        for n in mod._imports:
+            if n in system.modules:
+                system.modules[n].importers.append(name)
+
+    make_html_report(system)
+
+    if interactive:
+        import pdb
+        pdb.set_trace()
+
+recursive = False
+interactive = False
 
 if __name__=='__main__':
-    main(*sys.argv[1:])
+    if '-r' in sys.argv:
+        recursive = True
+        sys.argv.remove('-r')
+    if '-i' in sys.argv:
+        interactive = True
+        sys.argv.remove('-i')
+    if len(sys.argv) > 1:
+        main(*sys.argv[1:])
+    else:
+        paths = []
+        for line in os.popen("find pypy -name '*.py'"):
+            paths.append(line[:-1])
+        main(*paths)



More information about the Pypy-commit mailing list