mirror of https://github.com/python/cpython
276 lines
8.7 KiB
Python
276 lines
8.7 KiB
Python
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 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": (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, 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)
|
|
|
|
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'))
|
|
|
|
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.oldabs
|
|
self.assertEqual(hooktestpackage.oldabs.get_name(),
|
|
"hooktestpackage.oldabs")
|
|
self.assertEqual(hooktestpackage.oldabs.sub, 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
|
|
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
|
|
# Delete urllib from modules because urlparse was imported above.
|
|
# Without this hack, test_socket_ssl fails if run in this order:
|
|
# regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
|
|
try:
|
|
del sys.modules['urllib']
|
|
except KeyError:
|
|
pass
|
|
|
|
def test_main():
|
|
test_support.run_unittest(ImportHooksTestCase)
|
|
|
|
if __name__ == "__main__":
|
|
test_main()
|