Package pyamf :: Package util :: Module imports
[hide private]
[frames] | no frames]

Source Code for Module pyamf.util.imports

  1  # Copyright (c) 2007-2009 The PyAMF Project. 
  2  # See LICENSE.txt for details. 
  3   
  4  """ 
  5  Tools for doing dynamic imports. 
  6   
  7  @since: 0.3 
  8  """ 
  9   
 10  import sys 
 11   
 12   
 13  __all__ = ['when_imported'] 
 14   
 15  #: A list of callables to be executed when the module is imported. 
 16  post_load_hooks = {} 
 17  #: List of modules that have already been loaded. 
 18  loaded_modules = [] 
 19   
 20   
21 -class ModuleFinder(object):
22 """ 23 This is a special module finder object that executes a collection of 24 callables when a specific module has been imported. An instance of this 25 is placed in C{sys.meta_path}, which is consulted before C{sys.modules} - 26 allowing us to provide this functionality. 27 28 @see: L{when_imported} 29 @since: 0.5 30 """ 31
32 - def find_module(self, name, path):
33 """ 34 Called when an import is made. If there are hooks waiting for this 35 module to be imported then we stop the normal import process and 36 manually load the module. 37 38 @param name: The name of the module being imported. 39 @param path The root path of the module (if a package). We ignore this. 40 @return: If we want to hook this module, we return a C{loader} 41 interface (which is this instance again). If not we return C{None} 42 to allow the standard import process to continue. 43 """ 44 if name in loaded_modules or name not in post_load_hooks: 45 return None 46 47 return self
48
49 - def load_module(self, name):
50 """ 51 If we get this far, then there are hooks waiting to be called on 52 import of this module. We manually load the module and then run the 53 hooks. 54 55 @param name: The name of the module to import. 56 """ 57 loaded_modules.append(name) 58 parent, child = split_module(name) 59 60 __import__(name, {}, {}, []) 61 62 mod = sys.modules[name] 63 64 run_hooks(name, mod) 65 66 return mod
67 68
69 -def run_hooks(name, module):
70 """ 71 Run all hooks for a module. 72 Load an unactivated "lazy" module object. 73 """ 74 try: 75 for hook in post_load_hooks[name]: 76 hook(module) 77 finally: 78 del post_load_hooks[name]
79 80
81 -def split_module(name):
82 """ 83 Splits a module name into its parent and child parts. 84 85 >>> split_module('foo.bar.baz') 86 'foo.bar', 'baz' 87 >>> split_module('foo') 88 None, 'foo' 89 """ 90 try: 91 splitpos = name.rindex('.') + 1 92 93 return name[:splitpos - 1], name[splitpos:] 94 except ValueError: 95 return None, name
96 97
98 -def when_imported(name, hook):
99 """ 100 Call C{hook(module)} when module named C{name} is first used. 101 102 'hook' must accept one argument: the module object named by 'name', which 103 must be a fully qualified (i.e. absolute) module name. The hook should 104 not raise any exceptions, or it will prevent later hooks from running. 105 106 If the module has already been imported normally, 'hook(module)' is 107 called immediately, and the module object is returned from this function. 108 If the module has not been imported, then the hook is called when the 109 module is first imported. 110 """ 111 if name in loaded_modules or name in sys.modules: 112 hook(sys.modules[name]) 113 114 return 115 116 if name not in post_load_hooks: 117 post_load_hooks[name] = [] 118 119 post_load_hooks[name].append(hook)
120 121 122 # this is required for reloading this module 123 for obj in sys.meta_path: 124 if obj.__class__ is ModuleFinder: 125 break 126 else: 127 sys.meta_path.insert(0, ModuleFinder()) 128