blob: bf2870dbec5d283417dbee5743919337a531382e [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001import sys
2import imp
3import os
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Just van Rossum52e14d62002-12-30 22:08:05 +00006
7
8test_src = """\
9def get_name():
10 return __name__
11def get_file():
12 return __file__
13"""
14
Thomas Woutersf7f438b2006-02-28 16:09:29 +000015absimp = "import sub\n"
16relimp = "from . import sub\n"
Thomas Wouters477c8d52006-05-27 19:21:47 +000017deeprelimp = "from .... import sub\n"
Thomas Woutersf7f438b2006-02-28 16:09:29 +000018futimp = "from __future__ import absolute_import\n"
19
Phillip J. Eby7ec642a2004-09-23 04:37:36 +000020reload_src = test_src+"""\
21reloaded = True
22"""
23
Just van Rossum52e14d62002-12-30 22:08:05 +000024test_co = compile(test_src, "<???>", "exec")
Phillip J. Eby7ec642a2004-09-23 04:37:36 +000025reload_co = compile(reload_src, "<???>", "exec")
26
Thomas Woutersf7f438b2006-02-28 16:09:29 +000027test2_oldabs_co = compile(absimp + test_src, "<???>", "exec")
28test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec")
29test2_newrel_co = compile(relimp + test_src, "<???>", "exec")
Thomas Wouters477c8d52006-05-27 19:21:47 +000030test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec")
Thomas Woutersf7f438b2006-02-28 16:09:29 +000031test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec")
32
Just van Rossum52e14d62002-12-30 22:08:05 +000033test_path = "!!!_test_!!!"
34
35
Just van Rossum52e14d62002-12-30 22:08:05 +000036class TestImporter:
37
38 modules = {
39 "hooktestmodule": (False, test_co),
40 "hooktestpackage": (True, test_co),
41 "hooktestpackage.sub": (True, test_co),
Thomas Wouters477c8d52006-05-27 19:21:47 +000042 "hooktestpackage.sub.subber": (True, test_co),
Thomas Woutersf7f438b2006-02-28 16:09:29 +000043 "hooktestpackage.oldabs": (False, test2_oldabs_co),
44 "hooktestpackage.newabs": (False, test2_newabs_co),
45 "hooktestpackage.newrel": (False, test2_newrel_co),
Thomas Wouters477c8d52006-05-27 19:21:47 +000046 "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co),
Thomas Woutersf7f438b2006-02-28 16:09:29 +000047 "hooktestpackage.futrel": (False, test2_futrel_co),
48 "sub": (False, test_co),
Phillip J. Eby7ec642a2004-09-23 04:37:36 +000049 "reloadmodule": (False, test_co),
Just van Rossum52e14d62002-12-30 22:08:05 +000050 }
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]
Phillip J. Eby7ec642a2004-09-23 04:37:36 +000070 mod = sys.modules.setdefault(fullname,imp.new_module(fullname))
Just van Rossum52e14d62002-12-30 22:08:05 +000071 mod.__file__ = "<%s>" % self.__class__.__name__
72 mod.__loader__ = self
73 if ispkg:
74 mod.__path__ = self._get__path__()
Georg Brandl7cae87c2006-09-06 06:51:57 +000075 exec(code, mod.__dict__)
Just van Rossum52e14d62002-12-30 22:08:05 +000076 return mod
77
78
79class MetaImporter(TestImporter):
80 def _get__path__(self):
81 return []
82
83class PathImporter(TestImporter):
84 def _get__path__(self):
85 return [self.path]
86
87
88class 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):
Collin Winter3add4d72007-08-29 23:37:32 +000099 raise ImportError("I dare you")
Just van Rossum52e14d62002-12-30 22:08:05 +0000100
101
102class 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
124class 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
139class 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()
Georg Brandld68442d2008-07-20 23:21:49 +0000146 self.modules_before = sys.modules.copy()
Just van Rossum52e14d62002-12-30 22:08:05 +0000147
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()
Georg Brandld68442d2008-07-20 23:21:49 +0000153 sys.modules.clear()
154 sys.modules.update(self.modules_before)
Just van Rossum52e14d62002-12-30 22:08:05 +0000155
156
157class 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
Phillip J. Eby7ec642a2004-09-23 04:37:36 +0000178 TestImporter.modules['reloadmodule'] = (False, test_co)
179 import reloadmodule
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000180 self.assertFalse(hasattr(reloadmodule,'reloaded'))
Phillip J. Eby7ec642a2004-09-23 04:37:36 +0000181
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000182 import hooktestpackage.newrel
183 self.assertEqual(hooktestpackage.newrel.get_name(),
184 "hooktestpackage.newrel")
185 self.assertEqual(hooktestpackage.newrel.sub,
186 hooktestpackage.sub)
187
Thomas Wouters477c8d52006-05-27 19:21:47 +0000188 import hooktestpackage.sub.subber.subest as subest
189 self.assertEqual(subest.get_name(),
190 "hooktestpackage.sub.subber.subest")
191 self.assertEqual(subest.sub,
192 hooktestpackage.sub)
193
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000194 import hooktestpackage.futrel
195 self.assertEqual(hooktestpackage.futrel.get_name(),
196 "hooktestpackage.futrel")
197 self.assertEqual(hooktestpackage.futrel.sub,
198 hooktestpackage.sub)
Tim Peters710ab3b2006-02-28 18:30:36 +0000199
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000200 import sub
201 self.assertEqual(sub.get_name(), "sub")
202
Thomas Wouters60254fe2006-05-28 10:46:55 +0000203 import hooktestpackage.oldabs
204 self.assertEqual(hooktestpackage.oldabs.get_name(),
205 "hooktestpackage.oldabs")
206 self.assertEqual(hooktestpackage.oldabs.sub, sub)
207
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000208 import hooktestpackage.newabs
209 self.assertEqual(hooktestpackage.newabs.get_name(),
210 "hooktestpackage.newabs")
211 self.assertEqual(hooktestpackage.newabs.sub, sub)
Tim Peters1cc37382004-09-24 04:36:47 +0000212
Just van Rossum52e14d62002-12-30 22:08:05 +0000213 def testMetaPath(self):
214 i = MetaImporter()
215 sys.meta_path.append(i)
216 self.doTestImports(i)
217
218 def testPathHook(self):
219 sys.path_hooks.append(PathImporter)
220 sys.path.append(test_path)
221 self.doTestImports()
222
223 def testBlocker(self):
224 mname = "exceptions" # an arbitrary harmless builtin module
225 if mname in sys.modules:
226 del sys.modules[mname]
227 sys.meta_path.append(ImportBlocker(mname))
228 try:
229 __import__(mname)
230 except ImportError:
231 pass
232 else:
233 self.fail("'%s' was not supposed to be importable" % mname)
234
235 def testImpWrapper(self):
236 i = ImpWrapper()
237 sys.meta_path.append(i)
238 sys.path_hooks.append(ImpWrapper)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000239 mnames = ("colorsys", "urllib.parse", "distutils.core")
Just van Rossum52e14d62002-12-30 22:08:05 +0000240 for mname in mnames:
241 parent = mname.split(".")[0]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000242 for n in list(sys.modules):
Just van Rossum52e14d62002-12-30 22:08:05 +0000243 if n.startswith(parent):
244 del sys.modules[n]
245 for mname in mnames:
246 m = __import__(mname, globals(), locals(), ["__dummy__"])
247 m.__loader__ # to make sure we actually handled the import
Georg Brandld68442d2008-07-20 23:21:49 +0000248
Just van Rossum52e14d62002-12-30 22:08:05 +0000249
Neal Norwitz996acf12003-02-17 14:51:41 +0000250def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000251 support.run_unittest(ImportHooksTestCase)
Just van Rossum52e14d62002-12-30 22:08:05 +0000252
253if __name__ == "__main__":
Neal Norwitz996acf12003-02-17 14:51:41 +0000254 test_main()