mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
Issue #19712: Update test.test_importlib.import_ to test/use PEP 451
where appropriate.
This commit is contained in:
parent
010ff584bc
commit
86aae6a7b3
8 changed files with 114 additions and 61 deletions
|
@ -36,7 +36,7 @@ class Using__package__:
|
|||
|
||||
def test_using___package__(self):
|
||||
# [__package__]
|
||||
with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
|
||||
with self.mock_modules('pkg.__init__', 'pkg.fake') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__('pkg.fake')
|
||||
module = self.__import__('',
|
||||
|
@ -49,7 +49,7 @@ class Using__package__:
|
|||
globals_ = {'__name__': 'pkg.fake', '__path__': []}
|
||||
if package_as_None:
|
||||
globals_['__package__'] = None
|
||||
with util.mock_modules('pkg.__init__', 'pkg.fake') as importer:
|
||||
with self.mock_modules('pkg.__init__', 'pkg.fake') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__('pkg.fake')
|
||||
module = self.__import__('', globals= globals_,
|
||||
|
@ -70,11 +70,20 @@ class Using__package__:
|
|||
with self.assertRaises(TypeError):
|
||||
self.__import__('', globals, {}, ['relimport'], 1)
|
||||
|
||||
Frozen_UsingPackage, Source_UsingPackage = util.test_both(
|
||||
Using__package__, __import__=import_util.__import__)
|
||||
class Using__package__PEP302(Using__package__):
|
||||
mock_modules = util.mock_modules
|
||||
|
||||
Frozen_UsingPackagePEP302, Source_UsingPackagePEP302 = util.test_both(
|
||||
Using__package__PEP302, __import__=import_util.__import__)
|
||||
|
||||
class Using__package__PEP302(Using__package__):
|
||||
mock_modules = util.mock_spec
|
||||
|
||||
Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both(
|
||||
Using__package__PEP302, __import__=import_util.__import__)
|
||||
|
||||
|
||||
class Setting__package__(unittest.TestCase):
|
||||
class Setting__package__:
|
||||
|
||||
"""Because __package__ is a new feature, it is not always set by a loader.
|
||||
Import will set it as needed to help with the transition to relying on
|
||||
|
@ -90,7 +99,7 @@ class Setting__package__(unittest.TestCase):
|
|||
|
||||
# [top-level]
|
||||
def test_top_level(self):
|
||||
with util.mock_modules('top_level') as mock:
|
||||
with self.mock_modules('top_level') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['top_level'].__package__
|
||||
module = self.__import__('top_level')
|
||||
|
@ -98,7 +107,7 @@ class Setting__package__(unittest.TestCase):
|
|||
|
||||
# [package]
|
||||
def test_package(self):
|
||||
with util.mock_modules('pkg.__init__') as mock:
|
||||
with self.mock_modules('pkg.__init__') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['pkg'].__package__
|
||||
module = self.__import__('pkg')
|
||||
|
@ -106,13 +115,19 @@ class Setting__package__(unittest.TestCase):
|
|||
|
||||
# [submodule]
|
||||
def test_submodule(self):
|
||||
with util.mock_modules('pkg.__init__', 'pkg.mod') as mock:
|
||||
with self.mock_modules('pkg.__init__', 'pkg.mod') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
del mock['pkg.mod'].__package__
|
||||
pkg = self.__import__('pkg.mod')
|
||||
module = getattr(pkg, 'mod')
|
||||
self.assertEqual(module.__package__, 'pkg')
|
||||
|
||||
class Setting__package__PEP302(Setting__package__, unittest.TestCase):
|
||||
mock_modules = util.mock_modules
|
||||
|
||||
class Setting__package__PEP451(Setting__package__, unittest.TestCase):
|
||||
mock_modules = util.mock_spec
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -39,6 +39,16 @@ class UseCache:
|
|||
self.__import__(name)
|
||||
self.assertEqual(cm.exception.name, name)
|
||||
|
||||
Frozen_UseCache, Source_UseCache = util.test_both(
|
||||
UseCache, __import__=import_util.__import__)
|
||||
|
||||
|
||||
class ImportlibUseCache(UseCache, unittest.TestCase):
|
||||
|
||||
# Pertinent only to PEP 302; exec_module() doesn't return a module.
|
||||
|
||||
__import__ = import_util.__import__[1]
|
||||
|
||||
def create_mock(self, *names, return_=None):
|
||||
mock = util.mock_modules(*names)
|
||||
original_load = mock.load_module
|
||||
|
@ -48,14 +58,6 @@ class UseCache:
|
|||
mock.load_module = MethodType(load_module, mock)
|
||||
return mock
|
||||
|
||||
Frozen_UseCache, Source_UseCache = util.test_both(
|
||||
UseCache, __import__=import_util.__import__)
|
||||
|
||||
|
||||
class ImportlibUseCache(UseCache, unittest.TestCase):
|
||||
|
||||
__import__ = import_util.__import__[1]
|
||||
|
||||
# __import__ inconsistent between loaders and built-in import when it comes
|
||||
# to when to use the module in sys.modules and when not to.
|
||||
def test_using_cache_after_loader(self):
|
||||
|
|
|
@ -17,7 +17,7 @@ class ReturnValue:
|
|||
|
||||
def test_return_from_import(self):
|
||||
# [import return]
|
||||
with util.mock_modules('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.mock_spec('pkg.__init__', 'pkg.module') as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
module = self.__import__('pkg.module')
|
||||
self.assertEqual(module.__name__, 'pkg')
|
||||
|
|
|
@ -18,23 +18,18 @@ class CallingOrder:
|
|||
def test_first_called(self):
|
||||
# [first called]
|
||||
mod = 'top_level'
|
||||
first = util.mock_modules(mod)
|
||||
second = util.mock_modules(mod)
|
||||
with util.mock_modules(mod) as first, util.mock_modules(mod) as second:
|
||||
first.modules[mod] = 42
|
||||
second.modules[mod] = -13
|
||||
with util.mock_spec(mod) as first, util.mock_spec(mod) as second:
|
||||
with util.import_state(meta_path=[first, second]):
|
||||
self.assertEqual(self.__import__(mod), 42)
|
||||
self.assertIs(self.__import__(mod), first.modules[mod])
|
||||
|
||||
def test_continuing(self):
|
||||
# [continuing]
|
||||
mod_name = 'for_real'
|
||||
with util.mock_modules('nonexistent') as first, \
|
||||
util.mock_modules(mod_name) as second:
|
||||
first.find_module = lambda self, fullname, path=None: None
|
||||
second.modules[mod_name] = 42
|
||||
with util.mock_spec('nonexistent') as first, \
|
||||
util.mock_spec(mod_name) as second:
|
||||
first.find_spec = lambda self, fullname, path=None, parent=None: None
|
||||
with util.import_state(meta_path=[first, second]):
|
||||
self.assertEqual(self.__import__(mod_name), 42)
|
||||
self.assertIs(self.__import__(mod_name), second.modules[mod_name])
|
||||
|
||||
def test_empty(self):
|
||||
# Raise an ImportWarning if sys.meta_path is empty.
|
||||
|
@ -61,29 +56,27 @@ class CallSignature:
|
|||
[no path]. Otherwise, the value for __path__ is passed in for the 'path'
|
||||
argument [path set]."""
|
||||
|
||||
def log(self, fxn):
|
||||
def log_finder(self, importer):
|
||||
fxn = getattr(importer, self.finder_name)
|
||||
log = []
|
||||
def wrapper(self, *args, **kwargs):
|
||||
log.append([args, kwargs])
|
||||
return fxn(*args, **kwargs)
|
||||
return log, wrapper
|
||||
|
||||
|
||||
def test_no_path(self):
|
||||
# [no path]
|
||||
mod_name = 'top_level'
|
||||
assert '.' not in mod_name
|
||||
with util.mock_modules(mod_name) as importer:
|
||||
log, wrapped_call = self.log(importer.find_module)
|
||||
importer.find_module = MethodType(wrapped_call, importer)
|
||||
with self.mock_modules(mod_name) as importer:
|
||||
log, wrapped_call = self.log_finder(importer)
|
||||
setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__(mod_name)
|
||||
assert len(log) == 1
|
||||
args = log[0][0]
|
||||
kwargs = log[0][1]
|
||||
# Assuming all arguments are positional.
|
||||
self.assertEqual(len(args), 2)
|
||||
self.assertEqual(len(kwargs), 0)
|
||||
self.assertEqual(args[0], mod_name)
|
||||
self.assertIsNone(args[1])
|
||||
|
||||
|
@ -93,10 +86,10 @@ class CallSignature:
|
|||
mod_name = pkg_name + '.module'
|
||||
path = [42]
|
||||
assert '.' in mod_name
|
||||
with util.mock_modules(pkg_name+'.__init__', mod_name) as importer:
|
||||
with self.mock_modules(pkg_name+'.__init__', mod_name) as importer:
|
||||
importer.modules[pkg_name].__path__ = path
|
||||
log, wrapped_call = self.log(importer.find_module)
|
||||
importer.find_module = MethodType(wrapped_call, importer)
|
||||
log, wrapped_call = self.log_finder(importer)
|
||||
setattr(importer, self.finder_name, MethodType(wrapped_call, importer))
|
||||
with util.import_state(meta_path=[importer]):
|
||||
self.__import__(mod_name)
|
||||
assert len(log) == 2
|
||||
|
@ -107,8 +100,19 @@ class CallSignature:
|
|||
self.assertEqual(args[0], mod_name)
|
||||
self.assertIs(args[1], path)
|
||||
|
||||
Frozen_CallSignature, Source_CallSignature = util.test_both(
|
||||
CallSignature, __import__=import_util.__import__)
|
||||
class CallSignaturePEP302(CallSignature):
|
||||
mock_modules = util.mock_modules
|
||||
finder_name = 'find_module'
|
||||
|
||||
Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both(
|
||||
CallSignaturePEP302, __import__=import_util.__import__)
|
||||
|
||||
class CallSignaturePEP451(CallSignature):
|
||||
mock_modules = util.mock_spec
|
||||
finder_name = 'find_spec'
|
||||
|
||||
Frozen_CallSignaturePEP451, Source_CallSignaturePEP451 = util.test_both(
|
||||
CallSignaturePEP451, __import__=import_util.__import__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -11,13 +11,13 @@ class ParentModuleTests:
|
|||
"""Importing a submodule should import the parent modules."""
|
||||
|
||||
def test_import_parent(self):
|
||||
with util.mock_modules('pkg.__init__', 'pkg.module') as mock:
|
||||
with util.mock_spec('pkg.__init__', 'pkg.module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
module = self.__import__('pkg.module')
|
||||
self.assertIn('pkg', sys.modules)
|
||||
|
||||
def test_bad_parent(self):
|
||||
with util.mock_modules('pkg.module') as mock:
|
||||
with util.mock_spec('pkg.module') as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
with self.assertRaises(ImportError) as cm:
|
||||
self.__import__('pkg.module')
|
||||
|
@ -27,7 +27,7 @@ class ParentModuleTests:
|
|||
def __init__():
|
||||
import pkg.module
|
||||
1/0
|
||||
mock = util.mock_modules('pkg.__init__', 'pkg.module',
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.module',
|
||||
module_code={'pkg': __init__})
|
||||
with mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
|
@ -44,7 +44,7 @@ class ParentModuleTests:
|
|||
def __init__():
|
||||
from . import module
|
||||
1/0
|
||||
mock = util.mock_modules('pkg.__init__', 'pkg.module',
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.module',
|
||||
module_code={'pkg': __init__})
|
||||
with mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
|
@ -63,7 +63,7 @@ class ParentModuleTests:
|
|||
def __init__():
|
||||
from ..subpkg import module
|
||||
1/0
|
||||
mock = util.mock_modules('pkg.__init__', 'pkg.subpkg.__init__',
|
||||
mock = util.mock_spec('pkg.__init__', 'pkg.subpkg.__init__',
|
||||
'pkg.subpkg.module',
|
||||
module_code={'pkg.subpkg': __init__})
|
||||
with mock:
|
||||
|
@ -93,9 +93,9 @@ class ParentModuleTests:
|
|||
subname = name + '.b'
|
||||
def module_injection():
|
||||
sys.modules[subname] = 'total bunk'
|
||||
mock_modules = util.mock_modules('mod',
|
||||
mock_spec = util.mock_spec('mod',
|
||||
module_code={'mod': module_injection})
|
||||
with mock_modules as mock:
|
||||
with mock_spec as mock:
|
||||
with util.import_state(meta_path=[mock]):
|
||||
try:
|
||||
submodule = self.__import__(subname)
|
||||
|
|
|
@ -27,7 +27,7 @@ class FinderTests:
|
|||
# Implicitly tests that sys.path_importer_cache is used.
|
||||
module = '<test module>'
|
||||
path = '<test path>'
|
||||
importer = util.mock_modules(module)
|
||||
importer = util.mock_spec(module)
|
||||
with util.import_state(path_importer_cache={path: importer},
|
||||
path=[path]):
|
||||
loader = self.machinery.PathFinder.find_module(module)
|
||||
|
@ -38,7 +38,7 @@ class FinderTests:
|
|||
# Implicitly tests that sys.path_importer_cache is used.
|
||||
module = '<test module>'
|
||||
path = '<test path>'
|
||||
importer = util.mock_modules(module)
|
||||
importer = util.mock_spec(module)
|
||||
with util.import_state(path_importer_cache={path: importer}):
|
||||
loader = self.machinery.PathFinder.find_module(module, [path])
|
||||
self.assertIs(loader, importer)
|
||||
|
@ -47,7 +47,7 @@ class FinderTests:
|
|||
# An empty list should not count as asking for sys.path.
|
||||
module = 'module'
|
||||
path = '<test path>'
|
||||
importer = util.mock_modules(module)
|
||||
importer = util.mock_spec(module)
|
||||
with util.import_state(path_importer_cache={path: importer},
|
||||
path=[path]):
|
||||
self.assertIsNone(self.machinery.PathFinder.find_module('module', []))
|
||||
|
@ -57,7 +57,7 @@ class FinderTests:
|
|||
# Test that sys.path_importer_cache is set.
|
||||
module = '<test module>'
|
||||
path = '<test path>'
|
||||
importer = util.mock_modules(module)
|
||||
importer = util.mock_spec(module)
|
||||
hook = import_util.mock_path_hook(path, importer=importer)
|
||||
with util.import_state(path_hooks=[hook]):
|
||||
loader = self.machinery.PathFinder.find_module(module, [path])
|
||||
|
@ -82,7 +82,7 @@ class FinderTests:
|
|||
# The empty string should create a finder using the cwd.
|
||||
path = ''
|
||||
module = '<test module>'
|
||||
importer = util.mock_modules(module)
|
||||
importer = util.mock_spec(module)
|
||||
hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
|
||||
with util.import_state(path=[path], path_hooks=[hook]):
|
||||
loader = self.machinery.PathFinder.find_module(module)
|
||||
|
|
|
@ -64,7 +64,7 @@ class RelativeImports:
|
|||
uncache_names.append(name)
|
||||
else:
|
||||
uncache_names.append(name[:-len('.__init__')])
|
||||
with util.mock_modules(*create) as importer:
|
||||
with util.mock_spec(*create) as importer:
|
||||
with util.import_state(meta_path=[importer]):
|
||||
for global_ in globals_:
|
||||
with util.uncache(*uncache_names):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from contextlib import contextmanager
|
||||
from importlib import util
|
||||
import os.path
|
||||
from test import support
|
||||
import unittest
|
||||
|
@ -101,9 +102,9 @@ def import_state(**kwargs):
|
|||
setattr(sys, attr, value)
|
||||
|
||||
|
||||
class mock_modules:
|
||||
class _ImporterMock:
|
||||
|
||||
"""A mock importer/loader."""
|
||||
"""Base class to help with creating importer mocks."""
|
||||
|
||||
def __init__(self, *names, module_code={}):
|
||||
self.modules = {}
|
||||
|
@ -133,6 +134,19 @@ class mock_modules:
|
|||
def __getitem__(self, name):
|
||||
return self.modules[name]
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class mock_modules(_ImporterMock):
|
||||
|
||||
"""Importer mock using PEP 302 APIs."""
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
if fullname not in self.modules:
|
||||
return None
|
||||
|
@ -152,10 +166,28 @@ class mock_modules:
|
|||
raise
|
||||
return self.modules[fullname]
|
||||
|
||||
def __enter__(self):
|
||||
self._uncache = uncache(*self.modules.keys())
|
||||
self._uncache.__enter__()
|
||||
return self
|
||||
class mock_spec(_ImporterMock):
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
self._uncache.__exit__(None, None, None)
|
||||
"""Importer mock using PEP 451 APIs."""
|
||||
|
||||
def find_spec(self, fullname, path=None, parent=None):
|
||||
try:
|
||||
module = self.modules[fullname]
|
||||
except KeyError:
|
||||
return None
|
||||
is_package = hasattr(module, '__path__')
|
||||
spec = util.spec_from_file_location(
|
||||
fullname, module.__file__, loader=self,
|
||||
submodule_search_locations=getattr(module, '__path__', None))
|
||||
return spec
|
||||
|
||||
def create_module(self, spec):
|
||||
if spec.name not in self.modules:
|
||||
raise ImportError
|
||||
return self.modules[spec.name]
|
||||
|
||||
def exec_module(self, module):
|
||||
try:
|
||||
self.module_code[module.__spec__.name]()
|
||||
except KeyError:
|
||||
pass
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue