1 | import sys
|
---|
2 | import imp
|
---|
3 | import os
|
---|
4 | import unittest
|
---|
5 | from test import test_support
|
---|
6 |
|
---|
7 |
|
---|
8 | test_src = """\
|
---|
9 | def get_name():
|
---|
10 | return __name__
|
---|
11 | def get_file():
|
---|
12 | return __file__
|
---|
13 | """
|
---|
14 |
|
---|
15 | absimp = "import sub\n"
|
---|
16 | relimp = "from . import sub\n"
|
---|
17 | deeprelimp = "from .... import sub\n"
|
---|
18 | futimp = "from __future__ import absolute_import\n"
|
---|
19 |
|
---|
20 | reload_src = test_src+"""\
|
---|
21 | reloaded = True
|
---|
22 | """
|
---|
23 |
|
---|
24 | test_co = compile(test_src, "<???>", "exec")
|
---|
25 | reload_co = compile(reload_src, "<???>", "exec")
|
---|
26 |
|
---|
27 | test2_oldabs_co = compile(absimp + test_src, "<???>", "exec")
|
---|
28 | test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec")
|
---|
29 | test2_newrel_co = compile(relimp + test_src, "<???>", "exec")
|
---|
30 | test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec")
|
---|
31 | test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec")
|
---|
32 |
|
---|
33 | test_path = "!!!_test_!!!"
|
---|
34 |
|
---|
35 |
|
---|
36 | class TestImporter:
|
---|
37 |
|
---|
38 | modules = {
|
---|
39 | "hooktestmodule": (False, test_co),
|
---|
40 | "hooktestpackage": (True, test_co),
|
---|
41 | "hooktestpackage.sub": (True, test_co),
|
---|
42 | "hooktestpackage.sub.subber": (True, test_co),
|
---|
43 | "hooktestpackage.oldabs": (False, test2_oldabs_co),
|
---|
44 | "hooktestpackage.newabs": (False, test2_newabs_co),
|
---|
45 | "hooktestpackage.newrel": (False, test2_newrel_co),
|
---|
46 | "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co),
|
---|
47 | "hooktestpackage.futrel": (False, test2_futrel_co),
|
---|
48 | "sub": (False, test_co),
|
---|
49 | "reloadmodule": (False, test_co),
|
---|
50 | }
|
---|
51 |
|
---|
52 | def __init__(self, path=test_path):
|
---|
53 | if path != test_path:
|
---|
54 | # if out class is on sys.path_hooks, we must raise
|
---|
55 | # ImportError for any path item that we can't handle.
|
---|
56 | raise ImportError
|
---|
57 | self.path = path
|
---|
58 |
|
---|
59 | def _get__path__(self):
|
---|
60 | raise NotImplementedError
|
---|
61 |
|
---|
62 | def find_module(self, fullname, path=None):
|
---|
63 | if fullname in self.modules:
|
---|
64 | return self
|
---|
65 | else:
|
---|
66 | return None
|
---|
67 |
|
---|
68 | def load_module(self, fullname):
|
---|
69 | ispkg, code = self.modules[fullname]
|
---|
70 | mod = sys.modules.setdefault(fullname,imp.new_module(fullname))
|
---|
71 | mod.__file__ = "<%s>" % self.__class__.__name__
|
---|
72 | mod.__loader__ = self
|
---|
73 | if ispkg:
|
---|
74 | mod.__path__ = self._get__path__()
|
---|
75 | exec code in mod.__dict__
|
---|
76 | return mod
|
---|
77 |
|
---|
78 |
|
---|
79 | class MetaImporter(TestImporter):
|
---|
80 | def _get__path__(self):
|
---|
81 | return []
|
---|
82 |
|
---|
83 | class PathImporter(TestImporter):
|
---|
84 | def _get__path__(self):
|
---|
85 | return [self.path]
|
---|
86 |
|
---|
87 |
|
---|
88 | class ImportBlocker:
|
---|
89 | """Place an ImportBlocker instance on sys.meta_path and you
|
---|
90 | can be sure the modules you specified can't be imported, even
|
---|
91 | if it's a builtin."""
|
---|
92 | def __init__(self, *namestoblock):
|
---|
93 | self.namestoblock = dict.fromkeys(namestoblock)
|
---|
94 | def find_module(self, fullname, path=None):
|
---|
95 | if fullname in self.namestoblock:
|
---|
96 | return self
|
---|
97 | return None
|
---|
98 | def load_module(self, fullname):
|
---|
99 | raise ImportError, "I dare you"
|
---|
100 |
|
---|
101 |
|
---|
102 | class ImpWrapper:
|
---|
103 |
|
---|
104 | def __init__(self, path=None):
|
---|
105 | if path is not None and not os.path.isdir(path):
|
---|
106 | raise ImportError
|
---|
107 | self.path = path
|
---|
108 |
|
---|
109 | def find_module(self, fullname, path=None):
|
---|
110 | subname = fullname.split(".")[-1]
|
---|
111 | if subname != fullname and self.path is None:
|
---|
112 | return None
|
---|
113 | if self.path is None:
|
---|
114 | path = None
|
---|
115 | else:
|
---|
116 | path = [self.path]
|
---|
117 | try:
|
---|
118 | file, filename, stuff = imp.find_module(subname, path)
|
---|
119 | except ImportError:
|
---|
120 | return None
|
---|
121 | return ImpLoader(file, filename, stuff)
|
---|
122 |
|
---|
123 |
|
---|
124 | class ImpLoader:
|
---|
125 |
|
---|
126 | def __init__(self, file, filename, stuff):
|
---|
127 | self.file = file
|
---|
128 | self.filename = filename
|
---|
129 | self.stuff = stuff
|
---|
130 |
|
---|
131 | def load_module(self, fullname):
|
---|
132 | mod = imp.load_module(fullname, self.file, self.filename, self.stuff)
|
---|
133 | if self.file:
|
---|
134 | self.file.close()
|
---|
135 | mod.__loader__ = self # for introspection
|
---|
136 | return mod
|
---|
137 |
|
---|
138 |
|
---|
139 | class ImportHooksBaseTestCase(unittest.TestCase):
|
---|
140 |
|
---|
141 | def setUp(self):
|
---|
142 | self.path = sys.path[:]
|
---|
143 | self.meta_path = sys.meta_path[:]
|
---|
144 | self.path_hooks = sys.path_hooks[:]
|
---|
145 | sys.path_importer_cache.clear()
|
---|
146 | self.modules_before = sys.modules.copy()
|
---|
147 |
|
---|
148 | def tearDown(self):
|
---|
149 | sys.path[:] = self.path
|
---|
150 | sys.meta_path[:] = self.meta_path
|
---|
151 | sys.path_hooks[:] = self.path_hooks
|
---|
152 | sys.path_importer_cache.clear()
|
---|
153 | sys.modules.clear()
|
---|
154 | sys.modules.update(self.modules_before)
|
---|
155 |
|
---|
156 |
|
---|
157 | class ImportHooksTestCase(ImportHooksBaseTestCase):
|
---|
158 |
|
---|
159 | def doTestImports(self, importer=None):
|
---|
160 | import hooktestmodule
|
---|
161 | import hooktestpackage
|
---|
162 | import hooktestpackage.sub
|
---|
163 | import hooktestpackage.sub.subber
|
---|
164 | self.assertEqual(hooktestmodule.get_name(),
|
---|
165 | "hooktestmodule")
|
---|
166 | self.assertEqual(hooktestpackage.get_name(),
|
---|
167 | "hooktestpackage")
|
---|
168 | self.assertEqual(hooktestpackage.sub.get_name(),
|
---|
169 | "hooktestpackage.sub")
|
---|
170 | self.assertEqual(hooktestpackage.sub.subber.get_name(),
|
---|
171 | "hooktestpackage.sub.subber")
|
---|
172 | if importer:
|
---|
173 | self.assertEqual(hooktestmodule.__loader__, importer)
|
---|
174 | self.assertEqual(hooktestpackage.__loader__, importer)
|
---|
175 | self.assertEqual(hooktestpackage.sub.__loader__, importer)
|
---|
176 | self.assertEqual(hooktestpackage.sub.subber.__loader__, importer)
|
---|
177 |
|
---|
178 | TestImporter.modules['reloadmodule'] = (False, test_co)
|
---|
179 | import reloadmodule
|
---|
180 | self.assertFalse(hasattr(reloadmodule,'reloaded'))
|
---|
181 |
|
---|
182 | TestImporter.modules['reloadmodule'] = (False, reload_co)
|
---|
183 | imp.reload(reloadmodule)
|
---|
184 | self.assertTrue(hasattr(reloadmodule,'reloaded'))
|
---|
185 |
|
---|
186 | import hooktestpackage.oldabs
|
---|
187 | self.assertEqual(hooktestpackage.oldabs.get_name(),
|
---|
188 | "hooktestpackage.oldabs")
|
---|
189 | self.assertEqual(hooktestpackage.oldabs.sub,
|
---|
190 | hooktestpackage.sub)
|
---|
191 |
|
---|
192 | import hooktestpackage.newrel
|
---|
193 | self.assertEqual(hooktestpackage.newrel.get_name(),
|
---|
194 | "hooktestpackage.newrel")
|
---|
195 | self.assertEqual(hooktestpackage.newrel.sub,
|
---|
196 | hooktestpackage.sub)
|
---|
197 |
|
---|
198 | import hooktestpackage.sub.subber.subest as subest
|
---|
199 | self.assertEqual(subest.get_name(),
|
---|
200 | "hooktestpackage.sub.subber.subest")
|
---|
201 | self.assertEqual(subest.sub,
|
---|
202 | hooktestpackage.sub)
|
---|
203 |
|
---|
204 | import hooktestpackage.futrel
|
---|
205 | self.assertEqual(hooktestpackage.futrel.get_name(),
|
---|
206 | "hooktestpackage.futrel")
|
---|
207 | self.assertEqual(hooktestpackage.futrel.sub,
|
---|
208 | hooktestpackage.sub)
|
---|
209 |
|
---|
210 | import sub
|
---|
211 | self.assertEqual(sub.get_name(), "sub")
|
---|
212 |
|
---|
213 | import hooktestpackage.newabs
|
---|
214 | self.assertEqual(hooktestpackage.newabs.get_name(),
|
---|
215 | "hooktestpackage.newabs")
|
---|
216 | self.assertEqual(hooktestpackage.newabs.sub, sub)
|
---|
217 |
|
---|
218 | def testMetaPath(self):
|
---|
219 | i = MetaImporter()
|
---|
220 | sys.meta_path.append(i)
|
---|
221 | self.doTestImports(i)
|
---|
222 |
|
---|
223 | def testPathHook(self):
|
---|
224 | sys.path_hooks.append(PathImporter)
|
---|
225 | sys.path.append(test_path)
|
---|
226 | self.doTestImports()
|
---|
227 |
|
---|
228 | def testBlocker(self):
|
---|
229 | mname = "exceptions" # an arbitrary harmless builtin module
|
---|
230 | test_support.unload(mname)
|
---|
231 | sys.meta_path.append(ImportBlocker(mname))
|
---|
232 | self.assertRaises(ImportError, __import__, mname)
|
---|
233 |
|
---|
234 | def testImpWrapper(self):
|
---|
235 | i = ImpWrapper()
|
---|
236 | sys.meta_path.append(i)
|
---|
237 | sys.path_hooks.append(ImpWrapper)
|
---|
238 | mnames = ("colorsys", "urlparse", "distutils.core", "compiler.misc")
|
---|
239 | for mname in mnames:
|
---|
240 | parent = mname.split(".")[0]
|
---|
241 | for n in sys.modules.keys():
|
---|
242 | if n.startswith(parent):
|
---|
243 | del sys.modules[n]
|
---|
244 | with test_support.check_warnings(("The compiler package is deprecated "
|
---|
245 | "and removed", DeprecationWarning)):
|
---|
246 | for mname in mnames:
|
---|
247 | m = __import__(mname, globals(), locals(), ["__dummy__"])
|
---|
248 | m.__loader__ # to make sure we actually handled the import
|
---|
249 |
|
---|
250 |
|
---|
251 | def test_main():
|
---|
252 | test_support.run_unittest(ImportHooksTestCase)
|
---|
253 |
|
---|
254 | if __name__ == "__main__":
|
---|
255 | test_main()
|
---|