home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Tools / freeze / modulefinder.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2000-06-23  |  17.4 KB  |  504 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 1.5)
  3.  
  4. '''Find modules used by a script, using introspection.'''
  5. import dis
  6. import imp
  7. import marshal
  8. import os
  9. import re
  10. import string
  11. import sys
  12. if sys.platform == 'win32':
  13.     
  14.     try:
  15.         import win32api
  16.     except ImportError:
  17.         print 'The win32api module is not available - modules listed'
  18.         print 'in the registry will not be found.'
  19.         win32api = None
  20.  
  21.  
  22. IMPORT_NAME = dis.opname.index('IMPORT_NAME')
  23. IMPORT_FROM = dis.opname.index('IMPORT_FROM')
  24. packagePathMap = { }
  25.  
  26. def AddPackagePath(packagename, path):
  27.     paths = packagePathMap.get(packagename, [])
  28.     paths.append(path)
  29.     packagePathMap[packagename] = paths
  30.  
  31.  
  32. class Module:
  33.     
  34.     def __init__(self, name, file = None, path = None):
  35.         self.__name__ = name
  36.         self.__file__ = file
  37.         self.__path__ = path
  38.         self.__code__ = None
  39.  
  40.     
  41.     def __repr__(self):
  42.         s = 'Module(%s' % `self.__name__`
  43.         if self.__file__ is not None:
  44.             s = s + ', %s' % `self.__file__`
  45.         
  46.         if self.__path__ is not None:
  47.             s = s + ', %s' % `self.__path__`
  48.         
  49.         s = s + ')'
  50.         return s
  51.  
  52.  
  53.  
  54. class ModuleFinder:
  55.     
  56.     def __init__(self, path = None, debug = 0, excludes = []):
  57.         if path is None:
  58.             path = sys.path
  59.         
  60.         self.path = path
  61.         self.modules = { }
  62.         self.badmodules = { }
  63.         self.debug = debug
  64.         self.indent = 0
  65.         self.excludes = excludes
  66.  
  67.     
  68.     def msg(self, level, str, *args):
  69.         pass
  70.  
  71.     
  72.     def msgin(self, *args):
  73.         level = args[0]
  74.         if level <= self.debug:
  75.             self.indent = self.indent + 1
  76.             apply(self.msg, args)
  77.         
  78.  
  79.     
  80.     def msgout(self, *args):
  81.         level = args[0]
  82.         if level <= self.debug:
  83.             self.indent = self.indent - 1
  84.             apply(self.msg, args)
  85.         
  86.  
  87.     
  88.     def run_script(self, pathname):
  89.         self.msg(2, 'run_script', pathname)
  90.         fp = open(pathname)
  91.         stuff = ('', 'r', imp.PY_SOURCE)
  92.         self.load_module('__main__', fp, pathname, stuff)
  93.  
  94.     
  95.     def load_file(self, pathname):
  96.         (dir, name) = os.path.split(pathname)
  97.         (name, ext) = os.path.splitext(name)
  98.         fp = open(pathname)
  99.         stuff = (ext, 'r', imp.PY_SOURCE)
  100.         self.load_module(name, fp, pathname, stuff)
  101.  
  102.     
  103.     def import_hook(self, name, caller = None, fromlist = None):
  104.         self.msg(3, 'import_hook', name, caller, fromlist)
  105.         parent = self.determine_parent(caller)
  106.         (q, tail) = self.find_head_package(parent, name)
  107.         m = self.load_tail(q, tail)
  108.         if not fromlist:
  109.             return q
  110.         
  111.         if m.__path__:
  112.             self.ensure_fromlist(m, fromlist)
  113.         
  114.  
  115.     
  116.     def determine_parent(self, caller):
  117.         self.msgin(4, 'determine_parent', caller)
  118.         if not caller:
  119.             self.msgout(4, 'determine_parent -> None')
  120.             return None
  121.         
  122.         pname = caller.__name__
  123.         if caller.__path__:
  124.             parent = self.modules[pname]
  125.             if not __debug__ and caller is parent:
  126.                 raise AssertionError
  127.             self.msgout(4, 'determine_parent ->', parent)
  128.             return parent
  129.         
  130.         if '.' in pname:
  131.             i = string.rfind(pname, '.')
  132.             pname = pname[:i]
  133.             parent = self.modules[pname]
  134.             if not __debug__ and parent.__name__ == pname:
  135.                 raise AssertionError
  136.             self.msgout(4, 'determine_parent ->', parent)
  137.             return parent
  138.         
  139.         self.msgout(4, 'determine_parent -> None')
  140.         return None
  141.  
  142.     
  143.     def find_head_package(self, parent, name):
  144.         self.msgin(4, 'find_head_package', parent, name)
  145.         if '.' in name:
  146.             i = string.find(name, '.')
  147.             head = name[:i]
  148.             tail = name[i + 1:]
  149.         else:
  150.             head = name
  151.             tail = ''
  152.         if parent:
  153.             qname = '%s.%s' % (parent.__name__, head)
  154.         else:
  155.             qname = head
  156.         q = self.import_module(head, qname, parent)
  157.         if q:
  158.             self.msgout(4, 'find_head_package ->', (q, tail))
  159.             return (q, tail)
  160.         
  161.         if parent:
  162.             qname = head
  163.             parent = None
  164.             q = self.import_module(head, qname, parent)
  165.             if q:
  166.                 self.msgout(4, 'find_head_package ->', (q, tail))
  167.                 return (q, tail)
  168.             
  169.         
  170.         self.msgout(4, 'raise ImportError: No module named', qname)
  171.         raise ImportError, 'No module named ' + qname
  172.  
  173.     
  174.     def load_tail(self, q, tail):
  175.         self.msgin(4, 'load_tail', q, tail)
  176.         m = q
  177.         while tail:
  178.             i = string.find(tail, '.')
  179.             if i < 0:
  180.                 i = len(tail)
  181.             
  182.             (head, tail) = (tail[:i], tail[i + 1:])
  183.             mname = '%s.%s' % (m.__name__, head)
  184.             m = self.import_module(head, mname, m)
  185.             if not m:
  186.                 self.msgout(4, 'raise ImportError: No module named', mname)
  187.                 raise ImportError, 'No module named ' + mname
  188.             
  189.         self.msgout(4, 'load_tail ->', m)
  190.         return m
  191.  
  192.     
  193.     def ensure_fromlist(self, m, fromlist, recursive = 0):
  194.         self.msg(4, 'ensure_fromlist', m, fromlist, recursive)
  195.         for sub in fromlist:
  196.             if sub == '*':
  197.                 if not recursive:
  198.                     all = self.find_all_submodules(m)
  199.                     if all:
  200.                         self.ensure_fromlist(m, all, 1)
  201.                     
  202.                 
  203.             elif not hasattr(m, sub):
  204.                 subname = '%s.%s' % (m.__name__, sub)
  205.                 submod = self.import_module(sub, subname, m)
  206.                 if not submod:
  207.                     raise ImportError, 'No module named ' + subname
  208.                 
  209.             
  210.         
  211.  
  212.     
  213.     def find_all_submodules(self, m):
  214.         if not (m.__path__):
  215.             return None
  216.         
  217.         modules = { }
  218.         suffixes = [
  219.             '.py',
  220.             '.pyc',
  221.             '.pyo']
  222.         for dir in m.__path__:
  223.             
  224.             try:
  225.                 names = os.listdir(dir)
  226.             except os.error:
  227.                 0
  228.                 0
  229.                 m.__path__
  230.                 self.msg(2, "can't list directory", dir)
  231.                 continue
  232.             except:
  233.                 0
  234.  
  235.             for name in names:
  236.                 mod = None
  237.                 for suff in suffixes:
  238.                     n = len(suff)
  239.                 
  240.             
  241.         
  242.         return modules.keys()
  243.  
  244.     
  245.     def import_module(self, partname, fqname, parent):
  246.         self.msgin(3, 'import_module', partname, fqname, parent)
  247.         
  248.         try:
  249.             m = self.modules[fqname]
  250.         except KeyError:
  251.             pass
  252.  
  253.         self.msgout(3, 'import_module ->', m)
  254.         return m
  255.         if self.badmodules.has_key(fqname):
  256.             self.msgout(3, 'import_module -> None')
  257.             self.badmodules[fqname][parent.__name__] = None
  258.             return None
  259.         
  260.         
  261.         try:
  262.             if parent:
  263.                 pass
  264.             (fp, pathname, stuff) = self.find_module(partname, parent.__path__)
  265.         except ImportError:
  266.             self.msgout(3, 'import_module ->', None)
  267.             return None
  268.  
  269.         
  270.         try:
  271.             m = self.load_module(fqname, fp, pathname, stuff)
  272.         finally:
  273.             if fp:
  274.                 fp.close()
  275.             
  276.  
  277.         if parent:
  278.             setattr(parent, partname, m)
  279.         
  280.         self.msgout(3, 'import_module ->', m)
  281.         return m
  282.  
  283.     
  284.     def load_module(self, fqname, fp, pathname, .8):
  285.         (suffix, mode, type) = .8
  286.         if fp:
  287.             pass
  288.         self.msgin(2, 'load_module', fqname, 'fp', pathname)
  289.         if type == imp.PKG_DIRECTORY:
  290.             m = self.load_package(fqname, pathname)
  291.             self.msgout(2, 'load_module ->', m)
  292.             return m
  293.         
  294.         if type == imp.PY_SOURCE:
  295.             co = compile(fp.read() + '\n', pathname, 'exec')
  296.         elif type == imp.PY_COMPILED:
  297.             if fp.read(4) != imp.get_magic():
  298.                 self.msgout(2, 'raise ImportError: Bad magic number', pathname)
  299.                 raise ImportError, 'Bad magic number in %s', pathname
  300.             
  301.             fp.read(4)
  302.             co = marshal.load(fp)
  303.         else:
  304.             co = None
  305.         m = self.add_module(fqname)
  306.         m.__file__ = pathname
  307.         if co:
  308.             m.__code__ = co
  309.             self.scan_code(co, m)
  310.         
  311.         self.msgout(2, 'load_module ->', m)
  312.         return m
  313.  
  314.     
  315.     def scan_code(self, co, m):
  316.         code = co.co_code
  317.         n = len(code)
  318.         i = 0
  319.         lastname = None
  320.         while i < n:
  321.             c = code[i]
  322.             i = i + 1
  323.             op = ord(c)
  324.             if op >= dis.HAVE_ARGUMENT:
  325.                 oparg = ord(code[i]) + ord(code[i + 1]) * 256
  326.                 i = i + 2
  327.             
  328.             if op == IMPORT_NAME:
  329.                 name = lastname = co.co_names[oparg]
  330.                 if not self.badmodules.has_key(lastname):
  331.                     
  332.                     try:
  333.                         self.import_hook(name, m)
  334.                     except ImportError:
  335.                         msg = None
  336.                         self.msg(2, 'ImportError:', str(msg))
  337.                         if not self.badmodules.has_key(name):
  338.                             self.badmodules[name] = { }
  339.                         
  340.                         self.badmodules[name][m.__name__] = None
  341.  
  342.                 
  343.             elif op == IMPORT_FROM:
  344.                 name = co.co_names[oparg]
  345.                 if not __debug__ and lastname is not None:
  346.                     raise AssertionError
  347.                 if not self.badmodules.has_key(lastname):
  348.                     
  349.                     try:
  350.                         self.import_hook(lastname, m, [
  351.                             name])
  352.                     except ImportError:
  353.                         msg = None
  354.                         self.msg(2, 'ImportError:', str(msg))
  355.                         fullname = lastname + '.' + name
  356.                         if not self.badmodules.has_key(fullname):
  357.                             self.badmodules[fullname] = { }
  358.                         
  359.                         self.badmodules[fullname][m.__name__] = None
  360.  
  361.                 
  362.             else:
  363.                 lastname = None
  364.         for c in co.co_consts:
  365.             pass
  366.         
  367.  
  368.     
  369.     def load_package(self, fqname, pathname):
  370.         self.msgin(2, 'load_package', fqname, pathname)
  371.         m = self.add_module(fqname)
  372.         m.__file__ = pathname
  373.         m.__path__ = [
  374.             pathname]
  375.         m.__path__ = m.__path__ + packagePathMap.get(fqname, [])
  376.         (fp, buf, stuff) = self.find_module('__init__', m.__path__)
  377.         self.load_module(fqname, fp, buf, stuff)
  378.         self.msgout(2, 'load_package ->', m)
  379.         return m
  380.  
  381.     
  382.     def add_module(self, fqname):
  383.         if self.modules.has_key(fqname):
  384.             return self.modules[fqname]
  385.         
  386.         self.modules[fqname] = m = Module(fqname)
  387.         return m
  388.  
  389.     
  390.     def find_module(self, name, path):
  391.         if name in self.excludes:
  392.             self.msgout(3, 'find_module -> Excluded')
  393.             raise ImportError, name
  394.         
  395.         if path is None:
  396.             if name in sys.builtin_module_names:
  397.                 return (None, None, ('', '', imp.C_BUILTIN))
  398.             
  399.             if sys.platform == 'win32' and win32api is not None:
  400.                 HKEY_LOCAL_MACHINE = -2147483646
  401.                 
  402.                 try:
  403.                     pathname = win32api.RegQueryValue(HKEY_LOCAL_MACHINE, 'Software\\Python\\PythonCore\\%s\\Modules\\%s' % (sys.winver, name))
  404.                     fp = open(pathname, 'rb')
  405.                     stuff = ('', 'rb', imp.C_EXTENSION)
  406.                     return (fp, pathname, stuff)
  407.                 except win32api.error:
  408.                     pass
  409.  
  410.             
  411.             path = self.path
  412.         
  413.         return imp.find_module(name, path)
  414.  
  415.     
  416.     def report(self):
  417.         print 
  418.         print '  %-25s %s' % ('Name', 'File')
  419.         print '  %-25s %s' % ('----', '----')
  420.         keys = self.modules.keys()
  421.         keys.sort()
  422.         for key in keys:
  423.             m = self.modules[key]
  424.             print '%-25s' % key,
  425.             if not m.__file__:
  426.                 pass
  427.             print ''
  428.         
  429.         keys = self.badmodules.keys()
  430.         keys.sort()
  431.         for key in keys:
  432.             if key not in self.excludes:
  433.                 mods = self.badmodules[key].keys()
  434.                 mods.sort()
  435.                 print '?', key, 'from', string.join(mods, ', ')
  436.             
  437.         
  438.  
  439.  
  440.  
  441. def test():
  442.     import getopt
  443.     
  444.     try:
  445.         (opts, args) = getopt.getopt(sys.argv[1:], 'dmp:qx:')
  446.     except getopt.error:
  447.         msg = None
  448.         print msg
  449.         return None
  450.  
  451.     debug = 1
  452.     domods = 0
  453.     addpath = []
  454.     exclude = []
  455.     for o, a in opts:
  456.         if o == '-m':
  457.             domods = 1
  458.         
  459.         if o == '-p':
  460.             addpath = addpath + string.split(a, os.pathsep)
  461.         
  462.         if o == '-q':
  463.             debug = 0
  464.         
  465.         if o == '-x':
  466.             exclude.append(a)
  467.         
  468.     
  469.     if not args:
  470.         script = 'hello.py'
  471.     else:
  472.         script = args[0]
  473.     path = sys.path[:]
  474.     path[0] = os.path.dirname(script)
  475.     path = addpath + path
  476.     if debug > 1:
  477.         print 'path:'
  478.         for item in path:
  479.             print '   ', `item`
  480.         
  481.     
  482.     mf = ModuleFinder(path, debug, exclude)
  483.     for arg in args[1:]:
  484.         if domods:
  485.             if arg[-2:] == '.*':
  486.                 mf.import_hook(arg[:-2], None, [
  487.                     '*'])
  488.             else:
  489.                 mf.import_hook(arg)
  490.         else:
  491.             mf.load_file(arg)
  492.     
  493.     mf.run_script(script)
  494.     mf.report()
  495.  
  496. if __name__ == '__main__':
  497.     
  498.     try:
  499.         test()
  500.     except KeyboardInterrupt:
  501.         print '\n[interrupt]'
  502.  
  503.  
  504.