| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  | import sys | 
					
						
							|  |  |  | import imp | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from test import test_support | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test_src = """\
 | 
					
						
							|  |  |  | def get_name(): | 
					
						
							|  |  |  |     return __name__ | 
					
						
							|  |  |  | def get_file(): | 
					
						
							|  |  |  |     return __file__ | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  | absimp = "import sub\n" | 
					
						
							|  |  |  | relimp = "from . import sub\n" | 
					
						
							| 
									
										
										
										
											2006-05-25 11:26:25 +00:00
										 |  |  | deeprelimp = "from .... import sub\n" | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  | futimp = "from __future__ import absolute_import\n" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-23 04:37:36 +00:00
										 |  |  | reload_src = test_src+"""\
 | 
					
						
							|  |  |  | reloaded = True | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  | test_co = compile(test_src, "<???>", "exec") | 
					
						
							| 
									
										
										
										
											2004-09-23 04:37:36 +00:00
										 |  |  | reload_co = compile(reload_src, "<???>", "exec") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  | test2_oldabs_co = compile(absimp + test_src, "<???>", "exec") | 
					
						
							|  |  |  | test2_newabs_co = compile(futimp + absimp + test_src, "<???>", "exec") | 
					
						
							|  |  |  | test2_newrel_co = compile(relimp + test_src, "<???>", "exec") | 
					
						
							| 
									
										
										
										
											2006-05-25 11:26:25 +00:00
										 |  |  | test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec") | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  | test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  | test_path = "!!!_test_!!!" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImportTracker: | 
					
						
							|  |  |  |     """Importer that only tracks attempted imports.""" | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.imports = [] | 
					
						
							|  |  |  |     def find_module(self, fullname, path=None): | 
					
						
							|  |  |  |         self.imports.append(fullname) | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestImporter: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     modules = { | 
					
						
							|  |  |  |         "hooktestmodule": (False, test_co), | 
					
						
							|  |  |  |         "hooktestpackage": (True, test_co), | 
					
						
							|  |  |  |         "hooktestpackage.sub": (True, test_co), | 
					
						
							| 
									
										
										
										
											2006-05-25 11:26:25 +00:00
										 |  |  |         "hooktestpackage.sub.subber": (True, test_co), | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  |         "hooktestpackage.oldabs": (False, test2_oldabs_co), | 
					
						
							|  |  |  |         "hooktestpackage.newabs": (False, test2_newabs_co), | 
					
						
							|  |  |  |         "hooktestpackage.newrel": (False, test2_newrel_co), | 
					
						
							| 
									
										
										
										
											2006-05-25 11:26:25 +00:00
										 |  |  |         "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co), | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  |         "hooktestpackage.futrel": (False, test2_futrel_co), | 
					
						
							|  |  |  |         "sub": (False, test_co), | 
					
						
							| 
									
										
										
										
											2004-09-23 04:37:36 +00:00
										 |  |  |         "reloadmodule": (False, test_co), | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, path=test_path): | 
					
						
							|  |  |  |         if path != test_path: | 
					
						
							|  |  |  |             # if out class is on sys.path_hooks, we must raise | 
					
						
							|  |  |  |             # ImportError for any path item that we can't handle. | 
					
						
							|  |  |  |             raise ImportError | 
					
						
							|  |  |  |         self.path = path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _get__path__(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def find_module(self, fullname, path=None): | 
					
						
							|  |  |  |         if fullname in self.modules: | 
					
						
							|  |  |  |             return self | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_module(self, fullname): | 
					
						
							|  |  |  |         ispkg, code = self.modules[fullname] | 
					
						
							| 
									
										
										
										
											2004-09-23 04:37:36 +00:00
										 |  |  |         mod = sys.modules.setdefault(fullname,imp.new_module(fullname)) | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  |         mod.__file__ = "<%s>" % self.__class__.__name__ | 
					
						
							|  |  |  |         mod.__loader__ = self | 
					
						
							|  |  |  |         if ispkg: | 
					
						
							|  |  |  |             mod.__path__ = self._get__path__() | 
					
						
							|  |  |  |         exec code in mod.__dict__ | 
					
						
							|  |  |  |         return mod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MetaImporter(TestImporter): | 
					
						
							|  |  |  |     def _get__path__(self): | 
					
						
							|  |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PathImporter(TestImporter): | 
					
						
							|  |  |  |     def _get__path__(self): | 
					
						
							|  |  |  |         return [self.path] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImportBlocker: | 
					
						
							|  |  |  |     """Place an ImportBlocker instance on sys.meta_path and you
 | 
					
						
							|  |  |  |     can be sure the modules you specified can't be imported, even | 
					
						
							|  |  |  |     if it's a builtin.""" | 
					
						
							|  |  |  |     def __init__(self, *namestoblock): | 
					
						
							|  |  |  |         self.namestoblock = dict.fromkeys(namestoblock) | 
					
						
							|  |  |  |     def find_module(self, fullname, path=None): | 
					
						
							|  |  |  |         if fullname in self.namestoblock: | 
					
						
							|  |  |  |             return self | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     def load_module(self, fullname): | 
					
						
							|  |  |  |         raise ImportError, "I dare you" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImpWrapper: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, path=None): | 
					
						
							|  |  |  |         if path is not None and not os.path.isdir(path): | 
					
						
							|  |  |  |             raise ImportError | 
					
						
							|  |  |  |         self.path = path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def find_module(self, fullname, path=None): | 
					
						
							|  |  |  |         subname = fullname.split(".")[-1] | 
					
						
							|  |  |  |         if subname != fullname and self.path is None: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         if self.path is None: | 
					
						
							|  |  |  |             path = None | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             path = [self.path] | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             file, filename, stuff = imp.find_module(subname, path) | 
					
						
							|  |  |  |         except ImportError: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return ImpLoader(file, filename, stuff) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImpLoader: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, file, filename, stuff): | 
					
						
							|  |  |  |         self.file = file | 
					
						
							|  |  |  |         self.filename = filename | 
					
						
							|  |  |  |         self.stuff = stuff | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def load_module(self, fullname): | 
					
						
							|  |  |  |         mod = imp.load_module(fullname, self.file, self.filename, self.stuff) | 
					
						
							|  |  |  |         if self.file: | 
					
						
							|  |  |  |             self.file.close() | 
					
						
							|  |  |  |         mod.__loader__ = self  # for introspection | 
					
						
							|  |  |  |         return mod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImportHooksBaseTestCase(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         self.path = sys.path[:] | 
					
						
							|  |  |  |         self.meta_path = sys.meta_path[:] | 
					
						
							|  |  |  |         self.path_hooks = sys.path_hooks[:] | 
					
						
							|  |  |  |         sys.path_importer_cache.clear() | 
					
						
							|  |  |  |         self.tracker = ImportTracker() | 
					
						
							|  |  |  |         sys.meta_path.insert(0, self.tracker) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         sys.path[:] = self.path | 
					
						
							|  |  |  |         sys.meta_path[:] = self.meta_path | 
					
						
							|  |  |  |         sys.path_hooks[:] = self.path_hooks | 
					
						
							|  |  |  |         sys.path_importer_cache.clear() | 
					
						
							|  |  |  |         for fullname in self.tracker.imports: | 
					
						
							|  |  |  |             if fullname in sys.modules: | 
					
						
							|  |  |  |                 del sys.modules[fullname] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ImportHooksTestCase(ImportHooksBaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def doTestImports(self, importer=None): | 
					
						
							|  |  |  |         import hooktestmodule | 
					
						
							|  |  |  |         import hooktestpackage | 
					
						
							|  |  |  |         import hooktestpackage.sub | 
					
						
							|  |  |  |         import hooktestpackage.sub.subber | 
					
						
							|  |  |  |         self.assertEqual(hooktestmodule.get_name(), | 
					
						
							|  |  |  |                          "hooktestmodule") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.sub.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.sub") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.sub.subber.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.sub.subber") | 
					
						
							|  |  |  |         if importer: | 
					
						
							|  |  |  |             self.assertEqual(hooktestmodule.__loader__, importer) | 
					
						
							|  |  |  |             self.assertEqual(hooktestpackage.__loader__, importer) | 
					
						
							|  |  |  |             self.assertEqual(hooktestpackage.sub.__loader__, importer) | 
					
						
							|  |  |  |             self.assertEqual(hooktestpackage.sub.subber.__loader__, importer) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-23 04:37:36 +00:00
										 |  |  |         TestImporter.modules['reloadmodule'] = (False, test_co) | 
					
						
							|  |  |  |         import reloadmodule | 
					
						
							|  |  |  |         self.failIf(hasattr(reloadmodule,'reloaded')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TestImporter.modules['reloadmodule'] = (False, reload_co) | 
					
						
							|  |  |  |         reload(reloadmodule) | 
					
						
							|  |  |  |         self.failUnless(hasattr(reloadmodule,'reloaded')) | 
					
						
							| 
									
										
										
										
											2006-02-28 18:30:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  |         import hooktestpackage.oldabs | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.oldabs.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.oldabs") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.oldabs.sub, | 
					
						
							|  |  |  |                          hooktestpackage.sub) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import hooktestpackage.newrel | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.newrel.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.newrel") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.newrel.sub, | 
					
						
							|  |  |  |                          hooktestpackage.sub) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-25 11:26:25 +00:00
										 |  |  |         import hooktestpackage.sub.subber.subest as subest | 
					
						
							|  |  |  |         self.assertEqual(subest.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.sub.subber.subest") | 
					
						
							|  |  |  |         self.assertEqual(subest.sub, | 
					
						
							|  |  |  |                          hooktestpackage.sub) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  |         import hooktestpackage.futrel | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.futrel.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.futrel") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.futrel.sub, | 
					
						
							|  |  |  |                          hooktestpackage.sub) | 
					
						
							| 
									
										
										
										
											2006-02-28 18:30:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-28 16:09:29 +00:00
										 |  |  |         import sub | 
					
						
							|  |  |  |         self.assertEqual(sub.get_name(), "sub") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import hooktestpackage.newabs | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.newabs.get_name(), | 
					
						
							|  |  |  |                          "hooktestpackage.newabs") | 
					
						
							|  |  |  |         self.assertEqual(hooktestpackage.newabs.sub, sub) | 
					
						
							| 
									
										
										
										
											2004-09-24 04:36:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  |     def testMetaPath(self): | 
					
						
							|  |  |  |         i = MetaImporter() | 
					
						
							|  |  |  |         sys.meta_path.append(i) | 
					
						
							|  |  |  |         self.doTestImports(i) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def testPathHook(self): | 
					
						
							|  |  |  |         sys.path_hooks.append(PathImporter) | 
					
						
							|  |  |  |         sys.path.append(test_path) | 
					
						
							|  |  |  |         self.doTestImports() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def testBlocker(self): | 
					
						
							|  |  |  |         mname = "exceptions"  # an arbitrary harmless builtin module | 
					
						
							|  |  |  |         if mname in sys.modules: | 
					
						
							|  |  |  |             del sys.modules[mname] | 
					
						
							|  |  |  |         sys.meta_path.append(ImportBlocker(mname)) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             __import__(mname) | 
					
						
							|  |  |  |         except ImportError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("'%s' was not supposed to be importable" % mname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def testImpWrapper(self): | 
					
						
							|  |  |  |         i = ImpWrapper() | 
					
						
							|  |  |  |         sys.meta_path.append(i) | 
					
						
							|  |  |  |         sys.path_hooks.append(ImpWrapper) | 
					
						
							|  |  |  |         mnames = ("colorsys", "urlparse", "distutils.core", "compiler.misc") | 
					
						
							|  |  |  |         for mname in mnames: | 
					
						
							|  |  |  |             parent = mname.split(".")[0] | 
					
						
							|  |  |  |             for n in sys.modules.keys(): | 
					
						
							|  |  |  |                 if n.startswith(parent): | 
					
						
							|  |  |  |                     del sys.modules[n] | 
					
						
							|  |  |  |         for mname in mnames: | 
					
						
							|  |  |  |             m = __import__(mname, globals(), locals(), ["__dummy__"]) | 
					
						
							|  |  |  |             m.__loader__  # to make sure we actually handled the import | 
					
						
							| 
									
										
										
										
											2006-03-09 01:15:05 +00:00
										 |  |  |         # Delete urllib from modules because urlparse was imported above. | 
					
						
							| 
									
										
										
										
											2006-03-04 23:13:41 +00:00
										 |  |  |         # Without this hack, test_socket_ssl fails if run in this order: | 
					
						
							|  |  |  |         # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl | 
					
						
							| 
									
										
										
										
											2006-03-04 23:56:53 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             del sys.modules['urllib'] | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-17 14:51:41 +00:00
										 |  |  | def test_main(): | 
					
						
							|  |  |  |     test_support.run_unittest(ImportHooksTestCase) | 
					
						
							| 
									
										
										
										
											2002-12-30 22:08:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2003-02-17 14:51:41 +00:00
										 |  |  |     test_main() |