126 lines · 3.4 KB · Python
RawDownload
"""An Python re-implementation of hierarchical module import. This code is intended to be read, not executed.  However, it does work-- all you need to do to enable it is "import knee". (The name is a pun on the klunkier predecessor of this module, "ni".) """ import sys, imp, __builtin__  # Replacement for __import__()def import_hook(name, globals=None, locals=None, fromlist=None):    parent = determine_parent(globals)    q, tail = find_head_package(parent, name)    m = load_tail(q, tail)    if not fromlist:        return q    if hasattr(m, "__path__"):        ensure_fromlist(m, fromlist)    return m def determine_parent(globals):    if not globals or  not globals.has_key("__name__"):        return None    pname = globals['__name__']    if globals.has_key("__path__"):        parent = sys.modules[pname]        assert globals is parent.__dict__        return parent    if '.' in pname:        i = pname.rfind('.')        pname = pname[:i]        parent = sys.modules[pname]        assert parent.__name__ == pname        return parent    return None def find_head_package(parent, name):    if '.' in name:        i = name.find('.')        head = name[:i]        tail = name[i+1:]    else:        head = name        tail = ""    if parent:        qname = "%s.%s" % (parent.__name__, head)    else:        qname = head    q = import_module(head, qname, parent)    if q: return q, tail    if parent:        qname = head        parent = None        q = import_module(head, qname, parent)        if q: return q, tail    raise ImportError, "No module named " + qname def load_tail(q, tail):    m = q    while tail:        i = tail.find('.')        if i < 0: i = len(tail)        head, tail = tail[:i], tail[i+1:]        mname = "%s.%s" % (m.__name__, head)        m = import_module(head, mname, m)        if not m:            raise ImportError, "No module named " + mname    return m def ensure_fromlist(m, fromlist, recursive=0):    for sub in fromlist:        if sub == "*":            if not recursive:                try:                    all = m.__all__                except AttributeError:                    pass                else:                    ensure_fromlist(m, all, 1)            continue        if sub != "*" and not hasattr(m, sub):            subname = "%s.%s" % (m.__name__, sub)            submod = import_module(sub, subname, m)            if not submod:                raise ImportError, "No module named " + subname def import_module(partname, fqname, parent):    try:        return sys.modules[fqname]    except KeyError:        pass    try:        fp, pathname, stuff = imp.find_module(partname,                                              parent and parent.__path__)    except ImportError:        return None    try:        m = imp.load_module(fqname, fp, pathname, stuff)    finally:        if fp: fp.close()    if parent:        setattr(parent, partname, m)    return m  # Replacement for reload()def reload_hook(module):    name = module.__name__    if '.' not in name:        return import_module(name, name, None)    i = name.rfind('.')    pname = name[:i]    parent = sys.modules[pname]    return import_module(name[i+1:], name, parent)  # Save the original hooksoriginal_import = __builtin__.__import__original_reload = __builtin__.reload # Now install our hooks__builtin__.__import__ = import_hook__builtin__.reload = reload_hook