mirror of
https://github.com/python/cpython.git
synced 2025-10-21 22:22:48 +00:00
Rename importlib.test.support to importlib.test.util.
This commit is contained in:
parent
ae9ad186d0
commit
bcb26c53c0
22 changed files with 163 additions and 191 deletions
153
Lib/importlib/test/util.py
Normal file
153
Lib/importlib/test/util.py
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue