PageRenderTime 46ms CodeModel.GetById 15ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

/Demo/imputil/knee.py

http://unladen-swallow.googlecode.com/
Python | 126 lines | 123 code | 0 blank | 3 comment | 0 complexity | ef683a99aa1cd68d9f8297eb44584a52 MD5 | raw file
  1"""An Python re-implementation of hierarchical module import.
  2
  3This 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
 10import sys, imp, __builtin__
 11
 12
 13# Replacement for __import__()
 14def 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
 24def 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 = pname.rfind('.')
 34        pname = pname[:i]
 35        parent = sys.modules[pname]
 36        assert parent.__name__ == pname
 37        return parent
 38    return None
 39
 40def find_head_package(parent, name):
 41    if '.' in name:
 42        i = name.find('.')
 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
 61def load_tail(q, tail):
 62    m = q
 63    while tail:
 64        i = tail.find('.')
 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
 73def 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
 90def 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()
110def reload_hook(module):
111    name = module.__name__
112    if '.' not in name:
113        return import_module(name, name, None)
114    i = name.rfind('.')
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
121original_import = __builtin__.__import__
122original_reload = __builtin__.reload
123
124# Now install our hooks
125__builtin__.__import__ = import_hook
126__builtin__.reload = reload_hook