1 """This module has functions that help you dynamically import modules.
2 """
3
4
5
6 import sys
7 import imp
8 import os.path
9 from gmisclib import die
10
12 """Split a name in the form a/b.c into a, b, c, where
13 a is a search path,
14 b is a module (package) name, and
15 c is a name in the module.
16 """
17 p = None
18 fcn = []
19 if '/' in name:
20 p, name = os.path.split(name)
21 if '.' in name:
22 a = name.split('.')
23 name = a[0]
24 fcn = a[1:]
25 return (p, name, fcn)
26
27
28 -def load(name, path):
29 """Load a module from the specified list of paths.
30 It returns the module, but does not import it.
31 If path is None, only look in sys.path and builtins.
32 If path is an array containing None, replace the None with sys.path.
33 """
34 if path is None:
35 pth = None
36 else:
37 pth = []
38 for d in path:
39 if d is None:
40 pth.extend(sys.path)
41 else:
42 pth.append( d )
43 fd = None
44 imp.acquire_lock()
45 try:
46 fd, pn, desc = imp.find_module(name, pth)
47 except ImportError:
48 try:
49 fd, pn, desc = imp.find_module(name, None)
50 except:
51 die.warn('#ImportError: cannot find "%s" from path=%s' % (name, pth))
52 imp.release_lock()
53 raise
54
55
56 if(name in sys.modules and
57 hasattr(sys.modules[name], '__file__') and
58 os.path.dirname(sys.modules[name].__file__) == os.path.dirname(pn)
59 ):
60 fd.close()
61 tmp = sys.modules[name]
62 imp.release_lock()
63 return tmp
64
65
66 try:
67 pymod = imp.load_module(name, fd, pn, desc)
68 finally:
69 if fd:
70 fd.close()
71 imp.release_lock()
72 die.warn("#ImportError: cannot import %s %s" % (pn, desc))
73 return pymod
74
75
76 load_mod = load
77 load_inc_path = load
78 load_mod_inc_path = load_inc_path
79
80 _ModuleType = type(sys)
81
83 """Load a module.
84 If the module name is in the form a/b,
85 it looks in directory "a" first.
86 If use_sys_path is true, it searches the entire Python path
87
88 It returns the module, but does not import it.
89 This version handles importing packages and functions nicely,
90 but with less control over the search path.
91
92 Usage:
93 - load_named_module('/dir/my_module'), or
94 - load_named_module('foo/my_module'), or
95 - load_named_module('foo/my_module.submodule.function'), or
96 - various combinations.
97 """
98 p, lname, attrlist = split_name(name)
99
100 if use_sys_path:
101 path = list(sys.path)
102 else:
103 path = []
104 if p is not None:
105 path.insert(0, p)
106 try:
107 tmp0 = load(lname, path)
108 except ImportError, x:
109 raise ImportError, "%s in directory '%s'%s" % (str(x), p, ['', ' or sys.path'][use_sys_path])
110
111
112 tmp = tmp0
113 pname = [lname]
114 for a in attrlist:
115 try:
116 tmp = getattr(tmp, a)
117 except AttributeError:
118 if isinstance(tmp, _ModuleType) and hasattr(tmp, '__path__'):
119 try:
120 tmp = load(a, tmp.__path__)
121 except ImportError, x:
122 raise ImportError, "Cannot import %s from package %s at %s (%s)" % (a, '.'.join(pname), tmp.__path__, x)
123 pname.append(a)
124 continue
125 filename = getattr(tmp0, '__file__', None)
126 if filename is None:
127 filename = getattr(tmp0, '__name__', '???')
128 die.info("load_named lookup fails: %s amidst %s" % (a, dir(tmp)))
129 try:
130 xat = " from %s" % tmp0.__path__
131 except AttributeError:
132 xat = ""
133 raise ImportError, "Cannot look up %s from %s%s: attempting %s" % (a, '.'.join(pname), xat, '.'.join(attrlist))
134 else:
135 pname.append(a)
136 return tmp
137
138
139 load_named_module = load_named
140 load_named_fcn = load_named
141 load_fcn = load_named
142
148
149 if __name__ == '__main__':
150 _test()
151