blob: ec6730e9ba3921ba4f6eee0e06e8d94b644f9d3c [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()
Antoine Pitrou060cee22009-11-13 16:29:04 +0000146 self.modules_before = support.modules_setup()
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()
Antoine Pitrou060cee22009-11-13 16:29:04 +0000153 support.modules_cleanup(*self.modules_before)
Just van Rossum52e14d62002-12-30 22:08:05 +0000154
155
156class ImportHooksTestCase(ImportHooksBaseTestCase):
157
158 def doTestImports(self, importer=None):
159 import hooktestmodule
160 import hooktestpackage
161 import hooktestpackage.sub
162 import hooktestpackage.sub.subber
163 self.assertEqual(hooktestmodule.get_name(),
164 "hooktestmodule")
165 self.assertEqual(hooktestpackage.get_name(),
166 "hooktestpackage")
167 self.assertEqual(hooktestpackage.sub.get_name(),
168 "hooktestpackage.sub")
169 self.assertEqual(hooktestpackage.sub.subber.get_name(),
170 "hooktestpackage.sub.subber")
171 if importer:
172 self.assertEqual(hooktestmodule.__loader__, importer)
173 self.assertEqual(hooktestpackage.__loader__, importer)
174 self.assertEqual(hooktestpackage.sub.__loader__, importer)
175 self.assertEqual(hooktestpackage.sub.subber.__loader__, importer)
176
Phillip J. Eby7ec642a2004-09-23 04:37:36 +0000177 TestImporter.modules['reloadmodule'] = (False, test_co)
178 import reloadmodule
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000179 self.assertFalse(hasattr(reloadmodule,'reloaded'))
Phillip J. Eby7ec642a2004-09-23 04:37:36 +0000180
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000181 import hooktestpackage.newrel
182 self.assertEqual(hooktestpackage.newrel.get_name(),
183 "hooktestpackage.newrel")
184 self.assertEqual(hooktestpackage.newrel.sub,
185 hooktestpackage.sub)
186
Thomas Wouters477c8d52006-05-27 19:21:47 +0000187 import hooktestpackage.sub.subber.subest as subest
188 self.assertEqual(subest.get_name(),
189 "hooktestpackage.sub.subber.subest")
190 self.assertEqual(subest.sub,
191 hooktestpackage.sub)
192
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000193 import hooktestpackage.futrel
194 self.assertEqual(hooktestpackage.futrel.get_name(),
195 "hooktestpackage.futrel")
196 self.assertEqual(hooktestpackage.futrel.sub,
197 hooktestpackage.sub)
Tim Peters710ab3b2006-02-28 18:30:36 +0000198
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000199 import sub
200 self.assertEqual(sub.get_name(), "sub")
201
Thomas Wouters60254fe2006-05-28 10:46:55 +0000202 import hooktestpackage.oldabs
203 self.assertEqual(hooktestpackage.oldabs.get_name(),
204 "hooktestpackage.oldabs")
205 self.assertEqual(hooktestpackage.oldabs.sub, sub)
206
Thomas Woutersf7f438b2006-02-28 16:09:29 +0000207 import hooktestpackage.newabs
208 self.assertEqual(hooktestpackage.newabs.get_name(),
209 "hooktestpackage.newabs")
210 self.assertEqual(hooktestpackage.newabs.sub, sub)
Tim Peters1cc37382004-09-24 04:36:47 +0000211
Just van Rossum52e14d62002-12-30 22:08:05 +0000212 def testMetaPath(self):
213 i = MetaImporter()
214 sys.meta_path.append(i)
215 self.doTestImports(i)
216
217 def testPathHook(self):
218 sys.path_hooks.append(PathImporter)
219 sys.path.append(test_path)
220 self.doTestImports()
221
222 def testBlocker(self):
223 mname = "exceptions" # an arbitrary harmless builtin module
Benjamin Peterson886af962010-03-21 23:13:07 +0000224 support.unload(mname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000225 sys.meta_path.append(ImportBlocker(mname))
Benjamin Peterson886af962010-03-21 23:13:07 +0000226 self.assertRaises(ImportError, __import__, mname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000227
228 def testImpWrapper(self):
229 i = ImpWrapper()
230 sys.meta_path.append(i)
231 sys.path_hooks.append(ImpWrapper)
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000232 mnames = ("colorsys", "urllib.parse", "distutils.core")
Just van Rossum52e14d62002-12-30 22:08:05 +0000233 for mname in mnames:
234 parent = mname.split(".")[0]
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000235 for n in list(sys.modules):
Just van Rossum52e14d62002-12-30 22:08:05 +0000236 if n.startswith(parent):
237 del sys.modules[n]
238 for mname in mnames:
239 m = __import__(mname, globals(), locals(), ["__dummy__"])
240 m.__loader__ # to make sure we actually handled the import
Georg Brandld68442d2008-07-20 23:21:49 +0000241
Just van Rossum52e14d62002-12-30 22:08:05 +0000242
Neal Norwitz996acf12003-02-17 14:51:41 +0000243def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000244 support.run_unittest(ImportHooksTestCase)
Just van Rossum52e14d62002-12-30 22:08:05 +0000245
246if __name__ == "__main__":
Neal Norwitz996acf12003-02-17 14:51:41 +0000247 test_main()