summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_importlib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-12-06 17:07:25 (GMT)
committerBrett Cannon <brett@python.org>2013-12-06 17:07:25 (GMT)
commit86aae6a7b3b863529b6cce64859c0f56c7963bc0 (patch)
tree08235d86bcf078592b2e14a3231ec1c5db60b3a1 /Lib/test/test_importlib
parent010ff584bc2f6311ead82221a4e2072c7f31bad3 (diff)
downloadcpython-86aae6a7b3b863529b6cce64859c0f56c7963bc0.zip
cpython-86aae6a7b3b863529b6cce64859c0f56c7963bc0.tar.gz
cpython-86aae6a7b3b863529b6cce64859c0f56c7963bc0.tar.bz2
Issue #19712: Update test.test_importlib.import_ to test/use PEP 451
where appropriate.
Diffstat (limited to 'Lib/test/test_importlib')
-rw-r--r--Lib/test/test_importlib/import_/test___package__.py31
-rw-r--r--Lib/test/test_importlib/import_/test_caching.py18
-rw-r--r--Lib/test/test_importlib/import_/test_fromlist.py2
-rw-r--r--Lib/test/test_importlib/import_/test_meta_path.py50
-rw-r--r--Lib/test/test_importlib/import_/test_packages.py14
-rw-r--r--Lib/test/test_importlib/import_/test_path.py10
-rw-r--r--Lib/test/test_importlib/import_/test_relative_imports.py2
-rw-r--r--Lib/test/test_importlib/util.py48
8 files changed, 114 insertions, 61 deletions
diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py
index 5fa432f..2e19725 100644
--- a/Lib/test/test_importlib/import_/test___package__.py
+++ b/Lib/test/test_importlib/import_/test___package__.py
@@ -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()
diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py
index 4d082b8..c292ee4 100644
--- a/Lib/test/test_importlib/import_/test_caching.py
+++ b/Lib/test/test_importlib/import_/test_caching.py
@@ -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):
diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py
index fc29ce6..58f244b 100644
--- a/Lib/test/test_importlib/import_/test_fromlist.py
+++ b/Lib/test/test_importlib/import_/test_fromlist.py
@@ -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')
diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py
index a56253d..dc45420 100644
--- a/Lib/test/test_importlib/import_/test_meta_path.py
+++ b/Lib/test/test_importlib/import_/test_meta_path.py
@@ -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__':
diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py
index 2df421d..55a5d14 100644
--- a/Lib/test/test_importlib/import_/test_packages.py
+++ b/Lib/test/test_importlib/import_/test_packages.py
@@ -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)
diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py
index 2e5033e..713e754 100644
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -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)
diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py
index fc6d25a..b216e9c 100644
--- a/Lib/test/test_importlib/import_/test_relative_imports.py
+++ b/Lib/test/test_importlib/import_/test_relative_imports.py
@@ -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):
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
index 80d43b5..a0dee6e 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -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