diff options
author | Just van Rossum <just@letterror.com> | 2002-12-30 22:08:05 (GMT) |
---|---|---|
committer | Just van Rossum <just@letterror.com> | 2002-12-30 22:08:05 (GMT) |
commit | 52e14d640be3a7fa2c17f5a2a6bc9626d622aa40 (patch) | |
tree | 417c361ba0bae8b22b262570769933ccdd5ad5e0 /Lib/test/test_importhooks.py | |
parent | 60087fb45092d9c199cea162e58d9193c7c1558c (diff) | |
download | cpython-52e14d640be3a7fa2c17f5a2a6bc9626d622aa40.zip cpython-52e14d640be3a7fa2c17f5a2a6bc9626d622aa40.tar.gz cpython-52e14d640be3a7fa2c17f5a2a6bc9626d622aa40.tar.bz2 |
PEP 302 + zipimport:
- new import hooks in import.c, exposed in the sys module
- new module called 'zipimport'
- various changes to allow bootstrapping from zip files
I hope I didn't break the Windows build (or anything else for that
matter), but then again, it's been sitting on sf long enough...
Regarding the latest discussions on python-dev: zipimport sets
pkg.__path__ as specified in PEP 273, and likewise, sys.path item such as
/path/to/Archive.zip/subdir/ are supported again.
Diffstat (limited to 'Lib/test/test_importhooks.py')
-rw-r--r-- | Lib/test/test_importhooks.py | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/Lib/test/test_importhooks.py b/Lib/test/test_importhooks.py new file mode 100644 index 0000000..070b578 --- /dev/null +++ b/Lib/test/test_importhooks.py @@ -0,0 +1,204 @@ +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__ +""" + +test_co = compile(test_src, "<???>", "exec") +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), + "hooktestpackage.sub.subber": (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 = imp.new_module(fullname) + sys.modules[fullname] = mod + 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) + + 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 + + +if __name__ == "__main__": + test_support.run_unittest(ImportHooksTestCase) |