| 
									
										
										
										
											1997-09-09 20:44:04 +00:00
										 |  |  | """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".) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-09 09:48:45 +00:00
										 |  |  | import sys, imp, __builtin__ | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # 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: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return q | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     if hasattr(m, "__path__"): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         ensure_fromlist(m, fromlist) | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     return m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def determine_parent(globals): | 
					
						
							|  |  |  |     if not globals or  not globals.has_key("__name__"): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     pname = globals['__name__'] | 
					
						
							|  |  |  |     if globals.has_key("__path__"): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         parent = sys.modules[pname] | 
					
						
							|  |  |  |         assert globals is parent.__dict__ | 
					
						
							|  |  |  |         return parent | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     if '.' in pname: | 
					
						
							| 
									
										
										
										
											2001-02-09 09:48:45 +00:00
										 |  |  |         i = pname.rfind('.') | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         pname = pname[:i] | 
					
						
							|  |  |  |         parent = sys.modules[pname] | 
					
						
							|  |  |  |         assert parent.__name__ == pname | 
					
						
							|  |  |  |         return parent | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def find_head_package(parent, name): | 
					
						
							|  |  |  |     if '.' in name: | 
					
						
							| 
									
										
										
										
											2001-02-09 09:48:45 +00:00
										 |  |  |         i = name.find('.') | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         head = name[:i] | 
					
						
							|  |  |  |         tail = name[i+1:] | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         head = name | 
					
						
							|  |  |  |         tail = "" | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     if parent: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         qname = "%s.%s" % (parent.__name__, head) | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         qname = head | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     q = import_module(head, qname, parent) | 
					
						
							|  |  |  |     if q: return q, tail | 
					
						
							|  |  |  |     if parent: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         qname = head | 
					
						
							|  |  |  |         parent = None | 
					
						
							|  |  |  |         q = import_module(head, qname, parent) | 
					
						
							|  |  |  |         if q: return q, tail | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     raise ImportError, "No module named " + qname | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def load_tail(q, tail): | 
					
						
							|  |  |  |     m = q | 
					
						
							|  |  |  |     while tail: | 
					
						
							| 
									
										
										
										
											2001-02-09 09:48:45 +00:00
										 |  |  |         i = tail.find('.') | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     return m | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-09-09 20:39:58 +00:00
										 |  |  | def ensure_fromlist(m, fromlist, recursive=0): | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     for sub in fromlist: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def import_module(partname, fqname, parent): | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return sys.modules[fqname] | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     except KeyError: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         pass | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         fp, pathname, stuff = imp.find_module(partname, | 
					
						
							|  |  |  |                                               parent and parent.__path__) | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     except ImportError: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         m = imp.load_module(fqname, fp, pathname, stuff) | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     finally: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if fp: fp.close() | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     if parent: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         setattr(parent, partname, m) | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     return m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Replacement for reload() | 
					
						
							|  |  |  | def reload_hook(module): | 
					
						
							|  |  |  |     name = module.__name__ | 
					
						
							|  |  |  |     if '.' not in name: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return import_module(name, name, None) | 
					
						
							| 
									
										
										
										
											2001-02-09 09:48:45 +00:00
										 |  |  |     i = name.rfind('.') | 
					
						
							| 
									
										
										
										
											1997-09-09 20:35:20 +00:00
										 |  |  |     pname = name[:i] | 
					
						
							|  |  |  |     parent = sys.modules[pname] | 
					
						
							|  |  |  |     return import_module(name[i+1:], name, parent) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Save the original hooks | 
					
						
							|  |  |  | original_import = __builtin__.__import__ | 
					
						
							|  |  |  | original_reload = __builtin__.reload | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Now install our hooks | 
					
						
							|  |  |  | __builtin__.__import__ = import_hook | 
					
						
							|  |  |  | __builtin__.reload = reload_hook |