| 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__ | |
| """ | |
| absimp = "import sub\n" | |
| relimp = "from . import sub\n" | |
| deeprelimp = "from .... import sub\n" | |
| futimp = "from __future__ import absolute_import\n" | |
| reload_src = test_src+"""\ | |
| reloaded = True | |
| """ | |
| test_co = compile(test_src, "<???>", "exec") | |
| reload_co = compile(reload_src, "<???>", "exec") | |
| 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") | |
| test2_deeprel_co = compile(deeprelimp + test_src, "<???>", "exec") | |
| test2_futrel_co = compile(futimp + relimp + test_src, "<???>", "exec") | |
| test_path = "!!!_test_!!!" | |
| class TestImporter: | |
| modules = { | |
| "hooktestmodule": (False, test_co), | |
| "hooktestpackage": (True, test_co), | |
| "hooktestpackage.sub": (True, test_co), | |
| "hooktestpackage.sub.subber": (True, test_co), | |
| "hooktestpackage.oldabs": (False, test2_oldabs_co), | |
| "hooktestpackage.newabs": (False, test2_newabs_co), | |
| "hooktestpackage.newrel": (False, test2_newrel_co), | |
| "hooktestpackage.sub.subber.subest": (True, test2_deeprel_co), | |
| "hooktestpackage.futrel": (False, test2_futrel_co), | |
| "sub": (False, test_co), | |
| "reloadmodule": (False, test_co), | |
| } | |
| 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] | |
| mod = sys.modules.setdefault(fullname,imp.new_module(fullname)) | |
| 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.modules_before = sys.modules.copy() | |
| def tearDown(self): | |
| sys.path[:] = self.path | |
| sys.meta_path[:] = self.meta_path | |
| sys.path_hooks[:] = self.path_hooks | |
| sys.path_importer_cache.clear() | |
| sys.modules.clear() | |
| sys.modules.update(self.modules_before) | |
| 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) | |
| TestImporter.modules['reloadmodule'] = (False, test_co) | |
| import reloadmodule | |
| self.assertFalse(hasattr(reloadmodule,'reloaded')) | |
| TestImporter.modules['reloadmodule'] = (False, reload_co) | |
| imp.reload(reloadmodule) | |
| self.assertTrue(hasattr(reloadmodule,'reloaded')) | |
| 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) | |
| import hooktestpackage.sub.subber.subest as subest | |
| self.assertEqual(subest.get_name(), | |
| "hooktestpackage.sub.subber.subest") | |
| self.assertEqual(subest.sub, | |
| hooktestpackage.sub) | |
| import hooktestpackage.futrel | |
| self.assertEqual(hooktestpackage.futrel.get_name(), | |
| "hooktestpackage.futrel") | |
| self.assertEqual(hooktestpackage.futrel.sub, | |
| hooktestpackage.sub) | |
| 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) | |
| 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 | |
| test_support.unload(mname) | |
| sys.meta_path.append(ImportBlocker(mname)) | |
| self.assertRaises(ImportError, __import__, 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] | |
| with test_support.check_warnings(("The compiler package is deprecated " | |
| "and removed", DeprecationWarning)): | |
| for mname in mnames: | |
| m = __import__(mname, globals(), locals(), ["__dummy__"]) | |
| m.__loader__ # to make sure we actually handled the import | |
| def test_main(): | |
| test_support.run_unittest(ImportHooksTestCase) | |
| if __name__ == "__main__": | |
| test_main() |