Kaydet (Commit) 86aae6a7 authored tarafından Brett Cannon's avatar Brett Cannon

Issue #19712: Update test.test_importlib.import_ to test/use PEP 451

where appropriate.
üst 010ff584
......@@ -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 Setting__package__(unittest.TestCase):
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__:
"""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):
......
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment