summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/test/util.py
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2009-02-01 04:00:05 (GMT)
committerBrett Cannon <bcannon@gmail.com>2009-02-01 04:00:05 (GMT)
commitbcb26c53c095c7bcd0e5415088e25dbd27f12592 (patch)
tree35240e335dd91a385c13935ddc64b33d9c17a8ad /Lib/importlib/test/util.py
parentae9ad186d058c5700d0692e2f3b026e95639f5cf (diff)
downloadcpython-bcb26c53c095c7bcd0e5415088e25dbd27f12592.zip
cpython-bcb26c53c095c7bcd0e5415088e25dbd27f12592.tar.gz
cpython-bcb26c53c095c7bcd0e5415088e25dbd27f12592.tar.bz2
Rename importlib.test.support to importlib.test.util.
Diffstat (limited to 'Lib/importlib/test/util.py')
-rw-r--r--Lib/importlib/test/util.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/Lib/importlib/test/util.py b/Lib/importlib/test/util.py
new file mode 100644
index 0000000..1518d74
--- /dev/null
+++ b/Lib/importlib/test/util.py
@@ -0,0 +1,153 @@
+from importlib import Import
+
+from contextlib import contextmanager
+from functools import update_wrapper
+import imp
+import os.path
+from test.support import unlink
+import sys
+
+
+using___import__ = False
+
+def import_(*args, **kwargs):
+ """Delegate to allow for injecting different implementations of import."""
+ if using___import__:
+ return __import__(*args, **kwargs)
+ return Import()(*args, **kwargs)
+
+def importlib_only(fxn):
+ """Decorator to mark which tests are not supported by the current
+ implementation of __import__()."""
+ def inner(*args, **kwargs):
+ if using___import__:
+ return
+ else:
+ return fxn(*args, **kwargs)
+ update_wrapper(inner, fxn)
+ return inner
+
+
+def case_insensitive_tests(class_):
+ """Class decorator that nullifies tests that require a case-insensitive
+ file system."""
+ if sys.platform not in ('win32', 'darwin', 'cygwin'):
+ return object()
+ else:
+ return class_
+
+
+@contextmanager
+def uncache(*names):
+ """Uncache a module from sys.modules.
+
+ A basic sanity check is performed to prevent uncaching modules that either
+ cannot/shouldn't be uncached.
+
+ """
+ for name in names:
+ if name in ('sys', 'marshal', 'imp'):
+ raise ValueError(
+ "cannot uncache {0} as it will break _importlib".format(name))
+ try:
+ del sys.modules[name]
+ except KeyError:
+ pass
+ try:
+ yield
+ finally:
+ for name in names:
+ try:
+ del sys.modules[name]
+ except KeyError:
+ pass
+
+@contextmanager
+def import_state(**kwargs):
+ """Context manager to manage the various importers and stored state in the
+ sys module.
+
+ The 'modules' attribute is not supported as the interpreter state stores a
+ pointer to the dict that the interpreter uses internally;
+ reassigning to sys.modules does not have the desired effect.
+
+ """
+ originals = {}
+ try:
+ for attr, default in (('meta_path', []), ('path', []),
+ ('path_hooks', []),
+ ('path_importer_cache', {})):
+ originals[attr] = getattr(sys, attr)
+ if attr in kwargs:
+ new_value = kwargs[attr]
+ del kwargs[attr]
+ else:
+ new_value = default
+ setattr(sys, attr, new_value)
+ if len(kwargs):
+ raise ValueError(
+ 'unrecognized arguments: {0}'.format(kwargs.keys()))
+ yield
+ finally:
+ for attr, value in originals.items():
+ setattr(sys, attr, value)
+
+
+class mock_modules:
+
+ """A mock importer/loader."""
+
+ def __init__(self, *names):
+ self.modules = {}
+ for name in names:
+ if not name.endswith('.__init__'):
+ import_name = name
+ else:
+ import_name = name[:-len('.__init__')]
+ if '.' not in name:
+ package = None
+ elif import_name == name:
+ package = name.rsplit('.', 1)[0]
+ else:
+ package = import_name
+ module = imp.new_module(import_name)
+ module.__loader__ = self
+ module.__file__ = '<mock __file__>'
+ module.__package__ = package
+ module.attr = name
+ if import_name != name:
+ module.__path__ = ['<mock __path__>']
+ self.modules[import_name] = module
+
+ def __getitem__(self, name):
+ return self.modules[name]
+
+ def find_module(self, fullname, path=None):
+ if fullname not in self.modules:
+ return None
+ else:
+ return self
+
+ def load_module(self, fullname):
+ if fullname not in self.modules:
+ raise ImportError
+ else:
+ sys.modules[fullname] = self.modules[fullname]
+ return self.modules[fullname]
+
+ def __enter__(self):
+ self._uncache = uncache(*self.modules.keys())
+ self._uncache.__enter__()
+ return self
+
+ def __exit__(self, *exc_info):
+ self._uncache.__exit__(None, None, None)
+
+
+def mock_path_hook(*entries, importer):
+ """A mock sys.path_hooks entry."""
+ def hook(entry):
+ if entry not in entries:
+ raise ImportError
+ return importer
+ return hook