home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pytho152.zip / emx / lib / python1.5 / knee.py < prev    next >
Text File  |  2000-08-10  |  4KB  |  127 lines

  1. """An Python re-implementation of hierarchical module import.
  2.  
  3. This code is intended to be read, not executed.  However, it does work
  4. -- all you need to do to enable it is "import knee".
  5.  
  6. (The name is a pun on the klunkier predecessor of this module, "ni".)
  7.  
  8. """
  9.  
  10. import sys, imp, __builtin__, string
  11.  
  12.  
  13. # Replacement for __import__()
  14. def import_hook(name, globals=None, locals=None, fromlist=None):
  15.     parent = determine_parent(globals)
  16.     q, tail = find_head_package(parent, name)
  17.     m = load_tail(q, tail)
  18.     if not fromlist:
  19.         return q
  20.     if hasattr(m, "__path__"):
  21.         ensure_fromlist(m, fromlist)
  22.     return m
  23.  
  24. def determine_parent(globals):
  25.     if not globals or  not globals.has_key("__name__"):
  26.         return None
  27.     pname = globals['__name__']
  28.     if globals.has_key("__path__"):
  29.         parent = sys.modules[pname]
  30.         assert globals is parent.__dict__
  31.         return parent
  32.     if '.' in pname:
  33.         i = string.rfind(pname, '.')
  34.         pname = pname[:i]
  35.         parent = sys.modules[pname]
  36.         assert parent.__name__ == pname
  37.         return parent
  38.     return None
  39.  
  40. def find_head_package(parent, name):
  41.     if '.' in name:
  42.         i = string.find(name, '.')
  43.         head = name[:i]
  44.         tail = name[i+1:]
  45.     else:
  46.         head = name
  47.         tail = ""
  48.     if parent:
  49.         qname = "%s.%s" % (parent.__name__, head)
  50.     else:
  51.         qname = head
  52.     q = import_module(head, qname, parent)
  53.     if q: return q, tail
  54.     if parent:
  55.         qname = head
  56.         parent = None
  57.         q = import_module(head, qname, parent)
  58.         if q: return q, tail
  59.     raise ImportError, "No module named " + qname
  60.  
  61. def load_tail(q, tail):
  62.     m = q
  63.     while tail:
  64.         i = string.find(tail, '.')
  65.         if i < 0: i = len(tail)
  66.         head, tail = tail[:i], tail[i+1:]
  67.         mname = "%s.%s" % (m.__name__, head)
  68.         m = import_module(head, mname, m)
  69.         if not m:
  70.             raise ImportError, "No module named " + mname
  71.     return m
  72.  
  73. def ensure_fromlist(m, fromlist, recursive=0):
  74.     for sub in fromlist:
  75.         if sub == "*":
  76.             if not recursive:
  77.                 try:
  78.                     all = m.__all__
  79.                 except AttributeError:
  80.                     pass
  81.                 else:
  82.                     ensure_fromlist(m, all, 1)
  83.             continue
  84.         if sub != "*" and not hasattr(m, sub):
  85.             subname = "%s.%s" % (m.__name__, sub)
  86.             submod = import_module(sub, subname, m)
  87.             if not submod:
  88.                 raise ImportError, "No module named " + subname
  89.  
  90. def import_module(partname, fqname, parent):
  91.     try:
  92.         return sys.modules[fqname]
  93.     except KeyError:
  94.         pass
  95.     try:
  96.         fp, pathname, stuff = imp.find_module(partname,
  97.                                               parent and parent.__path__)
  98.     except ImportError:
  99.         return None
  100.     try:
  101.         m = imp.load_module(fqname, fp, pathname, stuff)
  102.     finally:
  103.         if fp: fp.close()
  104.     if parent:
  105.         setattr(parent, partname, m)
  106.     return m
  107.  
  108.  
  109. # Replacement for reload()
  110. def reload_hook(module):
  111.     name = module.__name__
  112.     if '.' not in name:
  113.         return import_module(name, name, None)
  114.     i = string.rfind(name, '.')
  115.     pname = name[:i]
  116.     parent = sys.modules[pname]
  117.     return import_module(name[i+1:], name, parent)
  118.  
  119.  
  120. # Save the original hooks
  121. original_import = __builtin__.__import__
  122. original_reload = __builtin__.reload
  123.  
  124. # Now install our hooks
  125. __builtin__.__import__ = import_hook
  126. __builtin__.reload = reload_hook
  127.