summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_importlib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_importlib')
-rw-r--r--Lib/test/test_importlib/builtin/test_finder.py33
-rw-r--r--Lib/test/test_importlib/builtin/test_loader.py39
-rw-r--r--Lib/test/test_importlib/builtin/util.py7
-rw-r--r--Lib/test/test_importlib/extension/test_case_sensitivity.py22
-rw-r--r--Lib/test/test_importlib/extension/test_finder.py15
-rw-r--r--Lib/test/test_importlib/extension/test_loader.py36
-rw-r--r--Lib/test/test_importlib/extension/test_path_hook.py13
-rw-r--r--Lib/test/test_importlib/extension/util.py19
-rw-r--r--Lib/test/test_importlib/frozen/test_finder.py12
-rw-r--r--Lib/test/test_importlib/frozen/test_loader.py17
-rw-r--r--Lib/test/test_importlib/import_/test___loader__.py15
-rw-r--r--Lib/test/test_importlib/import_/test___package__.py19
-rw-r--r--Lib/test/test_importlib/import_/test_api.py17
-rw-r--r--Lib/test/test_importlib/import_/test_caching.py9
-rw-r--r--Lib/test/test_importlib/import_/test_fromlist.py13
-rw-r--r--Lib/test/test_importlib/import_/test_meta_path.py21
-rw-r--r--Lib/test/test_importlib/import_/test_packages.py7
-rw-r--r--Lib/test/test_importlib/import_/test_path.py85
-rw-r--r--Lib/test/test_importlib/import_/test_relative_imports.py7
-rw-r--r--Lib/test/test_importlib/import_/util.py20
-rw-r--r--Lib/test/test_importlib/source/test_case_sensitivity.py23
-rw-r--r--Lib/test/test_importlib/source/test_file_loader.py111
-rw-r--r--Lib/test/test_importlib/source/test_finder.py28
-rw-r--r--Lib/test/test_importlib/source/test_path_hook.py8
-rw-r--r--Lib/test/test_importlib/source/test_source_encoding.py33
-rw-r--r--Lib/test/test_importlib/source/util.py96
-rw-r--r--Lib/test/test_importlib/test_abc.py292
-rw-r--r--Lib/test/test_importlib/test_api.py99
-rw-r--r--Lib/test/test_importlib/test_lazy.py132
-rw-r--r--Lib/test/test_importlib/test_locks.py178
-rw-r--r--Lib/test/test_importlib/test_spec.py256
-rw-r--r--Lib/test/test_importlib/test_util.py338
-rw-r--r--Lib/test/test_importlib/test_windows.py100
-rw-r--r--Lib/test/test_importlib/util.py185
34 files changed, 1354 insertions, 951 deletions
diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py
index 934562f..a2e6e1e 100644
--- a/Lib/test/test_importlib/builtin/test_finder.py
+++ b/Lib/test/test_importlib/builtin/test_finder.py
@@ -1,21 +1,21 @@
from .. import abc
from .. import util
-from . import util as builtin_util
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
+machinery = util.import_importlib('importlib.machinery')
import sys
import unittest
+@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class FindSpecTests(abc.FinderTests):
"""Test find_spec() for built-in modules."""
def test_module(self):
# Common case.
- with util.uncache(builtin_util.NAME):
- found = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME)
+ with util.uncache(util.BUILTINS.good_name):
+ found = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name)
self.assertTrue(found)
self.assertEqual(found.origin, 'built-in')
@@ -39,23 +39,26 @@ class FindSpecTests(abc.FinderTests):
def test_ignore_path(self):
# The value for 'path' should always trigger a failed import.
- with util.uncache(builtin_util.NAME):
- spec = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME,
+ with util.uncache(util.BUILTINS.good_name):
+ spec = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name,
['pkg'])
self.assertIsNone(spec)
-Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests,
- machinery=[frozen_machinery, source_machinery])
+(Frozen_FindSpecTests,
+ Source_FindSpecTests
+ ) = util.test_both(FindSpecTests, machinery=machinery)
+
+@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class FinderTests(abc.FinderTests):
"""Test find_module() for built-in modules."""
def test_module(self):
# Common case.
- with util.uncache(builtin_util.NAME):
- found = self.machinery.BuiltinImporter.find_module(builtin_util.NAME)
+ with util.uncache(util.BUILTINS.good_name):
+ found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name)
self.assertTrue(found)
self.assertTrue(hasattr(found, 'load_module'))
@@ -72,13 +75,15 @@ class FinderTests(abc.FinderTests):
def test_ignore_path(self):
# The value for 'path' should always trigger a failed import.
- with util.uncache(builtin_util.NAME):
- loader = self.machinery.BuiltinImporter.find_module(builtin_util.NAME,
+ with util.uncache(util.BUILTINS.good_name):
+ loader = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name,
['pkg'])
self.assertIsNone(loader)
-Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests,
- machinery=[frozen_machinery, source_machinery])
+
+(Frozen_FinderTests,
+ Source_FinderTests
+ ) = util.test_both(FinderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/builtin/test_loader.py b/Lib/test/test_importlib/builtin/test_loader.py
index 1f83574..1684ab6 100644
--- a/Lib/test/test_importlib/builtin/test_loader.py
+++ b/Lib/test/test_importlib/builtin/test_loader.py
@@ -1,14 +1,13 @@
from .. import abc
from .. import util
-from . import util as builtin_util
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
+machinery = util.import_importlib('importlib.machinery')
import sys
import types
import unittest
-
+@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class LoaderTests(abc.LoaderTests):
"""Test load_module() for built-in modules."""
@@ -29,8 +28,8 @@ class LoaderTests(abc.LoaderTests):
def test_module(self):
# Common case.
- with util.uncache(builtin_util.NAME):
- module = self.load_module(builtin_util.NAME)
+ with util.uncache(util.BUILTINS.good_name):
+ module = self.load_module(util.BUILTINS.good_name)
self.verify(module)
# Built-in modules cannot be a package.
@@ -41,9 +40,9 @@ class LoaderTests(abc.LoaderTests):
def test_module_reuse(self):
# Test that the same module is used in a reload.
- with util.uncache(builtin_util.NAME):
- module1 = self.load_module(builtin_util.NAME)
- module2 = self.load_module(builtin_util.NAME)
+ with util.uncache(util.BUILTINS.good_name):
+ module1 = self.load_module(util.BUILTINS.good_name)
+ module2 = self.load_module(util.BUILTINS.good_name)
self.assertIs(module1, module2)
def test_unloadable(self):
@@ -66,40 +65,44 @@ class LoaderTests(abc.LoaderTests):
self.assertEqual(cm.exception.name, module_name)
-Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests,
- machinery=[frozen_machinery, source_machinery])
+(Frozen_LoaderTests,
+ Source_LoaderTests
+ ) = util.test_both(LoaderTests, machinery=machinery)
+@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class InspectLoaderTests:
"""Tests for InspectLoader methods for BuiltinImporter."""
def test_get_code(self):
# There is no code object.
- result = self.machinery.BuiltinImporter.get_code(builtin_util.NAME)
+ result = self.machinery.BuiltinImporter.get_code(util.BUILTINS.good_name)
self.assertIsNone(result)
def test_get_source(self):
# There is no source.
- result = self.machinery.BuiltinImporter.get_source(builtin_util.NAME)
+ result = self.machinery.BuiltinImporter.get_source(util.BUILTINS.good_name)
self.assertIsNone(result)
def test_is_package(self):
# Cannot be a package.
- result = self.machinery.BuiltinImporter.is_package(builtin_util.NAME)
+ result = self.machinery.BuiltinImporter.is_package(util.BUILTINS.good_name)
self.assertFalse(result)
+ @unittest.skipIf(util.BUILTINS.bad_name is None, 'all modules are built in')
def test_not_builtin(self):
# Modules not built-in should raise ImportError.
for meth_name in ('get_code', 'get_source', 'is_package'):
method = getattr(self.machinery.BuiltinImporter, meth_name)
with self.assertRaises(ImportError) as cm:
- method(builtin_util.BAD_NAME)
- self.assertRaises(builtin_util.BAD_NAME)
+ method(util.BUILTINS.bad_name)
+ self.assertRaises(util.BUILTINS.bad_name)
+
-Frozen_InspectLoaderTests, Source_InspectLoaderTests = util.test_both(
- InspectLoaderTests,
- machinery=[frozen_machinery, source_machinery])
+(Frozen_InspectLoaderTests,
+ Source_InspectLoaderTests
+ ) = util.test_both(InspectLoaderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/builtin/util.py b/Lib/test/test_importlib/builtin/util.py
deleted file mode 100644
index 5704699..0000000
--- a/Lib/test/test_importlib/builtin/util.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import sys
-
-assert 'errno' in sys.builtin_module_names
-NAME = 'errno'
-
-assert 'importlib' not in sys.builtin_module_names
-BAD_NAME = 'importlib'
diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py
index bb2528e..706c3e4 100644
--- a/Lib/test/test_importlib/extension/test_case_sensitivity.py
+++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py
@@ -1,25 +1,24 @@
-from importlib import _bootstrap
+from importlib import _bootstrap_external
import sys
from test import support
import unittest
from .. import util
-from . import util as ext_util
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
+machinery = util.import_importlib('importlib.machinery')
# XXX find_spec tests
-@unittest.skipIf(ext_util.FILENAME is None, '_testcapi not available')
+@unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available')
@util.case_insensitive_tests
class ExtensionModuleCaseSensitivityTest:
def find_module(self):
- good_name = ext_util.NAME
+ good_name = util.EXTENSIONS.name
bad_name = good_name.upper()
assert good_name != bad_name
- finder = self.machinery.FileFinder(ext_util.PATH,
+ finder = self.machinery.FileFinder(util.EXTENSIONS.path,
(self.machinery.ExtensionFileLoader,
self.machinery.EXTENSION_SUFFIXES))
return finder.find_module(bad_name)
@@ -27,7 +26,7 @@ class ExtensionModuleCaseSensitivityTest:
def test_case_sensitive(self):
with support.EnvironmentVarGuard() as env:
env.unset('PYTHONCASEOK')
- if b'PYTHONCASEOK' in _bootstrap._os.environ:
+ if b'PYTHONCASEOK' in _bootstrap_external._os.environ:
self.skipTest('os.environ changes not reflected in '
'_os.environ')
loader = self.find_module()
@@ -36,15 +35,16 @@ class ExtensionModuleCaseSensitivityTest:
def test_case_insensitivity(self):
with support.EnvironmentVarGuard() as env:
env.set('PYTHONCASEOK', '1')
- if b'PYTHONCASEOK' not in _bootstrap._os.environ:
+ if b'PYTHONCASEOK' not in _bootstrap_external._os.environ:
self.skipTest('os.environ changes not reflected in '
'_os.environ')
loader = self.find_module()
self.assertTrue(hasattr(loader, 'load_module'))
-Frozen_ExtensionCaseSensitivity, Source_ExtensionCaseSensitivity = util.test_both(
- ExtensionModuleCaseSensitivityTest,
- machinery=[frozen_machinery, source_machinery])
+
+(Frozen_ExtensionCaseSensitivity,
+ Source_ExtensionCaseSensitivity
+ ) = util.test_both(ExtensionModuleCaseSensitivityTest, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py
index 990f29c..71bf67f 100644
--- a/Lib/test/test_importlib/extension/test_finder.py
+++ b/Lib/test/test_importlib/extension/test_finder.py
@@ -1,8 +1,7 @@
from .. import abc
-from .. import util as test_util
-from . import util
+from .. import util
-machinery = test_util.import_importlib('importlib.machinery')
+machinery = util.import_importlib('importlib.machinery')
import unittest
import warnings
@@ -14,7 +13,7 @@ class FinderTests(abc.FinderTests):
"""Test the finder for extension modules."""
def find_module(self, fullname):
- importer = self.machinery.FileFinder(util.PATH,
+ importer = self.machinery.FileFinder(util.EXTENSIONS.path,
(self.machinery.ExtensionFileLoader,
self.machinery.EXTENSION_SUFFIXES))
with warnings.catch_warnings():
@@ -22,7 +21,7 @@ class FinderTests(abc.FinderTests):
return importer.find_module(fullname)
def test_module(self):
- self.assertTrue(self.find_module(util.NAME))
+ self.assertTrue(self.find_module(util.EXTENSIONS.name))
# No extension module as an __init__ available for testing.
test_package = test_package_in_package = None
@@ -36,8 +35,10 @@ class FinderTests(abc.FinderTests):
def test_failure(self):
self.assertIsNone(self.find_module('asdfjkl;'))
-Frozen_FinderTests, Source_FinderTests = test_util.test_both(
- FinderTests, machinery=machinery)
+
+(Frozen_FinderTests,
+ Source_FinderTests
+ ) = util.test_both(FinderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py
index fd9abf2..aefd050 100644
--- a/Lib/test/test_importlib/extension/test_loader.py
+++ b/Lib/test/test_importlib/extension/test_loader.py
@@ -1,4 +1,3 @@
-from . import util as ext_util
from .. import abc
from .. import util
@@ -15,8 +14,8 @@ class LoaderTests(abc.LoaderTests):
"""Test load_module() for extension modules."""
def setUp(self):
- self.loader = self.machinery.ExtensionFileLoader(ext_util.NAME,
- ext_util.FILEPATH)
+ self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
+ util.EXTENSIONS.file_path)
def load_module(self, fullname):
return self.loader.load_module(fullname)
@@ -29,23 +28,23 @@ class LoaderTests(abc.LoaderTests):
self.load_module('XXX')
def test_equality(self):
- other = self.machinery.ExtensionFileLoader(ext_util.NAME,
- ext_util.FILEPATH)
+ other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
+ util.EXTENSIONS.file_path)
self.assertEqual(self.loader, other)
def test_inequality(self):
- other = self.machinery.ExtensionFileLoader('_' + ext_util.NAME,
- ext_util.FILEPATH)
+ other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name,
+ util.EXTENSIONS.file_path)
self.assertNotEqual(self.loader, other)
def test_module(self):
- with util.uncache(ext_util.NAME):
- module = self.load_module(ext_util.NAME)
- for attr, value in [('__name__', ext_util.NAME),
- ('__file__', ext_util.FILEPATH),
+ with util.uncache(util.EXTENSIONS.name):
+ module = self.load_module(util.EXTENSIONS.name)
+ for attr, value in [('__name__', util.EXTENSIONS.name),
+ ('__file__', util.EXTENSIONS.file_path),
('__package__', '')]:
self.assertEqual(getattr(module, attr), value)
- self.assertIn(ext_util.NAME, sys.modules)
+ self.assertIn(util.EXTENSIONS.name, sys.modules)
self.assertIsInstance(module.__loader__,
self.machinery.ExtensionFileLoader)
@@ -56,9 +55,9 @@ class LoaderTests(abc.LoaderTests):
test_lacking_parent = None
def test_module_reuse(self):
- with util.uncache(ext_util.NAME):
- module1 = self.load_module(ext_util.NAME)
- module2 = self.load_module(ext_util.NAME)
+ with util.uncache(util.EXTENSIONS.name):
+ module1 = self.load_module(util.EXTENSIONS.name)
+ module2 = self.load_module(util.EXTENSIONS.name)
self.assertIs(module1, module2)
# No easy way to trigger a failure after a successful import.
@@ -71,14 +70,15 @@ class LoaderTests(abc.LoaderTests):
self.assertEqual(cm.exception.name, name)
def test_is_package(self):
- self.assertFalse(self.loader.is_package(ext_util.NAME))
+ self.assertFalse(self.loader.is_package(util.EXTENSIONS.name))
for suffix in self.machinery.EXTENSION_SUFFIXES:
path = os.path.join('some', 'path', 'pkg', '__init__' + suffix)
loader = self.machinery.ExtensionFileLoader('pkg', path)
self.assertTrue(loader.is_package('pkg'))
-Frozen_LoaderTests, Source_LoaderTests = util.test_both(
- LoaderTests, machinery=machinery)
+(Frozen_LoaderTests,
+ Source_LoaderTests
+ ) = util.test_both(LoaderTests, machinery=machinery)
diff --git a/Lib/test/test_importlib/extension/test_path_hook.py b/Lib/test/test_importlib/extension/test_path_hook.py
index 49d6734..8f4b8bb 100644
--- a/Lib/test/test_importlib/extension/test_path_hook.py
+++ b/Lib/test/test_importlib/extension/test_path_hook.py
@@ -1,7 +1,6 @@
-from .. import util as test_util
-from . import util
+from .. import util
-machinery = test_util.import_importlib('importlib.machinery')
+machinery = util.import_importlib('importlib.machinery')
import collections
import sys
@@ -22,10 +21,12 @@ class PathHookTests:
def test_success(self):
# Path hook should handle a directory where a known extension module
# exists.
- self.assertTrue(hasattr(self.hook(util.PATH), 'find_module'))
+ self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module'))
-Frozen_PathHooksTests, Source_PathHooksTests = test_util.test_both(
- PathHookTests, machinery=machinery)
+
+(Frozen_PathHooksTests,
+ Source_PathHooksTests
+ ) = util.test_both(PathHookTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/extension/util.py b/Lib/test/test_importlib/extension/util.py
deleted file mode 100644
index 8d089f0..0000000
--- a/Lib/test/test_importlib/extension/util.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from importlib import machinery
-import os
-import sys
-
-PATH = None
-EXT = None
-FILENAME = None
-NAME = '_testcapi'
-try:
- for PATH in sys.path:
- for EXT in machinery.EXTENSION_SUFFIXES:
- FILENAME = NAME + EXT
- FILEPATH = os.path.join(PATH, FILENAME)
- if os.path.exists(os.path.join(PATH, FILENAME)):
- raise StopIteration
- else:
- PATH = EXT = FILENAME = FILEPATH = None
-except StopIteration:
- pass
diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py
index f9f97f3..519aa02 100644
--- a/Lib/test/test_importlib/frozen/test_finder.py
+++ b/Lib/test/test_importlib/frozen/test_finder.py
@@ -37,8 +37,10 @@ class FindSpecTests(abc.FinderTests):
spec = self.find('<not real>')
self.assertIsNone(spec)
-Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests,
- machinery=machinery)
+
+(Frozen_FindSpecTests,
+ Source_FindSpecTests
+ ) = util.test_both(FindSpecTests, machinery=machinery)
class FinderTests(abc.FinderTests):
@@ -72,8 +74,10 @@ class FinderTests(abc.FinderTests):
loader = self.find('<not real>')
self.assertIsNone(loader)
-Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests,
- machinery=machinery)
+
+(Frozen_FinderTests,
+ Source_FinderTests
+ ) = util.test_both(FinderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py
index 7c01464..603c7d7 100644
--- a/Lib/test/test_importlib/frozen/test_loader.py
+++ b/Lib/test/test_importlib/frozen/test_loader.py
@@ -85,8 +85,10 @@ class ExecModuleTests(abc.LoaderTests):
self.exec_module('_not_real')
self.assertEqual(cm.exception.name, '_not_real')
-Frozen_ExecModuleTests, Source_ExecModuleTests = util.test_both(ExecModuleTests,
- machinery=machinery)
+
+(Frozen_ExecModuleTests,
+ Source_ExecModuleTests
+ ) = util.test_both(ExecModuleTests, machinery=machinery)
class LoaderTests(abc.LoaderTests):
@@ -175,8 +177,10 @@ class LoaderTests(abc.LoaderTests):
self.machinery.FrozenImporter.load_module('_not_real')
self.assertEqual(cm.exception.name, '_not_real')
-Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests,
- machinery=machinery)
+
+(Frozen_LoaderTests,
+ Source_LoaderTests
+ ) = util.test_both(LoaderTests, machinery=machinery)
class InspectLoaderTests:
@@ -214,8 +218,9 @@ class InspectLoaderTests:
method('importlib')
self.assertEqual(cm.exception.name, 'importlib')
-Frozen_ILTests, Source_ILTests = util.test_both(InspectLoaderTests,
- machinery=machinery)
+(Frozen_ILTests,
+ Source_ILTests
+ ) = util.test_both(InspectLoaderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test___loader__.py b/Lib/test/test_importlib/import_/test___loader__.py
index 6df8010..4b18093 100644
--- a/Lib/test/test_importlib/import_/test___loader__.py
+++ b/Lib/test/test_importlib/import_/test___loader__.py
@@ -4,7 +4,6 @@ import types
import unittest
from .. import util
-from . import util as import_util
class SpecLoaderMock:
@@ -12,6 +11,9 @@ class SpecLoaderMock:
def find_spec(self, fullname, path=None, target=None):
return machinery.ModuleSpec(fullname, self)
+ def create_module(self, spec):
+ return None
+
def exec_module(self, module):
pass
@@ -24,8 +26,10 @@ class SpecLoaderAttributeTests:
module = self.__import__('blah')
self.assertEqual(loader, module.__loader__)
-Frozen_SpecTests, Source_SpecTests = util.test_both(
- SpecLoaderAttributeTests, __import__=import_util.__import__)
+
+(Frozen_SpecTests,
+ Source_SpecTests
+ ) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__)
class LoaderMock:
@@ -62,8 +66,9 @@ class LoaderAttributeTests:
self.assertEqual(loader, module.__loader__)
-Frozen_Tests, Source_Tests = util.test_both(LoaderAttributeTests,
- __import__=import_util.__import__)
+(Frozen_Tests,
+ Source_Tests
+ ) = util.test_both(LoaderAttributeTests, __import__=util.__import__)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py
index 2e19725..c7d3a2a 100644
--- a/Lib/test/test_importlib/import_/test___package__.py
+++ b/Lib/test/test_importlib/import_/test___package__.py
@@ -6,7 +6,6 @@ of using the typical __path__/__name__ test).
"""
import unittest
from .. import util
-from . import util as import_util
class Using__package__:
@@ -70,17 +69,23 @@ class Using__package__:
with self.assertRaises(TypeError):
self.__import__('', globals, {}, ['relimport'], 1)
+
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__):
+(Frozen_UsingPackagePEP302,
+ Source_UsingPackagePEP302
+ ) = util.test_both(Using__package__PEP302, __import__=util.__import__)
+
+
+class Using__package__PEP451(Using__package__):
mock_modules = util.mock_spec
-Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both(
- Using__package__PEP302, __import__=import_util.__import__)
+
+(Frozen_UsingPackagePEP451,
+ Source_UsingPackagePEP451
+ ) = util.test_both(Using__package__PEP451, __import__=util.__import__)
class Setting__package__:
@@ -95,7 +100,7 @@ class Setting__package__:
"""
- __import__ = import_util.__import__[1]
+ __import__ = util.__import__['Source']
# [top-level]
def test_top_level(self):
diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py
index 439c105..7069d9e 100644
--- a/Lib/test/test_importlib/import_/test_api.py
+++ b/Lib/test/test_importlib/import_/test_api.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as import_util
from importlib import machinery
import sys
@@ -18,6 +17,10 @@ class BadSpecFinderLoader:
return spec
@staticmethod
+ def create_module(spec):
+ return None
+
+ @staticmethod
def exec_module(module):
if module.__name__ == SUBMOD_NAME:
raise ImportError('I cannot be loaded!')
@@ -79,15 +82,19 @@ class APITest:
class OldAPITests(APITest):
bad_finder_loader = BadLoaderFinder
-Frozen_OldAPITests, Source_OldAPITests = util.test_both(
- OldAPITests, __import__=import_util.__import__)
+
+(Frozen_OldAPITests,
+ Source_OldAPITests
+ ) = util.test_both(OldAPITests, __import__=util.__import__)
class SpecAPITests(APITest):
bad_finder_loader = BadSpecFinderLoader
-Frozen_SpecAPITests, Source_SpecAPITests = util.test_both(
- SpecAPITests, __import__=import_util.__import__)
+
+(Frozen_SpecAPITests,
+ Source_SpecAPITests
+ ) = util.test_both(SpecAPITests, __import__=util.__import__)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py
index c292ee4..8079add 100644
--- a/Lib/test/test_importlib/import_/test_caching.py
+++ b/Lib/test/test_importlib/import_/test_caching.py
@@ -1,6 +1,5 @@
"""Test that sys.modules is used properly by import."""
from .. import util
-from . import util as import_util
import sys
from types import MethodType
import unittest
@@ -39,15 +38,17 @@ class UseCache:
self.__import__(name)
self.assertEqual(cm.exception.name, name)
-Frozen_UseCache, Source_UseCache = util.test_both(
- UseCache, __import__=import_util.__import__)
+
+(Frozen_UseCache,
+ Source_UseCache
+ ) = util.test_both(UseCache, __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]
+ __import__ = util.__import__['Source']
def create_mock(self, *names, return_=None):
mock = util.mock_modules(*names)
diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py
index a755b75..8045465 100644
--- a/Lib/test/test_importlib/import_/test_fromlist.py
+++ b/Lib/test/test_importlib/import_/test_fromlist.py
@@ -1,6 +1,5 @@
"""Test that the semantics relating to the 'fromlist' argument are correct."""
from .. import util
-from . import util as import_util
import unittest
@@ -29,8 +28,10 @@ class ReturnValue:
module = self.__import__('pkg.module', fromlist=['attr'])
self.assertEqual(module.__name__, 'pkg.module')
-Frozen_ReturnValue, Source_ReturnValue = util.test_both(
- ReturnValue, __import__=import_util.__import__)
+
+(Frozen_ReturnValue,
+ Source_ReturnValue
+ ) = util.test_both(ReturnValue, __import__=util.__import__)
class HandlingFromlist:
@@ -121,8 +122,10 @@ class HandlingFromlist:
self.assertEqual(module.module1.__name__, 'pkg.module1')
self.assertEqual(module.module2.__name__, 'pkg.module2')
-Frozen_FromList, Source_FromList = util.test_both(
- HandlingFromlist, __import__=import_util.__import__)
+
+(Frozen_FromList,
+ Source_FromList
+ ) = util.test_both(HandlingFromlist, __import__=util.__import__)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py
index 5eeb145..c452cdd 100644
--- a/Lib/test/test_importlib/import_/test_meta_path.py
+++ b/Lib/test/test_importlib/import_/test_meta_path.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as import_util
import importlib._bootstrap
import sys
from types import MethodType
@@ -46,8 +45,10 @@ class CallingOrder:
self.assertEqual(len(w), 1)
self.assertTrue(issubclass(w[-1].category, ImportWarning))
-Frozen_CallingOrder, Source_CallingOrder = util.test_both(
- CallingOrder, __import__=import_util.__import__)
+
+(Frozen_CallingOrder,
+ Source_CallingOrder
+ ) = util.test_both(CallingOrder, __import__=util.__import__)
class CallSignature:
@@ -100,19 +101,25 @@ class CallSignature:
self.assertEqual(args[0], mod_name)
self.assertIs(args[1], path)
+
class CallSignaturePEP302(CallSignature):
mock_modules = util.mock_modules
finder_name = 'find_module'
-Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both(
- CallSignaturePEP302, __import__=import_util.__import__)
+
+(Frozen_CallSignaturePEP302,
+ Source_CallSignaturePEP302
+ ) = util.test_both(CallSignaturePEP302, __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__)
+
+(Frozen_CallSignaturePEP451,
+ Source_CallSignaturePEP451
+ ) = util.test_both(CallSignaturePEP451, __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 55a5d14..3755b84 100644
--- a/Lib/test/test_importlib/import_/test_packages.py
+++ b/Lib/test/test_importlib/import_/test_packages.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as import_util
import sys
import unittest
import importlib
@@ -102,8 +101,10 @@ class ParentModuleTests:
finally:
support.unload(subname)
-Frozen_ParentTests, Source_ParentTests = util.test_both(
- ParentModuleTests, __import__=import_util.__import__)
+
+(Frozen_ParentTests,
+ Source_ParentTests
+ ) = util.test_both(ParentModuleTests, __import__=util.__import__)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py
index 1274f8c..4359dd9 100644
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -1,11 +1,12 @@
from .. import util
-from . import util as import_util
importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery')
+import errno
import os
import sys
+import tempfile
from types import ModuleType
import unittest
import warnings
@@ -58,7 +59,7 @@ class FinderTests:
module = '<test module>'
path = '<test path>'
importer = util.mock_spec(module)
- hook = import_util.mock_path_hook(path, importer=importer)
+ hook = util.mock_path_hook(path, importer=importer)
with util.import_state(path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module, [path])
self.assertIs(loader, importer)
@@ -83,7 +84,7 @@ class FinderTests:
path = ''
module = '<test module>'
importer = util.mock_spec(module)
- hook = import_util.mock_path_hook(os.getcwd(), importer=importer)
+ hook = util.mock_path_hook(os.getcwd(), importer=importer)
with util.import_state(path=[path], path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module)
self.assertIs(loader, importer)
@@ -98,7 +99,7 @@ class FinderTests:
new_path_importer_cache.pop(None, None)
new_path_hooks = [zipimport.zipimporter,
self.machinery.FileFinder.path_hook(
- *self.importlib._bootstrap._get_supported_file_loaders())]
+ *self.importlib._bootstrap_external._get_supported_file_loaders())]
missing = object()
email = sys.modules.pop('email', missing)
try:
@@ -112,8 +113,74 @@ class FinderTests:
if email is not missing:
sys.modules['email'] = email
-Frozen_FinderTests, Source_FinderTests = util.test_both(
- FinderTests, importlib=importlib, machinery=machinery)
+ def test_finder_with_find_module(self):
+ class TestFinder:
+ def find_module(self, fullname):
+ return self.to_return
+ failing_finder = TestFinder()
+ failing_finder.to_return = None
+ path = 'testing path'
+ with util.import_state(path_importer_cache={path: failing_finder}):
+ self.assertIsNone(
+ self.machinery.PathFinder.find_spec('whatever', [path]))
+ success_finder = TestFinder()
+ success_finder.to_return = __loader__
+ with util.import_state(path_importer_cache={path: success_finder}):
+ spec = self.machinery.PathFinder.find_spec('whatever', [path])
+ self.assertEqual(spec.loader, __loader__)
+
+ def test_finder_with_find_loader(self):
+ class TestFinder:
+ loader = None
+ portions = []
+ def find_loader(self, fullname):
+ return self.loader, self.portions
+ path = 'testing path'
+ with util.import_state(path_importer_cache={path: TestFinder()}):
+ self.assertIsNone(
+ self.machinery.PathFinder.find_spec('whatever', [path]))
+ success_finder = TestFinder()
+ success_finder.loader = __loader__
+ with util.import_state(path_importer_cache={path: success_finder}):
+ spec = self.machinery.PathFinder.find_spec('whatever', [path])
+ self.assertEqual(spec.loader, __loader__)
+
+ def test_finder_with_find_spec(self):
+ class TestFinder:
+ spec = None
+ def find_spec(self, fullname, target=None):
+ return self.spec
+ path = 'testing path'
+ with util.import_state(path_importer_cache={path: TestFinder()}):
+ self.assertIsNone(
+ self.machinery.PathFinder.find_spec('whatever', [path]))
+ success_finder = TestFinder()
+ success_finder.spec = self.machinery.ModuleSpec('whatever', __loader__)
+ with util.import_state(path_importer_cache={path: success_finder}):
+ got = self.machinery.PathFinder.find_spec('whatever', [path])
+ self.assertEqual(got, success_finder.spec)
+
+ @unittest.skipIf(sys.platform == 'win32', "cwd can't not exist on Windows")
+ def test_deleted_cwd(self):
+ # Issue #22834
+ self.addCleanup(os.chdir, os.getcwd())
+ try:
+ with tempfile.TemporaryDirectory() as path:
+ os.chdir(path)
+ except OSError as exc:
+ if exc.errno == errno.EINVAL:
+ self.skipTest("platform does not allow the deletion of the cwd")
+ raise
+ with util.import_state(path=['']):
+ # Do not want FileNotFoundError raised.
+ self.assertIsNone(self.machinery.PathFinder.find_spec('whatever'))
+
+
+
+
+(Frozen_FinderTests,
+ Source_FinderTests
+ ) = util.test_both(FinderTests, importlib=importlib, machinery=machinery)
class PathEntryFinderTests:
@@ -136,8 +203,10 @@ class PathEntryFinderTests:
path_hooks=[Finder]):
self.machinery.PathFinder.find_spec('importlib')
-Frozen_PEFTests, Source_PEFTests = util.test_both(
- PathEntryFinderTests, machinery=machinery)
+
+(Frozen_PEFTests,
+ Source_PEFTests
+ ) = util.test_both(PathEntryFinderTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py
index b216e9c..28bb6f7 100644
--- a/Lib/test/test_importlib/import_/test_relative_imports.py
+++ b/Lib/test/test_importlib/import_/test_relative_imports.py
@@ -1,6 +1,5 @@
"""Test relative imports (PEP 328)."""
from .. import util
-from . import util as import_util
import sys
import unittest
@@ -208,8 +207,10 @@ class RelativeImports:
with self.assertRaises(KeyError):
self.__import__('sys', level=1)
-Frozen_RelativeImports, Source_RelativeImports = util.test_both(
- RelativeImports, __import__=import_util.__import__)
+
+(Frozen_RelativeImports,
+ Source_RelativeImports
+ ) = util.test_both(RelativeImports, __import__=util.__import__)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/import_/util.py b/Lib/test/test_importlib/import_/util.py
deleted file mode 100644
index dcb490f..0000000
--- a/Lib/test/test_importlib/import_/util.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from .. import util
-
-frozen_importlib, source_importlib = util.import_importlib('importlib')
-
-import builtins
-import functools
-import importlib
-import unittest
-
-
-__import__ = staticmethod(builtins.__import__), staticmethod(source_importlib.__import__)
-
-
-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
diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py
index efd3146..c274b38 100644
--- a/Lib/test/test_importlib/source/test_case_sensitivity.py
+++ b/Lib/test/test_importlib/source/test_case_sensitivity.py
@@ -1,6 +1,5 @@
"""Test case-sensitivity (PEP 235)."""
from .. import util
-from . import util as source_util
importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery')
@@ -32,7 +31,7 @@ class CaseSensitivityTest:
"""Look for a module with matching and non-matching sensitivity."""
sensitive_pkg = 'sensitive.{0}'.format(self.name)
insensitive_pkg = 'insensitive.{0}'.format(self.name.lower())
- context = source_util.create_modules(insensitive_pkg, sensitive_pkg)
+ context = util.create_modules(insensitive_pkg, sensitive_pkg)
with context as mapping:
sensitive_path = os.path.join(mapping['.root'], 'sensitive')
insensitive_path = os.path.join(mapping['.root'], 'insensitive')
@@ -43,7 +42,7 @@ class CaseSensitivityTest:
def test_sensitive(self):
with test_support.EnvironmentVarGuard() as env:
env.unset('PYTHONCASEOK')
- if b'PYTHONCASEOK' in self.importlib._bootstrap._os.environ:
+ if b'PYTHONCASEOK' in self.importlib._bootstrap_external._os.environ:
self.skipTest('os.environ changes not reflected in '
'_os.environ')
sensitive, insensitive = self.sensitivity_test()
@@ -54,7 +53,7 @@ class CaseSensitivityTest:
def test_insensitive(self):
with test_support.EnvironmentVarGuard() as env:
env.set('PYTHONCASEOK', '1')
- if b'PYTHONCASEOK' not in self.importlib._bootstrap._os.environ:
+ if b'PYTHONCASEOK' not in self.importlib._bootstrap_external._os.environ:
self.skipTest('os.environ changes not reflected in '
'_os.environ')
sensitive, insensitive = self.sensitivity_test()
@@ -63,20 +62,28 @@ class CaseSensitivityTest:
self.assertIsNotNone(insensitive)
self.assertIn(self.name, insensitive.get_filename(self.name))
+
class CaseSensitivityTestPEP302(CaseSensitivityTest):
def find(self, finder):
return finder.find_module(self.name)
-Frozen_CaseSensitivityTestPEP302, Source_CaseSensitivityTestPEP302 = util.test_both(
- CaseSensitivityTestPEP302, importlib=importlib, machinery=machinery)
+
+(Frozen_CaseSensitivityTestPEP302,
+ Source_CaseSensitivityTestPEP302
+ ) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib,
+ machinery=machinery)
+
class CaseSensitivityTestPEP451(CaseSensitivityTest):
def find(self, finder):
found = finder.find_spec(self.name)
return found.loader if found is not None else found
-Frozen_CaseSensitivityTestPEP451, Source_CaseSensitivityTestPEP451 = util.test_both(
- CaseSensitivityTestPEP451, importlib=importlib, machinery=machinery)
+
+(Frozen_CaseSensitivityTestPEP451,
+ Source_CaseSensitivityTestPEP451
+ ) = util.test_both(CaseSensitivityTestPEP451, importlib=importlib,
+ machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py
index 2d415f9..73f4c62 100644
--- a/Lib/test/test_importlib/source/test_file_loader.py
+++ b/Lib/test/test_importlib/source/test_file_loader.py
@@ -1,6 +1,5 @@
from .. import abc
from .. import util
-from . import util as source_util
importlib = util.import_importlib('importlib')
importlib_abc = util.import_importlib('importlib.abc')
@@ -71,7 +70,7 @@ class SimpleTest(abc.LoaderTests):
# [basic]
def test_module(self):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
@@ -83,7 +82,7 @@ class SimpleTest(abc.LoaderTests):
self.assertEqual(getattr(module, attr), value)
def test_package(self):
- with source_util.create_modules('_pkg.__init__') as mapping:
+ with util.create_modules('_pkg.__init__') as mapping:
loader = self.machinery.SourceFileLoader('_pkg',
mapping['_pkg.__init__'])
with warnings.catch_warnings():
@@ -98,7 +97,7 @@ class SimpleTest(abc.LoaderTests):
def test_lacking_parent(self):
- with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
+ with util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
loader = self.machinery.SourceFileLoader('_pkg.mod',
mapping['_pkg.mod'])
with warnings.catch_warnings():
@@ -115,7 +114,7 @@ class SimpleTest(abc.LoaderTests):
return lambda name: fxn(name) + 1
def test_module_reuse(self):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
@@ -139,7 +138,7 @@ class SimpleTest(abc.LoaderTests):
attributes = ('__file__', '__path__', '__package__')
value = '<test>'
name = '_temp'
- with source_util.create_modules(name) as mapping:
+ with util.create_modules(name) as mapping:
orig_module = types.ModuleType(name)
for attr in attributes:
setattr(orig_module, attr, value)
@@ -159,7 +158,7 @@ class SimpleTest(abc.LoaderTests):
# [syntax error]
def test_bad_syntax(self):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
with open(mapping['_temp'], 'w') as file:
file.write('=')
loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
@@ -190,11 +189,11 @@ class SimpleTest(abc.LoaderTests):
if os.path.exists(pycache):
shutil.rmtree(pycache)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_timestamp_overflow(self):
# When a modification timestamp is larger than 2**32, it should be
# truncated rather than raise an OverflowError.
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
source = mapping['_temp']
compiled = self.util.cache_from_source(source)
with open(source, 'w') as f:
@@ -236,9 +235,11 @@ class SimpleTest(abc.LoaderTests):
warnings.simplefilter('ignore', DeprecationWarning)
loader.load_module('bad name')
-Frozen_SimpleTest, Source_SimpleTest = util.test_both(
- SimpleTest, importlib=importlib, machinery=machinery, abc=importlib_abc,
- util=importlib_util)
+
+(Frozen_SimpleTest,
+ Source_SimpleTest
+ ) = util.test_both(SimpleTest, importlib=importlib, machinery=machinery,
+ abc=importlib_abc, util=importlib_util)
class BadBytecodeTest:
@@ -275,45 +276,45 @@ class BadBytecodeTest:
return bytecode_path
def _test_empty_file(self, test, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: b'',
del_source=del_source)
test('_temp', mapping, bc_path)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def _test_partial_magic(self, test, *, del_source=False):
# When their are less than 4 bytes to a .pyc, regenerate it if
# possible, else raise ImportError.
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:3],
del_source=del_source)
test('_temp', mapping, bc_path)
def _test_magic_only(self, test, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:4],
del_source=del_source)
test('_temp', mapping, bc_path)
def _test_partial_timestamp(self, test, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:7],
del_source=del_source)
test('_temp', mapping, bc_path)
def _test_partial_size(self, test, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:11],
del_source=del_source)
test('_temp', mapping, bc_path)
def _test_no_marshal(self, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:12],
del_source=del_source)
@@ -322,7 +323,7 @@ class BadBytecodeTest:
self.import_(file_path, '_temp')
def _test_non_code_marshal(self, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bytecode_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:12] + marshal.dumps(b'abcd'),
del_source=del_source)
@@ -333,7 +334,7 @@ class BadBytecodeTest:
self.assertEqual(cm.exception.path, bytecode_path)
def _test_bad_marshal(self, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bytecode_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: bc[:12] + b'<test>',
del_source=del_source)
@@ -342,11 +343,12 @@ class BadBytecodeTest:
self.import_(file_path, '_temp')
def _test_bad_magic(self, test, *, del_source=False):
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
bc_path = self.manipulate_bytecode('_temp', mapping,
lambda bc: b'\x00\x00\x00\x00' + bc[4:])
test('_temp', mapping, bc_path)
+
class BadBytecodeTestPEP451(BadBytecodeTest):
def import_(self, file, module_name):
@@ -355,6 +357,7 @@ class BadBytecodeTestPEP451(BadBytecodeTest):
module.__spec__ = self.util.spec_from_loader(module_name, loader)
loader.exec_module(module)
+
class BadBytecodeTestPEP302(BadBytecodeTest):
def import_(self, file, module_name):
@@ -371,7 +374,7 @@ class SourceLoaderBadBytecodeTest:
def setUpClass(cls):
cls.loader = cls.machinery.SourceFileLoader
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_empty_file(self):
# When a .pyc is empty, regenerate it if possible, else raise
# ImportError.
@@ -390,7 +393,7 @@ class SourceLoaderBadBytecodeTest:
self._test_partial_magic(test)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_magic_only(self):
# When there is only the magic number, regenerate the .pyc if possible,
# else raise EOFError.
@@ -401,7 +404,7 @@ class SourceLoaderBadBytecodeTest:
self._test_magic_only(test)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_bad_magic(self):
# When the magic number is different, the bytecode should be
# regenerated.
@@ -413,7 +416,7 @@ class SourceLoaderBadBytecodeTest:
self._test_bad_magic(test)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_partial_timestamp(self):
# When the timestamp is partial, regenerate the .pyc, else
# raise EOFError.
@@ -424,7 +427,7 @@ class SourceLoaderBadBytecodeTest:
self._test_partial_timestamp(test)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_partial_size(self):
# When the size is partial, regenerate the .pyc, else
# raise EOFError.
@@ -435,29 +438,29 @@ class SourceLoaderBadBytecodeTest:
self._test_partial_size(test)
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_no_marshal(self):
# When there is only the magic number and timestamp, raise EOFError.
self._test_no_marshal()
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_non_code_marshal(self):
self._test_non_code_marshal()
# XXX ImportError when sourceless
# [bad marshal]
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_bad_marshal(self):
# Bad marshal data should raise a ValueError.
self._test_bad_marshal()
# [bad timestamp]
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_old_timestamp(self):
# When the timestamp is older than the source, bytecode should be
# regenerated.
zeros = b'\x00\x00\x00\x00'
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
py_compile.compile(mapping['_temp'])
bytecode_path = self.util.cache_from_source(mapping['_temp'])
with open(bytecode_path, 'r+b') as bytecode_file:
@@ -471,10 +474,10 @@ class SourceLoaderBadBytecodeTest:
self.assertEqual(bytecode_file.read(4), source_timestamp)
# [bytecode read-only]
- @source_util.writes_bytecode_files
+ @util.writes_bytecode_files
def test_read_only_bytecode(self):
# When bytecode is read-only but should be rewritten, fail silently.
- with source_util.create_modules('_temp') as mapping:
+ with util.create_modules('_temp') as mapping:
# Create bytecode that will need to be re-created.
py_compile.compile(mapping['_temp'])
bytecode_path = self.util.cache_from_source(mapping['_temp'])
@@ -491,21 +494,29 @@ class SourceLoaderBadBytecodeTest:
# Make writable for eventual clean-up.
os.chmod(bytecode_path, stat.S_IWUSR)
+
class SourceLoaderBadBytecodeTestPEP451(
SourceLoaderBadBytecodeTest, BadBytecodeTestPEP451):
pass
-Frozen_SourceBadBytecodePEP451, Source_SourceBadBytecodePEP451 = util.test_both(
- SourceLoaderBadBytecodeTestPEP451, importlib=importlib, machinery=machinery,
- abc=importlib_abc, util=importlib_util)
+
+(Frozen_SourceBadBytecodePEP451,
+ Source_SourceBadBytecodePEP451
+ ) = util.test_both(SourceLoaderBadBytecodeTestPEP451, importlib=importlib,
+ machinery=machinery, abc=importlib_abc,
+ util=importlib_util)
+
class SourceLoaderBadBytecodeTestPEP302(
SourceLoaderBadBytecodeTest, BadBytecodeTestPEP302):
pass
-Frozen_SourceBadBytecodePEP302, Source_SourceBadBytecodePEP302 = util.test_both(
- SourceLoaderBadBytecodeTestPEP302, importlib=importlib, machinery=machinery,
- abc=importlib_abc, util=importlib_util)
+
+(Frozen_SourceBadBytecodePEP302,
+ Source_SourceBadBytecodePEP302
+ ) = util.test_both(SourceLoaderBadBytecodeTestPEP302, importlib=importlib,
+ machinery=machinery, abc=importlib_abc,
+ util=importlib_util)
class SourcelessLoaderBadBytecodeTest:
@@ -567,21 +578,29 @@ class SourcelessLoaderBadBytecodeTest:
def test_non_code_marshal(self):
self._test_non_code_marshal(del_source=True)
+
class SourcelessLoaderBadBytecodeTestPEP451(SourcelessLoaderBadBytecodeTest,
BadBytecodeTestPEP451):
pass
-Frozen_SourcelessBadBytecodePEP451, Source_SourcelessBadBytecodePEP451 = util.test_both(
- SourcelessLoaderBadBytecodeTestPEP451, importlib=importlib,
- machinery=machinery, abc=importlib_abc, util=importlib_util)
+
+(Frozen_SourcelessBadBytecodePEP451,
+ Source_SourcelessBadBytecodePEP451
+ ) = util.test_both(SourcelessLoaderBadBytecodeTestPEP451, importlib=importlib,
+ machinery=machinery, abc=importlib_abc,
+ util=importlib_util)
+
class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest,
BadBytecodeTestPEP302):
pass
-Frozen_SourcelessBadBytecodePEP302, Source_SourcelessBadBytecodePEP302 = util.test_both(
- SourcelessLoaderBadBytecodeTestPEP302, importlib=importlib,
- machinery=machinery, abc=importlib_abc, util=importlib_util)
+
+(Frozen_SourcelessBadBytecodePEP302,
+ Source_SourcelessBadBytecodePEP302
+ ) = util.test_both(SourcelessLoaderBadBytecodeTestPEP302, importlib=importlib,
+ machinery=machinery, abc=importlib_abc,
+ util=importlib_util)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py
index 473297b..f372b85 100644
--- a/Lib/test/test_importlib/source/test_finder.py
+++ b/Lib/test/test_importlib/source/test_finder.py
@@ -1,6 +1,5 @@
from .. import abc
from .. import util
-from . import util as source_util
machinery = util.import_importlib('importlib.machinery')
@@ -60,7 +59,7 @@ class FinderTests(abc.FinderTests):
"""
if create is None:
create = {test}
- with source_util.create_modules(*create) as mapping:
+ with util.create_modules(*create) as mapping:
if compile_:
for name in compile_:
py_compile.compile(mapping[name])
@@ -100,14 +99,14 @@ class FinderTests(abc.FinderTests):
# [sub module]
def test_module_in_package(self):
- with source_util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
+ with util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub')
self.assertTrue(hasattr(loader, 'load_module'))
# [sub package]
def test_package_in_package(self):
- context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__')
+ context = util.create_modules('pkg.__init__', 'pkg.sub.__init__')
with context as mapping:
pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub')
@@ -120,7 +119,7 @@ class FinderTests(abc.FinderTests):
self.assertIn('__init__', loader.get_filename(name))
def test_failure(self):
- with source_util.create_modules('blah') as mapping:
+ with util.create_modules('blah') as mapping:
nothing = self.import_(mapping['.root'], 'sdfsadsadf')
self.assertIsNone(nothing)
@@ -147,7 +146,7 @@ class FinderTests(abc.FinderTests):
# Regression test for http://bugs.python.org/issue14846
def test_dir_removal_handling(self):
mod = 'mod'
- with source_util.create_modules(mod) as mapping:
+ with util.create_modules(mod) as mapping:
finder = self.get_finder(mapping['.root'])
found = self._find(finder, 'mod', loader_only=True)
self.assertIsNotNone(found)
@@ -196,8 +195,10 @@ class FinderTestsPEP451(FinderTests):
spec = finder.find_spec(name)
return spec.loader if spec is not None else spec
-Frozen_FinderTestsPEP451, Source_FinderTestsPEP451 = util.test_both(
- FinderTestsPEP451, machinery=machinery)
+
+(Frozen_FinderTestsPEP451,
+ Source_FinderTestsPEP451
+ ) = util.test_both(FinderTestsPEP451, machinery=machinery)
class FinderTestsPEP420(FinderTests):
@@ -210,8 +211,10 @@ class FinderTestsPEP420(FinderTests):
loader_portions = finder.find_loader(name)
return loader_portions[0] if loader_only else loader_portions
-Frozen_FinderTestsPEP420, Source_FinderTestsPEP420 = util.test_both(
- FinderTestsPEP420, machinery=machinery)
+
+(Frozen_FinderTestsPEP420,
+ Source_FinderTestsPEP420
+ ) = util.test_both(FinderTestsPEP420, machinery=machinery)
class FinderTestsPEP302(FinderTests):
@@ -223,9 +226,10 @@ class FinderTestsPEP302(FinderTests):
warnings.simplefilter("ignore", DeprecationWarning)
return finder.find_module(name)
-Frozen_FinderTestsPEP302, Source_FinderTestsPEP302 = util.test_both(
- FinderTestsPEP302, machinery=machinery)
+(Frozen_FinderTestsPEP302,
+ Source_FinderTestsPEP302
+ ) = util.test_both(FinderTestsPEP302, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py
index 92da772..e6a2415 100644
--- a/Lib/test/test_importlib/source/test_path_hook.py
+++ b/Lib/test/test_importlib/source/test_path_hook.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as source_util
machinery = util.import_importlib('importlib.machinery')
@@ -15,7 +14,7 @@ class PathHookTest:
self.machinery.SOURCE_SUFFIXES))
def test_success(self):
- with source_util.create_modules('dummy') as mapping:
+ with util.create_modules('dummy') as mapping:
self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
'find_module'))
@@ -23,7 +22,10 @@ class PathHookTest:
# The empty string represents the cwd.
self.assertTrue(hasattr(self.path_hook()(''), 'find_module'))
-Frozen_PathHookTest, Source_PathHooktest = util.test_both(PathHookTest, machinery=machinery)
+
+(Frozen_PathHookTest,
+ Source_PathHooktest
+ ) = util.test_both(PathHookTest, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/source/test_source_encoding.py b/Lib/test/test_importlib/source/test_source_encoding.py
index c62dfa1..b604afb 100644
--- a/Lib/test/test_importlib/source/test_source_encoding.py
+++ b/Lib/test/test_importlib/source/test_source_encoding.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as source_util
machinery = util.import_importlib('importlib.machinery')
@@ -37,7 +36,7 @@ class EncodingTest:
module_name = '_temp'
def run_test(self, source):
- with source_util.create_modules(self.module_name) as mapping:
+ with util.create_modules(self.module_name) as mapping:
with open(mapping[self.module_name], 'wb') as file:
file.write(source)
loader = self.machinery.SourceFileLoader(self.module_name,
@@ -89,6 +88,7 @@ class EncodingTest:
with self.assertRaises(SyntaxError):
self.run_test(source)
+
class EncodingTestPEP451(EncodingTest):
def load(self, loader):
@@ -97,8 +97,11 @@ class EncodingTestPEP451(EncodingTest):
loader.exec_module(module)
return module
-Frozen_EncodingTestPEP451, Source_EncodingTestPEP451 = util.test_both(
- EncodingTestPEP451, machinery=machinery)
+
+(Frozen_EncodingTestPEP451,
+ Source_EncodingTestPEP451
+ ) = util.test_both(EncodingTestPEP451, machinery=machinery)
+
class EncodingTestPEP302(EncodingTest):
@@ -107,8 +110,10 @@ class EncodingTestPEP302(EncodingTest):
warnings.simplefilter('ignore', DeprecationWarning)
return loader.load_module(self.module_name)
-Frozen_EncodingTestPEP302, Source_EncodingTestPEP302 = util.test_both(
- EncodingTestPEP302, machinery=machinery)
+
+(Frozen_EncodingTestPEP302,
+ Source_EncodingTestPEP302
+ ) = util.test_both(EncodingTestPEP302, machinery=machinery)
class LineEndingTest:
@@ -120,7 +125,7 @@ class LineEndingTest:
module_name = '_temp'
source_lines = [b"a = 42", b"b = -13", b'']
source = line_ending.join(source_lines)
- with source_util.create_modules(module_name) as mapping:
+ with util.create_modules(module_name) as mapping:
with open(mapping[module_name], 'wb') as file:
file.write(source)
loader = self.machinery.SourceFileLoader(module_name,
@@ -139,6 +144,7 @@ class LineEndingTest:
def test_lf(self):
self.run_test(b'\n')
+
class LineEndingTestPEP451(LineEndingTest):
def load(self, loader, module_name):
@@ -147,8 +153,11 @@ class LineEndingTestPEP451(LineEndingTest):
loader.exec_module(module)
return module
-Frozen_LineEndingTestPEP451, Source_LineEndingTestPEP451 = util.test_both(
- LineEndingTestPEP451, machinery=machinery)
+
+(Frozen_LineEndingTestPEP451,
+ Source_LineEndingTestPEP451
+ ) = util.test_both(LineEndingTestPEP451, machinery=machinery)
+
class LineEndingTestPEP302(LineEndingTest):
@@ -157,8 +166,10 @@ class LineEndingTestPEP302(LineEndingTest):
warnings.simplefilter('ignore', DeprecationWarning)
return loader.load_module(module_name)
-Frozen_LineEndingTestPEP302, Source_LineEndingTestPEP302 = util.test_both(
- LineEndingTestPEP302, machinery=machinery)
+
+(Frozen_LineEndingTestPEP302,
+ Source_LineEndingTestPEP302
+ ) = util.test_both(LineEndingTestPEP302, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/source/util.py b/Lib/test/test_importlib/source/util.py
deleted file mode 100644
index 63cd25a..0000000
--- a/Lib/test/test_importlib/source/util.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from .. import util
-import contextlib
-import errno
-import functools
-import os
-import os.path
-import sys
-import tempfile
-from test import support
-
-
-def writes_bytecode_files(fxn):
- """Decorator to protect sys.dont_write_bytecode from mutation and to skip
- tests that require it to be set to False."""
- if sys.dont_write_bytecode:
- return lambda *args, **kwargs: None
- @functools.wraps(fxn)
- def wrapper(*args, **kwargs):
- original = sys.dont_write_bytecode
- sys.dont_write_bytecode = False
- try:
- to_return = fxn(*args, **kwargs)
- finally:
- sys.dont_write_bytecode = original
- return to_return
- return wrapper
-
-
-def ensure_bytecode_path(bytecode_path):
- """Ensure that the __pycache__ directory for PEP 3147 pyc file exists.
-
- :param bytecode_path: File system path to PEP 3147 pyc file.
- """
- try:
- os.mkdir(os.path.dirname(bytecode_path))
- except OSError as error:
- if error.errno != errno.EEXIST:
- raise
-
-
-@contextlib.contextmanager
-def create_modules(*names):
- """Temporarily create each named module with an attribute (named 'attr')
- that contains the name passed into the context manager that caused the
- creation of the module.
-
- All files are created in a temporary directory returned by
- tempfile.mkdtemp(). This directory is inserted at the beginning of
- sys.path. When the context manager exits all created files (source and
- bytecode) are explicitly deleted.
-
- No magic is performed when creating packages! This means that if you create
- a module within a package you must also create the package's __init__ as
- well.
-
- """
- source = 'attr = {0!r}'
- created_paths = []
- mapping = {}
- state_manager = None
- uncache_manager = None
- try:
- temp_dir = tempfile.mkdtemp()
- mapping['.root'] = temp_dir
- import_names = set()
- for name in names:
- if not name.endswith('__init__'):
- import_name = name
- else:
- import_name = name[:-len('.__init__')]
- import_names.add(import_name)
- if import_name in sys.modules:
- del sys.modules[import_name]
- name_parts = name.split('.')
- file_path = temp_dir
- for directory in name_parts[:-1]:
- file_path = os.path.join(file_path, directory)
- if not os.path.exists(file_path):
- os.mkdir(file_path)
- created_paths.append(file_path)
- file_path = os.path.join(file_path, name_parts[-1] + '.py')
- with open(file_path, 'w') as file:
- file.write(source.format(name))
- created_paths.append(file_path)
- mapping[name] = file_path
- uncache_manager = util.uncache(*import_names)
- uncache_manager.__enter__()
- state_manager = util.import_state(path=[temp_dir])
- state_manager.__enter__()
- yield mapping
- finally:
- if state_manager is not None:
- state_manager.__exit__(None, None, None)
- if uncache_manager is not None:
- uncache_manager.__exit__(None, None, None)
- support.rmtree(temp_dir)
diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py
index a1f8e76..d4bf915 100644
--- a/Lib/test/test_importlib/test_abc.py
+++ b/Lib/test/test_importlib/test_abc.py
@@ -10,12 +10,13 @@ import unittest
from unittest import mock
import warnings
-from . import util
+from . import util as test_util
+
+init = test_util.import_importlib('importlib')
+abc = test_util.import_importlib('importlib.abc')
+machinery = test_util.import_importlib('importlib.machinery')
+util = test_util.import_importlib('importlib.util')
-frozen_init, source_init = util.import_importlib('importlib')
-frozen_abc, source_abc = util.import_importlib('importlib.abc')
-machinery = util.import_importlib('importlib.machinery')
-frozen_util, source_util = util.import_importlib('importlib.util')
##### Inheritance ##############################################################
class InheritanceTests:
@@ -26,8 +27,7 @@ class InheritanceTests:
subclasses = []
superclasses = []
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ def setUp(self):
self.superclasses = [getattr(self.abc, class_name)
for class_name in self.superclass_names]
if hasattr(self, 'subclass_names'):
@@ -36,11 +36,11 @@ class InheritanceTests:
# checking across module boundaries (i.e. the _bootstrap in abc is
# not the same as the one in machinery). That means stealing one of
# the modules from the other to make sure the same instance is used.
- self.subclasses = [getattr(self.abc.machinery, class_name)
- for class_name in self.subclass_names]
+ machinery = self.abc.machinery
+ self.subclasses = [getattr(machinery, class_name)
+ for class_name in self.subclass_names]
assert self.subclasses or self.superclasses, self.__class__
- testing = self.__class__.__name__.partition('_')[2]
- self.__test = getattr(self.abc, testing)
+ self.__test = getattr(self.abc, self._NAME)
def test_subclasses(self):
# Test that the expected subclasses inherit.
@@ -54,94 +54,97 @@ class InheritanceTests:
self.assertTrue(issubclass(self.__test, superclass),
"{0} is not a superclass of {1}".format(superclass, self.__test))
-def create_inheritance_tests(base_class):
- def set_frozen(ns):
- ns['abc'] = frozen_abc
- def set_source(ns):
- ns['abc'] = source_abc
-
- classes = []
- for prefix, ns_set in [('Frozen', set_frozen), ('Source', set_source)]:
- classes.append(types.new_class('_'.join([prefix, base_class.__name__]),
- (base_class, unittest.TestCase),
- exec_body=ns_set))
- return classes
-
class MetaPathFinder(InheritanceTests):
superclass_names = ['Finder']
subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder',
'WindowsRegistryFinder']
-tests = create_inheritance_tests(MetaPathFinder)
-Frozen_MetaPathFinderInheritanceTests, Source_MetaPathFinderInheritanceTests = tests
+
+(Frozen_MetaPathFinderInheritanceTests,
+ Source_MetaPathFinderInheritanceTests
+ ) = test_util.test_both(MetaPathFinder, abc=abc)
class PathEntryFinder(InheritanceTests):
superclass_names = ['Finder']
subclass_names = ['FileFinder']
-tests = create_inheritance_tests(PathEntryFinder)
-Frozen_PathEntryFinderInheritanceTests, Source_PathEntryFinderInheritanceTests = tests
+
+(Frozen_PathEntryFinderInheritanceTests,
+ Source_PathEntryFinderInheritanceTests
+ ) = test_util.test_both(PathEntryFinder, abc=abc)
class ResourceLoader(InheritanceTests):
superclass_names = ['Loader']
-tests = create_inheritance_tests(ResourceLoader)
-Frozen_ResourceLoaderInheritanceTests, Source_ResourceLoaderInheritanceTests = tests
+
+(Frozen_ResourceLoaderInheritanceTests,
+ Source_ResourceLoaderInheritanceTests
+ ) = test_util.test_both(ResourceLoader, abc=abc)
class InspectLoader(InheritanceTests):
superclass_names = ['Loader']
subclass_names = ['BuiltinImporter', 'FrozenImporter', 'ExtensionFileLoader']
-tests = create_inheritance_tests(InspectLoader)
-Frozen_InspectLoaderInheritanceTests, Source_InspectLoaderInheritanceTests = tests
+
+(Frozen_InspectLoaderInheritanceTests,
+ Source_InspectLoaderInheritanceTests
+ ) = test_util.test_both(InspectLoader, abc=abc)
class ExecutionLoader(InheritanceTests):
superclass_names = ['InspectLoader']
subclass_names = ['ExtensionFileLoader']
-tests = create_inheritance_tests(ExecutionLoader)
-Frozen_ExecutionLoaderInheritanceTests, Source_ExecutionLoaderInheritanceTests = tests
+
+(Frozen_ExecutionLoaderInheritanceTests,
+ Source_ExecutionLoaderInheritanceTests
+ ) = test_util.test_both(ExecutionLoader, abc=abc)
class FileLoader(InheritanceTests):
superclass_names = ['ResourceLoader', 'ExecutionLoader']
subclass_names = ['SourceFileLoader', 'SourcelessFileLoader']
-tests = create_inheritance_tests(FileLoader)
-Frozen_FileLoaderInheritanceTests, Source_FileLoaderInheritanceTests = tests
+
+(Frozen_FileLoaderInheritanceTests,
+ Source_FileLoaderInheritanceTests
+ ) = test_util.test_both(FileLoader, abc=abc)
class SourceLoader(InheritanceTests):
superclass_names = ['ResourceLoader', 'ExecutionLoader']
subclass_names = ['SourceFileLoader']
-tests = create_inheritance_tests(SourceLoader)
-Frozen_SourceLoaderInheritanceTests, Source_SourceLoaderInheritanceTests = tests
+
+(Frozen_SourceLoaderInheritanceTests,
+ Source_SourceLoaderInheritanceTests
+ ) = test_util.test_both(SourceLoader, abc=abc)
+
##### Default return values ####################################################
-def make_abc_subclasses(base_class):
- classes = []
- for kind, abc in [('Frozen', frozen_abc), ('Source', source_abc)]:
- name = '_'.join([kind, base_class.__name__])
- base_classes = base_class, getattr(abc, base_class.__name__)
- classes.append(types.new_class(name, base_classes))
- return classes
-
-def make_return_value_tests(base_class, test_class):
- frozen_class, source_class = make_abc_subclasses(base_class)
- tests = []
- for prefix, class_in_test in [('Frozen', frozen_class), ('Source', source_class)]:
- def set_ns(ns):
- ns['ins'] = class_in_test()
- tests.append(types.new_class('_'.join([prefix, test_class.__name__]),
- (test_class, unittest.TestCase),
- exec_body=set_ns))
- return tests
+
+def make_abc_subclasses(base_class, name=None, inst=False, **kwargs):
+ if name is None:
+ name = base_class.__name__
+ base = {kind: getattr(splitabc, name)
+ for kind, splitabc in abc.items()}
+ return {cls._KIND: cls() if inst else cls
+ for cls in test_util.split_frozen(base_class, base, **kwargs)}
+
+
+class ABCTestHarness:
+
+ @property
+ def ins(self):
+ # Lazily set ins on the class.
+ cls = self.SPLIT[self._KIND]
+ ins = cls()
+ self.__class__.ins = ins
+ return ins
class MetaPathFinder:
@@ -149,10 +152,10 @@ class MetaPathFinder:
def find_module(self, fullname, path):
return super().find_module(fullname, path)
-Frozen_MPF, Source_MPF = make_abc_subclasses(MetaPathFinder)
+class MetaPathFinderDefaultsTests(ABCTestHarness):
-class MetaPathFinderDefaultsTests:
+ SPLIT = make_abc_subclasses(MetaPathFinder)
def test_find_module(self):
# Default should return None.
@@ -163,8 +166,9 @@ class MetaPathFinderDefaultsTests:
self.ins.invalidate_caches()
-tests = make_return_value_tests(MetaPathFinder, MetaPathFinderDefaultsTests)
-Frozen_MPFDefaultTests, Source_MPFDefaultTests = tests
+(Frozen_MPFDefaultTests,
+ Source_MPFDefaultTests
+ ) = test_util.test_both(MetaPathFinderDefaultsTests)
class PathEntryFinder:
@@ -172,10 +176,10 @@ class PathEntryFinder:
def find_loader(self, fullname):
return super().find_loader(fullname)
-Frozen_PEF, Source_PEF = make_abc_subclasses(PathEntryFinder)
+class PathEntryFinderDefaultsTests(ABCTestHarness):
-class PathEntryFinderDefaultsTests:
+ SPLIT = make_abc_subclasses(PathEntryFinder)
def test_find_loader(self):
self.assertEqual((None, []), self.ins.find_loader('something'))
@@ -188,8 +192,9 @@ class PathEntryFinderDefaultsTests:
self.ins.invalidate_caches()
-tests = make_return_value_tests(PathEntryFinder, PathEntryFinderDefaultsTests)
-Frozen_PEFDefaultTests, Source_PEFDefaultTests = tests
+(Frozen_PEFDefaultTests,
+ Source_PEFDefaultTests
+ ) = test_util.test_both(PathEntryFinderDefaultsTests)
class Loader:
@@ -198,10 +203,9 @@ class Loader:
return super().load_module(fullname)
-Frozen_L, Source_L = make_abc_subclasses(Loader)
+class LoaderDefaultsTests(ABCTestHarness):
-
-class LoaderDefaultsTests:
+ SPLIT = make_abc_subclasses(Loader)
def test_load_module(self):
with self.assertRaises(ImportError):
@@ -217,8 +221,9 @@ class LoaderDefaultsTests:
self.assertTrue(repr(mod))
-tests = make_return_value_tests(Loader, LoaderDefaultsTests)
-Frozen_LDefaultTests, SourceLDefaultTests = tests
+(Frozen_LDefaultTests,
+ SourceLDefaultTests
+ ) = test_util.test_both(LoaderDefaultsTests)
class ResourceLoader(Loader):
@@ -227,18 +232,18 @@ class ResourceLoader(Loader):
return super().get_data(path)
-Frozen_RL, Source_RL = make_abc_subclasses(ResourceLoader)
-
+class ResourceLoaderDefaultsTests(ABCTestHarness):
-class ResourceLoaderDefaultsTests:
+ SPLIT = make_abc_subclasses(ResourceLoader)
def test_get_data(self):
with self.assertRaises(IOError):
self.ins.get_data('/some/path')
-tests = make_return_value_tests(ResourceLoader, ResourceLoaderDefaultsTests)
-Frozen_RLDefaultTests, Source_RLDefaultTests = tests
+(Frozen_RLDefaultTests,
+ Source_RLDefaultTests
+ ) = test_util.test_both(ResourceLoaderDefaultsTests)
class InspectLoader(Loader):
@@ -250,10 +255,12 @@ class InspectLoader(Loader):
return super().get_source(fullname)
-Frozen_IL, Source_IL = make_abc_subclasses(InspectLoader)
+SPLIT_IL = make_abc_subclasses(InspectLoader)
-class InspectLoaderDefaultsTests:
+class InspectLoaderDefaultsTests(ABCTestHarness):
+
+ SPLIT = SPLIT_IL
def test_is_package(self):
with self.assertRaises(ImportError):
@@ -264,8 +271,9 @@ class InspectLoaderDefaultsTests:
self.ins.get_source('blah')
-tests = make_return_value_tests(InspectLoader, InspectLoaderDefaultsTests)
-Frozen_ILDefaultTests, Source_ILDefaultTests = tests
+(Frozen_ILDefaultTests,
+ Source_ILDefaultTests
+ ) = test_util.test_both(InspectLoaderDefaultsTests)
class ExecutionLoader(InspectLoader):
@@ -273,21 +281,25 @@ class ExecutionLoader(InspectLoader):
def get_filename(self, fullname):
return super().get_filename(fullname)
-Frozen_EL, Source_EL = make_abc_subclasses(ExecutionLoader)
+
+SPLIT_EL = make_abc_subclasses(ExecutionLoader)
-class ExecutionLoaderDefaultsTests:
+class ExecutionLoaderDefaultsTests(ABCTestHarness):
+
+ SPLIT = SPLIT_EL
def test_get_filename(self):
with self.assertRaises(ImportError):
self.ins.get_filename('blah')
-tests = make_return_value_tests(ExecutionLoader, InspectLoaderDefaultsTests)
-Frozen_ELDefaultTests, Source_ELDefaultsTests = tests
+(Frozen_ELDefaultTests,
+ Source_ELDefaultsTests
+ ) = test_util.test_both(InspectLoaderDefaultsTests)
-##### MetaPathFinder concrete methods ##########################################
+##### MetaPathFinder concrete methods ##########################################
class MetaPathFinderFindModuleTests:
@classmethod
@@ -317,13 +329,12 @@ class MetaPathFinderFindModuleTests:
self.assertIs(found, spec.loader)
-Frozen_MPFFindModuleTests, Source_MPFFindModuleTests = util.test_both(
- MetaPathFinderFindModuleTests,
- abc=(frozen_abc, source_abc),
- util=(frozen_util, source_util))
+(Frozen_MPFFindModuleTests,
+ Source_MPFFindModuleTests
+ ) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util)
-##### PathEntryFinder concrete methods #########################################
+##### PathEntryFinder concrete methods #########################################
class PathEntryFinderFindLoaderTests:
@classmethod
@@ -361,11 +372,10 @@ class PathEntryFinderFindLoaderTests:
self.assertEqual(paths, found[1])
-Frozen_PEFFindLoaderTests, Source_PEFFindLoaderTests = util.test_both(
- PathEntryFinderFindLoaderTests,
- abc=(frozen_abc, source_abc),
- machinery=machinery,
- util=(frozen_util, source_util))
+(Frozen_PEFFindLoaderTests,
+ Source_PEFFindLoaderTests
+ ) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util,
+ machinery=machinery)
##### Loader concrete methods ##################################################
@@ -386,7 +396,7 @@ class LoaderLoadModuleTests:
def test_fresh(self):
loader = self.loader()
name = 'blah'
- with util.uncache(name):
+ with test_util.uncache(name):
loader.load_module(name)
module = loader.found
self.assertIs(sys.modules[name], module)
@@ -404,7 +414,7 @@ class LoaderLoadModuleTests:
module = types.ModuleType(name)
module.__spec__ = self.util.spec_from_loader(name, loader)
module.__loader__ = loader
- with util.uncache(name):
+ with test_util.uncache(name):
sys.modules[name] = module
loader.load_module(name)
found = loader.found
@@ -412,10 +422,9 @@ class LoaderLoadModuleTests:
self.assertIs(module, sys.modules[name])
-Frozen_LoaderLoadModuleTests, Source_LoaderLoadModuleTests = util.test_both(
- LoaderLoadModuleTests,
- abc=(frozen_abc, source_abc),
- util=(frozen_util, source_util))
+(Frozen_LoaderLoadModuleTests,
+ Source_LoaderLoadModuleTests
+ ) = test_util.test_both(LoaderLoadModuleTests, abc=abc, util=util)
##### InspectLoader concrete methods ###########################################
@@ -461,11 +470,10 @@ class InspectLoaderSourceToCodeTests:
self.assertEqual(code.co_filename, '<string>')
-class Frozen_ILSourceToCodeTests(InspectLoaderSourceToCodeTests, unittest.TestCase):
- InspectLoaderSubclass = Frozen_IL
-
-class Source_ILSourceToCodeTests(InspectLoaderSourceToCodeTests, unittest.TestCase):
- InspectLoaderSubclass = Source_IL
+(Frozen_ILSourceToCodeTests,
+ Source_ILSourceToCodeTests
+ ) = test_util.test_both(InspectLoaderSourceToCodeTests,
+ InspectLoaderSubclass=SPLIT_IL)
class InspectLoaderGetCodeTests:
@@ -495,11 +503,10 @@ class InspectLoaderGetCodeTests:
loader.get_code('blah')
-class Frozen_ILGetCodeTests(InspectLoaderGetCodeTests, unittest.TestCase):
- InspectLoaderSubclass = Frozen_IL
-
-class Source_ILGetCodeTests(InspectLoaderGetCodeTests, unittest.TestCase):
- InspectLoaderSubclass = Source_IL
+(Frozen_ILGetCodeTests,
+ Source_ILGetCodeTests
+ ) = test_util.test_both(InspectLoaderGetCodeTests,
+ InspectLoaderSubclass=SPLIT_IL)
class InspectLoaderLoadModuleTests:
@@ -543,11 +550,10 @@ class InspectLoaderLoadModuleTests:
self.assertEqual(module, sys.modules[self.module_name])
-class Frozen_ILLoadModuleTests(InspectLoaderLoadModuleTests, unittest.TestCase):
- InspectLoaderSubclass = Frozen_IL
-
-class Source_ILLoadModuleTests(InspectLoaderLoadModuleTests, unittest.TestCase):
- InspectLoaderSubclass = Source_IL
+(Frozen_ILLoadModuleTests,
+ Source_ILLoadModuleTests
+ ) = test_util.test_both(InspectLoaderLoadModuleTests,
+ InspectLoaderSubclass=SPLIT_IL)
##### ExecutionLoader concrete methods #########################################
@@ -608,15 +614,14 @@ class ExecutionLoaderGetCodeTests:
self.assertEqual(module.attr, 42)
-class Frozen_ELGetCodeTests(ExecutionLoaderGetCodeTests, unittest.TestCase):
- ExecutionLoaderSubclass = Frozen_EL
-
-class Source_ELGetCodeTests(ExecutionLoaderGetCodeTests, unittest.TestCase):
- ExecutionLoaderSubclass = Source_EL
+(Frozen_ELGetCodeTests,
+ Source_ELGetCodeTests
+ ) = test_util.test_both(ExecutionLoaderGetCodeTests,
+ ExecutionLoaderSubclass=SPLIT_EL)
##### SourceLoader concrete methods ############################################
-class SourceLoader:
+class SourceOnlyLoader:
# Globals that should be defined for all modules.
source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, "
@@ -637,10 +642,10 @@ class SourceLoader:
return '<module>'
-Frozen_SourceOnlyL, Source_SourceOnlyL = make_abc_subclasses(SourceLoader)
+SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader')
-class SourceLoader(SourceLoader):
+class SourceLoader(SourceOnlyLoader):
source_mtime = 1
@@ -677,11 +682,7 @@ class SourceLoader(SourceLoader):
return path == self.bytecode_path
-Frozen_SL, Source_SL = make_abc_subclasses(SourceLoader)
-Frozen_SL.util = frozen_util
-Source_SL.util = source_util
-Frozen_SL.init = frozen_init
-Source_SL.init = source_init
+SPLIT_SL = make_abc_subclasses(SourceLoader, util=util, init=init)
class SourceLoaderTestHarness:
@@ -765,7 +766,7 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness):
# Loading a module should set __name__, __loader__, __package__,
# __path__ (for packages), __file__, and __cached__.
# The module should also be put into sys.modules.
- with util.uncache(self.name):
+ with test_util.uncache(self.name):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
module = self.loader.load_module(self.name)
@@ -778,7 +779,7 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness):
# is a package.
# Testing the values for a package are covered by test_load_module.
self.setUp(is_package=False)
- with util.uncache(self.name):
+ with test_util.uncache(self.name):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
module = self.loader.load_module(self.name)
@@ -798,13 +799,10 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness):
self.assertEqual(returned_source, source)
-class Frozen_SourceOnlyLTests(SourceOnlyLoaderTests, unittest.TestCase):
- loader_mock = Frozen_SourceOnlyL
- util = frozen_util
-
-class Source_SourceOnlyLTests(SourceOnlyLoaderTests, unittest.TestCase):
- loader_mock = Source_SourceOnlyL
- util = source_util
+(Frozen_SourceOnlyLoaderTests,
+ Source_SourceOnlyLoaderTests
+ ) = test_util.test_both(SourceOnlyLoaderTests, util=util,
+ loader_mock=SPLIT_SOL)
@unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true")
@@ -896,15 +894,10 @@ class SourceLoaderBytecodeTests(SourceLoaderTestHarness):
self.verify_code(code_object)
-class Frozen_SLBytecodeTests(SourceLoaderBytecodeTests, unittest.TestCase):
- loader_mock = Frozen_SL
- init = frozen_init
- util = frozen_util
-
-class SourceSLBytecodeTests(SourceLoaderBytecodeTests, unittest.TestCase):
- loader_mock = Source_SL
- init = source_init
- util = source_util
+(Frozen_SLBytecodeTests,
+ SourceSLBytecodeTests
+ ) = test_util.test_both(SourceLoaderBytecodeTests, init=init, util=util,
+ loader_mock=SPLIT_SL)
class SourceLoaderGetSourceTests:
@@ -940,11 +933,10 @@ class SourceLoaderGetSourceTests:
self.assertEqual(mock.get_source(name), expect)
-class Frozen_SourceOnlyLGetSourceTests(SourceLoaderGetSourceTests, unittest.TestCase):
- SourceOnlyLoaderMock = Frozen_SourceOnlyL
-
-class Source_SourceOnlyLGetSourceTests(SourceLoaderGetSourceTests, unittest.TestCase):
- SourceOnlyLoaderMock = Source_SourceOnlyL
+(Frozen_SourceOnlyLoaderGetSourceTests,
+ Source_SourceOnlyLoaderGetSourceTests
+ ) = test_util.test_both(SourceLoaderGetSourceTests,
+ SourceOnlyLoaderMock=SPLIT_SOL)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py
index 2a2d42b..6bc3c56 100644
--- a/Lib/test/test_importlib/test_api.py
+++ b/Lib/test/test_importlib/test_api.py
@@ -1,8 +1,8 @@
-from . import util
+from . import util as test_util
-frozen_init, source_init = util.import_importlib('importlib')
-frozen_util, source_util = util.import_importlib('importlib.util')
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
+init = test_util.import_importlib('importlib')
+util = test_util.import_importlib('importlib.util')
+machinery = test_util.import_importlib('importlib.machinery')
import os.path
import sys
@@ -18,8 +18,8 @@ class ImportModuleTests:
def test_module_import(self):
# Test importing a top-level module.
- with util.mock_modules('top_level') as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules('top_level') as mock:
+ with test_util.import_state(meta_path=[mock]):
module = self.init.import_module('top_level')
self.assertEqual(module.__name__, 'top_level')
@@ -28,8 +28,8 @@ class ImportModuleTests:
pkg_name = 'pkg'
pkg_long_name = '{0}.__init__'.format(pkg_name)
name = '{0}.mod'.format(pkg_name)
- with util.mock_modules(pkg_long_name, name) as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules(pkg_long_name, name) as mock:
+ with test_util.import_state(meta_path=[mock]):
module = self.init.import_module(name)
self.assertEqual(module.__name__, name)
@@ -40,16 +40,16 @@ class ImportModuleTests:
module_name = 'mod'
absolute_name = '{0}.{1}'.format(pkg_name, module_name)
relative_name = '.{0}'.format(module_name)
- with util.mock_modules(pkg_long_name, absolute_name) as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules(pkg_long_name, absolute_name) as mock:
+ with test_util.import_state(meta_path=[mock]):
self.init.import_module(pkg_name)
module = self.init.import_module(relative_name, pkg_name)
self.assertEqual(module.__name__, absolute_name)
def test_deep_relative_package_import(self):
modules = ['a.__init__', 'a.b.__init__', 'a.c']
- with util.mock_modules(*modules) as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules(*modules) as mock:
+ with test_util.import_state(meta_path=[mock]):
self.init.import_module('a')
self.init.import_module('a.b')
module = self.init.import_module('..c', 'a.b')
@@ -61,8 +61,8 @@ class ImportModuleTests:
pkg_name = 'pkg'
pkg_long_name = '{0}.__init__'.format(pkg_name)
name = '{0}.mod'.format(pkg_name)
- with util.mock_modules(pkg_long_name, name) as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules(pkg_long_name, name) as mock:
+ with test_util.import_state(meta_path=[mock]):
self.init.import_module(pkg_name)
module = self.init.import_module(name, pkg_name)
self.assertEqual(module.__name__, name)
@@ -86,16 +86,15 @@ class ImportModuleTests:
b_load_count += 1
code = {'a': load_a, 'a.b': load_b}
modules = ['a.__init__', 'a.b']
- with util.mock_modules(*modules, module_code=code) as mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.mock_modules(*modules, module_code=code) as mock:
+ with test_util.import_state(meta_path=[mock]):
self.init.import_module('a.b')
self.assertEqual(b_load_count, 1)
-class Frozen_ImportModuleTests(ImportModuleTests, unittest.TestCase):
- init = frozen_init
-class Source_ImportModuleTests(ImportModuleTests, unittest.TestCase):
- init = source_init
+(Frozen_ImportModuleTests,
+ Source_ImportModuleTests
+ ) = test_util.test_both(ImportModuleTests, init=init)
class FindLoaderTests:
@@ -107,7 +106,7 @@ class FindLoaderTests:
def test_sys_modules(self):
# If a module with __loader__ is in sys.modules, then return it.
name = 'some_mod'
- with util.uncache(name):
+ with test_util.uncache(name):
module = types.ModuleType(name)
loader = 'a loader!'
module.__loader__ = loader
@@ -120,7 +119,7 @@ class FindLoaderTests:
def test_sys_modules_loader_is_None(self):
# If sys.modules[name].__loader__ is None, raise ValueError.
name = 'some_mod'
- with util.uncache(name):
+ with test_util.uncache(name):
module = types.ModuleType(name)
module.__loader__ = None
sys.modules[name] = module
@@ -133,7 +132,7 @@ class FindLoaderTests:
# Should raise ValueError
# Issue #17099
name = 'some_mod'
- with util.uncache(name):
+ with test_util.uncache(name):
module = types.ModuleType(name)
try:
del module.__loader__
@@ -148,8 +147,8 @@ class FindLoaderTests:
def test_success(self):
# Return the loader found on sys.meta_path.
name = 'some_mod'
- with util.uncache(name):
- with util.import_state(meta_path=[self.FakeMetaFinder]):
+ with test_util.uncache(name):
+ with test_util.import_state(meta_path=[self.FakeMetaFinder]):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertEqual((name, None), self.init.find_loader(name))
@@ -158,8 +157,8 @@ class FindLoaderTests:
# Searching on a path should work.
name = 'some_mod'
path = 'path to some place'
- with util.uncache(name):
- with util.import_state(meta_path=[self.FakeMetaFinder]):
+ with test_util.uncache(name):
+ with test_util.import_state(meta_path=[self.FakeMetaFinder]):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.assertEqual((name, path),
@@ -171,11 +170,10 @@ class FindLoaderTests:
warnings.simplefilter('ignore', DeprecationWarning)
self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule'))
-class Frozen_FindLoaderTests(FindLoaderTests, unittest.TestCase):
- init = frozen_init
-class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase):
- init = source_init
+(Frozen_FindLoaderTests,
+ Source_FindLoaderTests
+ ) = test_util.test_both(FindLoaderTests, init=init)
class ReloadTests:
@@ -195,10 +193,10 @@ class ReloadTests:
module = type(sys)('top_level')
module.spam = 3
sys.modules['top_level'] = module
- mock = util.mock_modules('top_level',
- module_code={'top_level': code})
+ mock = test_util.mock_modules('top_level',
+ module_code={'top_level': code})
with mock:
- with util.import_state(meta_path=[mock]):
+ with test_util.import_state(meta_path=[mock]):
module = self.init.import_module('top_level')
reloaded = self.init.reload(module)
actual = sys.modules['top_level']
@@ -230,7 +228,7 @@ class ReloadTests:
def test_reload_location_changed(self):
name = 'spam'
with support.temp_cwd(None) as cwd:
- with util.uncache('spam'):
+ with test_util.uncache('spam'):
with support.DirsOnSysPath(cwd):
# Start as a plain module.
self.init.invalidate_caches()
@@ -281,7 +279,7 @@ class ReloadTests:
def test_reload_namespace_changed(self):
name = 'spam'
with support.temp_cwd(None) as cwd:
- with util.uncache('spam'):
+ with test_util.uncache('spam'):
with support.DirsOnSysPath(cwd):
# Start as a namespace package.
self.init.invalidate_caches()
@@ -338,20 +336,16 @@ class ReloadTests:
# See #19851.
name = 'spam'
subname = 'ham'
- with util.temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = util.submodule(name, subname, pkg_dir)
+ with test_util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = test_util.submodule(name, subname, pkg_dir)
ham = self.init.import_module(fullname)
reloaded = self.init.reload(ham)
self.assertIs(reloaded, ham)
-class Frozen_ReloadTests(ReloadTests, unittest.TestCase):
- init = frozen_init
- util = frozen_util
-
-class Source_ReloadTests(ReloadTests, unittest.TestCase):
- init = source_init
- util = source_util
+(Frozen_ReloadTests,
+ Source_ReloadTests
+ ) = test_util.test_both(ReloadTests, init=init, util=util)
class InvalidateCacheTests:
@@ -384,11 +378,10 @@ class InvalidateCacheTests:
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
self.init.invalidate_caches() # Shouldn't trigger an exception.
-class Frozen_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase):
- init = frozen_init
-class Source_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase):
- init = source_init
+(Frozen_InvalidateCacheTests,
+ Source_InvalidateCacheTests
+ ) = test_util.test_both(InvalidateCacheTests, init=init)
class FrozenImportlibTests(unittest.TestCase):
@@ -398,6 +391,7 @@ class FrozenImportlibTests(unittest.TestCase):
# Can't do an isinstance() check since separate copies of importlib
# may have been used for import, so just check the name is not for the
# frozen loader.
+ source_init = init['Source']
self.assertNotEqual(source_init.__loader__.__class__.__name__,
'FrozenImporter')
@@ -426,11 +420,10 @@ class StartupTests:
elif self.machinery.FrozenImporter.find_module(name):
self.assertIsNot(module.__spec__, None)
-class Frozen_StartupTests(StartupTests, unittest.TestCase):
- machinery = frozen_machinery
-class Source_StartupTests(StartupTests, unittest.TestCase):
- machinery = source_machinery
+(Frozen_StartupTests,
+ Source_StartupTests
+ ) = test_util.test_both(StartupTests, machinery=machinery)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/test_lazy.py b/Lib/test/test_importlib/test_lazy.py
new file mode 100644
index 0000000..2e191bb
--- /dev/null
+++ b/Lib/test/test_importlib/test_lazy.py
@@ -0,0 +1,132 @@
+import importlib
+from importlib import abc
+from importlib import util
+import unittest
+
+from . import util as test_util
+
+
+class CollectInit:
+
+ def __init__(self, *args, **kwargs):
+ self.args = args
+ self.kwargs = kwargs
+
+ def exec_module(self, module):
+ return self
+
+
+class LazyLoaderFactoryTests(unittest.TestCase):
+
+ def test_init(self):
+ factory = util.LazyLoader.factory(CollectInit)
+ # E.g. what importlib.machinery.FileFinder instantiates loaders with
+ # plus keyword arguments.
+ lazy_loader = factory('module name', 'module path', kw='kw')
+ loader = lazy_loader.loader
+ self.assertEqual(('module name', 'module path'), loader.args)
+ self.assertEqual({'kw': 'kw'}, loader.kwargs)
+
+ def test_validation(self):
+ # No exec_module(), no lazy loading.
+ with self.assertRaises(TypeError):
+ util.LazyLoader.factory(object)
+
+
+class TestingImporter(abc.MetaPathFinder, abc.Loader):
+
+ module_name = 'lazy_loader_test'
+ mutated_name = 'changed'
+ loaded = None
+ source_code = 'attr = 42; __name__ = {!r}'.format(mutated_name)
+
+ def find_spec(self, name, path, target=None):
+ if name != self.module_name:
+ return None
+ return util.spec_from_loader(name, util.LazyLoader(self))
+
+ def exec_module(self, module):
+ exec(self.source_code, module.__dict__)
+ self.loaded = module
+
+
+class LazyLoaderTests(unittest.TestCase):
+
+ def test_init(self):
+ with self.assertRaises(TypeError):
+ util.LazyLoader(object)
+
+ def new_module(self, source_code=None):
+ loader = TestingImporter()
+ if source_code is not None:
+ loader.source_code = source_code
+ spec = util.spec_from_loader(TestingImporter.module_name,
+ util.LazyLoader(loader))
+ module = spec.loader.create_module(spec)
+ module.__spec__ = spec
+ module.__loader__ = spec.loader
+ spec.loader.exec_module(module)
+ # Module is now lazy.
+ self.assertIsNone(loader.loaded)
+ return module
+
+ def test_e2e(self):
+ # End-to-end test to verify the load is in fact lazy.
+ importer = TestingImporter()
+ assert importer.loaded is None
+ with test_util.uncache(importer.module_name):
+ with test_util.import_state(meta_path=[importer]):
+ module = importlib.import_module(importer.module_name)
+ self.assertIsNone(importer.loaded)
+ # Trigger load.
+ self.assertEqual(module.__loader__, importer)
+ self.assertIsNotNone(importer.loaded)
+ self.assertEqual(module, importer.loaded)
+
+ def test_attr_unchanged(self):
+ # An attribute only mutated as a side-effect of import should not be
+ # changed needlessly.
+ module = self.new_module()
+ self.assertEqual(TestingImporter.mutated_name, module.__name__)
+
+ def test_new_attr(self):
+ # A new attribute should persist.
+ module = self.new_module()
+ module.new_attr = 42
+ self.assertEqual(42, module.new_attr)
+
+ def test_mutated_preexisting_attr(self):
+ # Changing an attribute that already existed on the module --
+ # e.g. __name__ -- should persist.
+ module = self.new_module()
+ module.__name__ = 'bogus'
+ self.assertEqual('bogus', module.__name__)
+
+ def test_mutated_attr(self):
+ # Changing an attribute that comes into existence after an import
+ # should persist.
+ module = self.new_module()
+ module.attr = 6
+ self.assertEqual(6, module.attr)
+
+ def test_delete_eventual_attr(self):
+ # Deleting an attribute should stay deleted.
+ module = self.new_module()
+ del module.attr
+ self.assertFalse(hasattr(module, 'attr'))
+
+ def test_delete_preexisting_attr(self):
+ module = self.new_module()
+ del module.__name__
+ self.assertFalse(hasattr(module, '__name__'))
+
+ def test_module_substitution_error(self):
+ source_code = 'import sys; sys.modules[__name__] = 42'
+ module = self.new_module(source_code)
+ with test_util.uncache(TestingImporter.module_name):
+ with self.assertRaises(ValueError):
+ module.__name__
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py
index dc97ba1..df0af12 100644
--- a/Lib/test/test_importlib/test_locks.py
+++ b/Lib/test/test_importlib/test_locks.py
@@ -1,7 +1,6 @@
-from . import util
-frozen_init, source_init = util.import_importlib('importlib')
-frozen_bootstrap = frozen_init._bootstrap
-source_bootstrap = source_init._bootstrap
+from . import util as test_util
+
+init = test_util.import_importlib('importlib')
import sys
import time
@@ -32,14 +31,20 @@ if threading is not None:
test_timeout = None
# _release_save() unsupported
test_release_save_unacquired = None
+ # lock status in repr unsupported
+ test_repr = None
+ test_locked_repr = None
- class Frozen_ModuleLockAsRLockTests(ModuleLockAsRLockTests, lock_tests.RLockTests):
- LockType = frozen_bootstrap._ModuleLock
-
- class Source_ModuleLockAsRLockTests(ModuleLockAsRLockTests, lock_tests.RLockTests):
- LockType = source_bootstrap._ModuleLock
+ LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
+ for kind, splitinit in init.items()}
+ (Frozen_ModuleLockAsRLockTests,
+ Source_ModuleLockAsRLockTests
+ ) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests,
+ LockType=LOCK_TYPES)
else:
+ LOCK_TYPES = {}
+
class Frozen_ModuleLockAsRLockTests(unittest.TestCase):
pass
@@ -47,78 +52,94 @@ else:
pass
-class DeadlockAvoidanceTests:
-
- def setUp(self):
- try:
- self.old_switchinterval = sys.getswitchinterval()
- sys.setswitchinterval(0.000001)
- except AttributeError:
- self.old_switchinterval = None
-
- def tearDown(self):
- if self.old_switchinterval is not None:
- sys.setswitchinterval(self.old_switchinterval)
-
- def run_deadlock_avoidance_test(self, create_deadlock):
- NLOCKS = 10
- locks = [self.LockType(str(i)) for i in range(NLOCKS)]
- pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)]
- if create_deadlock:
- NTHREADS = NLOCKS
- else:
- NTHREADS = NLOCKS - 1
- barrier = threading.Barrier(NTHREADS)
- results = []
- def _acquire(lock):
- """Try to acquire the lock. Return True on success, False on deadlock."""
+if threading is not None:
+ class DeadlockAvoidanceTests:
+
+ def setUp(self):
try:
- lock.acquire()
- except self.DeadlockError:
- return False
+ self.old_switchinterval = sys.getswitchinterval()
+ sys.setswitchinterval(0.000001)
+ except AttributeError:
+ self.old_switchinterval = None
+
+ def tearDown(self):
+ if self.old_switchinterval is not None:
+ sys.setswitchinterval(self.old_switchinterval)
+
+ def run_deadlock_avoidance_test(self, create_deadlock):
+ NLOCKS = 10
+ locks = [self.LockType(str(i)) for i in range(NLOCKS)]
+ pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)]
+ if create_deadlock:
+ NTHREADS = NLOCKS
else:
- return True
- def f():
- a, b = pairs.pop()
- ra = _acquire(a)
- barrier.wait()
- rb = _acquire(b)
- results.append((ra, rb))
- if rb:
- b.release()
- if ra:
- a.release()
- lock_tests.Bunch(f, NTHREADS).wait_for_finished()
- self.assertEqual(len(results), NTHREADS)
- return results
-
- def test_deadlock(self):
- results = self.run_deadlock_avoidance_test(True)
- # At least one of the threads detected a potential deadlock on its
- # second acquire() call. It may be several of them, because the
- # deadlock avoidance mechanism is conservative.
- nb_deadlocks = results.count((True, False))
- self.assertGreaterEqual(nb_deadlocks, 1)
- self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks)
-
- def test_no_deadlock(self):
- results = self.run_deadlock_avoidance_test(False)
- self.assertEqual(results.count((True, False)), 0)
- self.assertEqual(results.count((True, True)), len(results))
-
-@unittest.skipUnless(threading, "threads needed for this test")
-class Frozen_DeadlockAvoidanceTests(DeadlockAvoidanceTests, unittest.TestCase):
- LockType = frozen_bootstrap._ModuleLock
- DeadlockError = frozen_bootstrap._DeadlockError
-
-@unittest.skipUnless(threading, "threads needed for this test")
-class Source_DeadlockAvoidanceTests(DeadlockAvoidanceTests, unittest.TestCase):
- LockType = source_bootstrap._ModuleLock
- DeadlockError = source_bootstrap._DeadlockError
+ NTHREADS = NLOCKS - 1
+ barrier = threading.Barrier(NTHREADS)
+ results = []
+
+ def _acquire(lock):
+ """Try to acquire the lock. Return True on success,
+ False on deadlock."""
+ try:
+ lock.acquire()
+ except self.DeadlockError:
+ return False
+ else:
+ return True
+
+ def f():
+ a, b = pairs.pop()
+ ra = _acquire(a)
+ barrier.wait()
+ rb = _acquire(b)
+ results.append((ra, rb))
+ if rb:
+ b.release()
+ if ra:
+ a.release()
+ lock_tests.Bunch(f, NTHREADS).wait_for_finished()
+ self.assertEqual(len(results), NTHREADS)
+ return results
+
+ def test_deadlock(self):
+ results = self.run_deadlock_avoidance_test(True)
+ # At least one of the threads detected a potential deadlock on its
+ # second acquire() call. It may be several of them, because the
+ # deadlock avoidance mechanism is conservative.
+ nb_deadlocks = results.count((True, False))
+ self.assertGreaterEqual(nb_deadlocks, 1)
+ self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks)
+
+ def test_no_deadlock(self):
+ results = self.run_deadlock_avoidance_test(False)
+ self.assertEqual(results.count((True, False)), 0)
+ self.assertEqual(results.count((True, True)), len(results))
+
+
+ DEADLOCK_ERRORS = {kind: splitinit._bootstrap._DeadlockError
+ for kind, splitinit in init.items()}
+
+ (Frozen_DeadlockAvoidanceTests,
+ Source_DeadlockAvoidanceTests
+ ) = test_util.test_both(DeadlockAvoidanceTests,
+ LockType=LOCK_TYPES,
+ DeadlockError=DEADLOCK_ERRORS)
+else:
+ DEADLOCK_ERRORS = {}
+
+ class Frozen_DeadlockAvoidanceTests(unittest.TestCase):
+ pass
+
+ class Source_DeadlockAvoidanceTests(unittest.TestCase):
+ pass
class LifetimeTests:
+ @property
+ def bootstrap(self):
+ return self.init._bootstrap
+
def test_lock_lifetime(self):
name = "xyzzy"
self.assertNotIn(name, self.bootstrap._module_locks)
@@ -135,11 +156,10 @@ class LifetimeTests:
self.assertEqual(0, len(self.bootstrap._module_locks),
self.bootstrap._module_locks)
-class Frozen_LifetimeTests(LifetimeTests, unittest.TestCase):
- bootstrap = frozen_bootstrap
-class Source_LifetimeTests(LifetimeTests, unittest.TestCase):
- bootstrap = source_bootstrap
+(Frozen_LifetimeTests,
+ Source_LifetimeTests
+ ) = test_util.test_both(LifetimeTests, init=init)
@support.reap_threads
diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py
index 71541f6..8b333e8 100644
--- a/Lib/test/test_importlib/test_spec.py
+++ b/Lib/test/test_importlib/test_spec.py
@@ -1,10 +1,8 @@
-from . import util
+from . import util as test_util
-frozen_init, source_init = util.import_importlib('importlib')
-frozen_bootstrap = frozen_init._bootstrap
-source_bootstrap = source_init._bootstrap
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
-frozen_util, source_util = util.import_importlib('importlib.util')
+init = test_util.import_importlib('importlib')
+machinery = test_util.import_importlib('importlib.machinery')
+util = test_util.import_importlib('importlib.util')
import os.path
from test.support import CleanImport
@@ -36,6 +34,9 @@ class TestLoader:
def _is_package(self, name):
return self.package
+ def create_module(self, spec):
+ return None
+
class NewLoader(TestLoader):
@@ -52,6 +53,8 @@ class LegacyLoader(TestLoader):
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
+ frozen_util = util['Frozen']
+
@frozen_util.module_for_loader
def load_module(self, module):
module.ham = self.HAM
@@ -221,18 +224,17 @@ class ModuleSpecTests:
self.assertEqual(self.loc_spec.cached, 'spam.pyc')
-class Frozen_ModuleSpecTests(ModuleSpecTests, unittest.TestCase):
- util = frozen_util
- machinery = frozen_machinery
-
-
-class Source_ModuleSpecTests(ModuleSpecTests, unittest.TestCase):
- util = source_util
- machinery = source_machinery
+(Frozen_ModuleSpecTests,
+ Source_ModuleSpecTests
+ ) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery)
class ModuleSpecMethodsTests:
+ @property
+ def bootstrap(self):
+ return self.init._bootstrap
+
def setUp(self):
self.name = 'spam'
self.path = 'spam.py'
@@ -243,152 +245,14 @@ class ModuleSpecMethodsTests:
origin=self.path)
self.loc_spec._set_fileattr = True
- # init_module_attrs
-
- def test_init_module_attrs(self):
- module = type(sys)(self.name)
- spec = self.machinery.ModuleSpec(self.name, self.loader)
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertEqual(module.__name__, spec.name)
- self.assertIs(module.__loader__, spec.loader)
- self.assertEqual(module.__package__, spec.parent)
- self.assertIs(module.__spec__, spec)
- self.assertFalse(hasattr(module, '__path__'))
- self.assertFalse(hasattr(module, '__file__'))
- self.assertFalse(hasattr(module, '__cached__'))
-
- def test_init_module_attrs_package(self):
- module = type(sys)(self.name)
- spec = self.machinery.ModuleSpec(self.name, self.loader)
- spec.submodule_search_locations = ['spam', 'ham']
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertEqual(module.__name__, spec.name)
- self.assertIs(module.__loader__, spec.loader)
- self.assertEqual(module.__package__, spec.parent)
- self.assertIs(module.__spec__, spec)
- self.assertIs(module.__path__, spec.submodule_search_locations)
- self.assertFalse(hasattr(module, '__file__'))
- self.assertFalse(hasattr(module, '__cached__'))
-
- def test_init_module_attrs_location(self):
- module = type(sys)(self.name)
- spec = self.loc_spec
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertEqual(module.__name__, spec.name)
- self.assertIs(module.__loader__, spec.loader)
- self.assertEqual(module.__package__, spec.parent)
- self.assertIs(module.__spec__, spec)
- self.assertFalse(hasattr(module, '__path__'))
- self.assertEqual(module.__file__, spec.origin)
- self.assertEqual(module.__cached__,
- self.util.cache_from_source(spec.origin))
-
- def test_init_module_attrs_different_name(self):
- module = type(sys)('eggs')
- spec = self.machinery.ModuleSpec(self.name, self.loader)
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertEqual(module.__name__, spec.name)
-
- def test_init_module_attrs_different_spec(self):
- module = type(sys)(self.name)
- module.__spec__ = self.machinery.ModuleSpec('eggs', object())
- spec = self.machinery.ModuleSpec(self.name, self.loader)
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertEqual(module.__name__, spec.name)
- self.assertIs(module.__loader__, spec.loader)
- self.assertEqual(module.__package__, spec.parent)
- self.assertIs(module.__spec__, spec)
-
- def test_init_module_attrs_already_set(self):
- module = type(sys)('ham.eggs')
- module.__loader__ = object()
- module.__package__ = 'ham'
- module.__path__ = ['eggs']
- module.__file__ = 'ham/eggs/__init__.py'
- module.__cached__ = self.util.cache_from_source(module.__file__)
- original = vars(module).copy()
- spec = self.loc_spec
- spec.submodule_search_locations = ['']
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertIs(module.__loader__, original['__loader__'])
- self.assertEqual(module.__package__, original['__package__'])
- self.assertIs(module.__path__, original['__path__'])
- self.assertEqual(module.__file__, original['__file__'])
- self.assertEqual(module.__cached__, original['__cached__'])
-
- def test_init_module_attrs_immutable(self):
- module = object()
- spec = self.loc_spec
- spec.submodule_search_locations = ['']
- self.bootstrap._SpecMethods(spec).init_module_attrs(module)
-
- self.assertFalse(hasattr(module, '__name__'))
- self.assertFalse(hasattr(module, '__loader__'))
- self.assertFalse(hasattr(module, '__package__'))
- self.assertFalse(hasattr(module, '__spec__'))
- self.assertFalse(hasattr(module, '__path__'))
- self.assertFalse(hasattr(module, '__file__'))
- self.assertFalse(hasattr(module, '__cached__'))
-
- # create()
-
- def test_create(self):
- created = self.bootstrap._SpecMethods(self.spec).create()
-
- self.assertEqual(created.__name__, self.spec.name)
- self.assertIs(created.__loader__, self.spec.loader)
- self.assertEqual(created.__package__, self.spec.parent)
- self.assertIs(created.__spec__, self.spec)
- self.assertFalse(hasattr(created, '__path__'))
- self.assertFalse(hasattr(created, '__file__'))
- self.assertFalse(hasattr(created, '__cached__'))
-
- def test_create_from_loader(self):
- module = type(sys.implementation)()
- class CreatingLoader(TestLoader):
- def create_module(self, spec):
- return module
- self.spec.loader = CreatingLoader()
- created = self.bootstrap._SpecMethods(self.spec).create()
-
- self.assertIs(created, module)
- self.assertEqual(created.__name__, self.spec.name)
- self.assertIs(created.__loader__, self.spec.loader)
- self.assertEqual(created.__package__, self.spec.parent)
- self.assertIs(created.__spec__, self.spec)
- self.assertFalse(hasattr(created, '__path__'))
- self.assertFalse(hasattr(created, '__file__'))
- self.assertFalse(hasattr(created, '__cached__'))
-
- def test_create_from_loader_not_handled(self):
- class CreatingLoader(TestLoader):
- def create_module(self, spec):
- return None
- self.spec.loader = CreatingLoader()
- created = self.bootstrap._SpecMethods(self.spec).create()
-
- self.assertEqual(created.__name__, self.spec.name)
- self.assertIs(created.__loader__, self.spec.loader)
- self.assertEqual(created.__package__, self.spec.parent)
- self.assertIs(created.__spec__, self.spec)
- self.assertFalse(hasattr(created, '__path__'))
- self.assertFalse(hasattr(created, '__file__'))
- self.assertFalse(hasattr(created, '__cached__'))
-
# exec()
def test_exec(self):
self.spec.loader = NewLoader()
- module = self.bootstrap._SpecMethods(self.spec).create()
+ module = self.util.module_from_spec(self.spec)
sys.modules[self.name] = module
self.assertFalse(hasattr(module, 'eggs'))
- self.bootstrap._SpecMethods(self.spec).exec(module)
+ self.bootstrap._exec(self.spec, module)
self.assertEqual(module.eggs, 1)
@@ -397,7 +261,7 @@ class ModuleSpecMethodsTests:
def test_load(self):
self.spec.loader = NewLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
installed = sys.modules[self.spec.name]
self.assertEqual(loaded.eggs, 1)
@@ -410,7 +274,7 @@ class ModuleSpecMethodsTests:
sys.modules[module.__name__] = replacement
self.spec.loader = ReplacingLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
installed = sys.modules[self.spec.name]
self.assertIs(loaded, replacement)
@@ -423,7 +287,7 @@ class ModuleSpecMethodsTests:
self.spec.loader = FailedLoader()
with CleanImport(self.spec.name):
with self.assertRaises(RuntimeError):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
self.assertNotIn(self.spec.name, sys.modules)
def test_load_failed_removed(self):
@@ -434,20 +298,20 @@ class ModuleSpecMethodsTests:
self.spec.loader = FailedLoader()
with CleanImport(self.spec.name):
with self.assertRaises(RuntimeError):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
self.assertNotIn(self.spec.name, sys.modules)
def test_load_legacy(self):
self.spec.loader = LegacyLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
self.assertEqual(loaded.ham, -1)
def test_load_legacy_attributes(self):
self.spec.loader = LegacyLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
self.assertIs(loaded.__loader__, self.spec.loader)
self.assertEqual(loaded.__package__, self.spec.parent)
@@ -461,7 +325,7 @@ class ModuleSpecMethodsTests:
return module
self.spec.loader = ImmutableLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
self.assertIs(sys.modules[self.spec.name], module)
@@ -470,8 +334,8 @@ class ModuleSpecMethodsTests:
def test_reload(self):
self.spec.loader = NewLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
- reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+ loaded = self.bootstrap._load(self.spec)
+ reloaded = self.bootstrap._exec(self.spec, loaded)
installed = sys.modules[self.spec.name]
self.assertEqual(loaded.eggs, 1)
@@ -481,9 +345,9 @@ class ModuleSpecMethodsTests:
def test_reload_modified(self):
self.spec.loader = NewLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
loaded.eggs = 2
- reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+ reloaded = self.bootstrap._exec(self.spec, loaded)
self.assertEqual(loaded.eggs, 1)
self.assertIs(reloaded, loaded)
@@ -491,9 +355,9 @@ class ModuleSpecMethodsTests:
def test_reload_extra_attributes(self):
self.spec.loader = NewLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
loaded.available = False
- reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+ reloaded = self.bootstrap._exec(self.spec, loaded)
self.assertFalse(loaded.available)
self.assertIs(reloaded, loaded)
@@ -501,12 +365,12 @@ class ModuleSpecMethodsTests:
def test_reload_init_module_attrs(self):
self.spec.loader = NewLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
+ loaded = self.bootstrap._load(self.spec)
loaded.__name__ = 'ham'
del loaded.__loader__
del loaded.__package__
del loaded.__spec__
- self.bootstrap._SpecMethods(self.spec).exec(loaded)
+ self.bootstrap._exec(self.spec, loaded)
self.assertEqual(loaded.__name__, self.spec.name)
self.assertIs(loaded.__loader__, self.spec.loader)
@@ -519,8 +383,8 @@ class ModuleSpecMethodsTests:
def test_reload_legacy(self):
self.spec.loader = LegacyLoader()
with CleanImport(self.spec.name):
- loaded = self.bootstrap._SpecMethods(self.spec).load()
- reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded)
+ loaded = self.bootstrap._load(self.spec)
+ reloaded = self.bootstrap._exec(self.spec, loaded)
installed = sys.modules[self.spec.name]
self.assertEqual(loaded.ham, -1)
@@ -528,20 +392,18 @@ class ModuleSpecMethodsTests:
self.assertIs(installed, loaded)
-class Frozen_ModuleSpecMethodsTests(ModuleSpecMethodsTests, unittest.TestCase):
- bootstrap = frozen_bootstrap
- machinery = frozen_machinery
- util = frozen_util
-
-
-class Source_ModuleSpecMethodsTests(ModuleSpecMethodsTests, unittest.TestCase):
- bootstrap = source_bootstrap
- machinery = source_machinery
- util = source_util
+(Frozen_ModuleSpecMethodsTests,
+ Source_ModuleSpecMethodsTests
+ ) = test_util.test_both(ModuleSpecMethodsTests, init=init, util=util,
+ machinery=machinery)
class ModuleReprTests:
+ @property
+ def bootstrap(self):
+ return self.init._bootstrap
+
def setUp(self):
self.module = type(os)('spam')
self.spec = self.machinery.ModuleSpec('spam', TestLoader())
@@ -625,16 +487,10 @@ class ModuleReprTests:
self.assertEqual(modrepr, '<module {!r}>'.format('spam'))
-class Frozen_ModuleReprTests(ModuleReprTests, unittest.TestCase):
- bootstrap = frozen_bootstrap
- machinery = frozen_machinery
- util = frozen_util
-
-
-class Source_ModuleReprTests(ModuleReprTests, unittest.TestCase):
- bootstrap = source_bootstrap
- machinery = source_machinery
- util = source_util
+(Frozen_ModuleReprTests,
+ Source_ModuleReprTests
+ ) = test_util.test_both(ModuleReprTests, init=init, util=util,
+ machinery=machinery)
class FactoryTests:
@@ -787,13 +643,14 @@ class FactoryTests:
# spec_from_file_location()
def test_spec_from_file_location_default(self):
- if self.machinery is source_machinery:
- raise unittest.SkipTest('not sure why this is breaking...')
spec = self.util.spec_from_file_location(self.name, self.path)
self.assertEqual(spec.name, self.name)
+ # Need to use a circuitous route to get at importlib.machinery to make
+ # sure the same class object is used in the isinstance() check as
+ # would have been used to create the loader.
self.assertIsInstance(spec.loader,
- self.machinery.SourceFileLoader)
+ self.util.abc.machinery.SourceFileLoader)
self.assertEqual(spec.loader.name, self.name)
self.assertEqual(spec.loader.path, self.path)
self.assertEqual(spec.origin, self.path)
@@ -947,11 +804,10 @@ class FactoryTests:
self.assertTrue(spec.has_location)
-class Frozen_FactoryTests(FactoryTests, unittest.TestCase):
- util = frozen_util
- machinery = frozen_machinery
+(Frozen_FactoryTests,
+ Source_FactoryTests
+ ) = test_util.test_both(FactoryTests, util=util, machinery=machinery)
-class Source_FactoryTests(FactoryTests, unittest.TestCase):
- util = source_util
- machinery = source_machinery
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index b2823c6..69466b2 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -1,10 +1,11 @@
-from importlib import util
-from . import util as test_util
-frozen_init, source_init = test_util.import_importlib('importlib')
-frozen_machinery, source_machinery = test_util.import_importlib('importlib.machinery')
-frozen_util, source_util = test_util.import_importlib('importlib.util')
+from . import util
+abc = util.import_importlib('importlib.abc')
+init = util.import_importlib('importlib')
+machinery = util.import_importlib('importlib.machinery')
+importlib_util = util.import_importlib('importlib.util')
import os
+import string
import sys
from test import support
import types
@@ -32,8 +33,94 @@ class DecodeSourceBytesTests:
self.assertEqual(self.util.decode_source(source_bytes),
'\n'.join([self.source, self.source]))
-Frozen_DecodeSourceBytesTests, Source_DecodeSourceBytesTests = test_util.test_both(
- DecodeSourceBytesTests, util=[frozen_util, source_util])
+
+(Frozen_DecodeSourceBytesTests,
+ Source_DecodeSourceBytesTests
+ ) = util.test_both(DecodeSourceBytesTests, util=importlib_util)
+
+
+class ModuleFromSpecTests:
+
+ def test_no_create_module(self):
+ class Loader:
+ def exec_module(self, module):
+ pass
+ spec = self.machinery.ModuleSpec('test', Loader())
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(1, len(w))
+ self.assertTrue(issubclass(w[0].category, DeprecationWarning))
+ self.assertIn('create_module', str(w[0].message))
+ self.assertIsInstance(module, types.ModuleType)
+ self.assertEqual(module.__name__, spec.name)
+
+ def test_create_module_returns_None(self):
+ class Loader(self.abc.Loader):
+ def create_module(self, spec):
+ return None
+ spec = self.machinery.ModuleSpec('test', Loader())
+ module = self.util.module_from_spec(spec)
+ self.assertIsInstance(module, types.ModuleType)
+ self.assertEqual(module.__name__, spec.name)
+
+ def test_create_module(self):
+ name = 'already set'
+ class CustomModule(types.ModuleType):
+ pass
+ class Loader(self.abc.Loader):
+ def create_module(self, spec):
+ module = CustomModule(spec.name)
+ module.__name__ = name
+ return module
+ spec = self.machinery.ModuleSpec('test', Loader())
+ module = self.util.module_from_spec(spec)
+ self.assertIsInstance(module, CustomModule)
+ self.assertEqual(module.__name__, name)
+
+ def test___name__(self):
+ spec = self.machinery.ModuleSpec('test', object())
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__name__, spec.name)
+
+ def test___spec__(self):
+ spec = self.machinery.ModuleSpec('test', object())
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__spec__, spec)
+
+ def test___loader__(self):
+ loader = object()
+ spec = self.machinery.ModuleSpec('test', loader)
+ module = self.util.module_from_spec(spec)
+ self.assertIs(module.__loader__, loader)
+
+ def test___package__(self):
+ spec = self.machinery.ModuleSpec('test.pkg', object())
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__package__, spec.parent)
+
+ def test___path__(self):
+ spec = self.machinery.ModuleSpec('test', object(), is_package=True)
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__path__, spec.submodule_search_locations)
+
+ def test___file__(self):
+ spec = self.machinery.ModuleSpec('test', object(), origin='some/path')
+ spec.has_location = True
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__file__, spec.origin)
+
+ def test___cached__(self):
+ spec = self.machinery.ModuleSpec('test', object())
+ spec.cached = 'some/path'
+ spec.has_location = True
+ module = self.util.module_from_spec(spec)
+ self.assertEqual(module.__cached__, spec.cached)
+
+(Frozen_ModuleFromSpecTests,
+ Source_ModuleFromSpecTests
+) = util.test_both(ModuleFromSpecTests, abc=abc, machinery=machinery,
+ util=importlib_util)
class ModuleForLoaderTests:
@@ -70,7 +157,7 @@ class ModuleForLoaderTests:
# Test that when no module exists in sys.modules a new module is
# created.
module_name = 'a.b.c'
- with test_util.uncache(module_name):
+ with util.uncache(module_name):
module = self.return_module(module_name)
self.assertIn(module_name, sys.modules)
self.assertIsInstance(module, types.ModuleType)
@@ -88,7 +175,7 @@ class ModuleForLoaderTests:
module = types.ModuleType('a.b.c')
module.__loader__ = 42
module.__package__ = 42
- with test_util.uncache(name):
+ with util.uncache(name):
sys.modules[name] = module
loader = FakeLoader()
returned_module = loader.load_module(name)
@@ -100,7 +187,7 @@ class ModuleForLoaderTests:
# Test that a module is removed from sys.modules if added but an
# exception is raised.
name = 'a.b.c'
- with test_util.uncache(name):
+ with util.uncache(name):
self.raise_exception(name)
self.assertNotIn(name, sys.modules)
@@ -108,7 +195,7 @@ class ModuleForLoaderTests:
# Test that a failure on reload leaves the module in-place.
name = 'a.b.c'
module = types.ModuleType(name)
- with test_util.uncache(name):
+ with util.uncache(name):
sys.modules[name] = module
self.raise_exception(name)
self.assertIs(module, sys.modules[name])
@@ -127,7 +214,7 @@ class ModuleForLoaderTests:
name = 'mod'
module = FalseModule(name)
- with test_util.uncache(name):
+ with util.uncache(name):
self.assertFalse(module)
sys.modules[name] = module
given = self.return_module(name)
@@ -146,7 +233,7 @@ class ModuleForLoaderTests:
return module
name = 'pkg.mod'
- with test_util.uncache(name):
+ with util.uncache(name):
loader = FakeLoader(False)
module = loader.load_module(name)
self.assertEqual(module.__name__, name)
@@ -154,15 +241,17 @@ class ModuleForLoaderTests:
self.assertEqual(module.__package__, 'pkg')
name = 'pkg.sub'
- with test_util.uncache(name):
+ with util.uncache(name):
loader = FakeLoader(True)
module = loader.load_module(name)
self.assertEqual(module.__name__, name)
self.assertIs(module.__loader__, loader)
self.assertEqual(module.__package__, name)
-Frozen_ModuleForLoaderTests, Source_ModuleForLoaderTests = test_util.test_both(
- ModuleForLoaderTests, util=[frozen_util, source_util])
+
+(Frozen_ModuleForLoaderTests,
+ Source_ModuleForLoaderTests
+ ) = util.test_both(ModuleForLoaderTests, util=importlib_util)
class SetPackageTests:
@@ -222,18 +311,25 @@ class SetPackageTests:
self.assertEqual(wrapped.__name__, fxn.__name__)
self.assertEqual(wrapped.__qualname__, fxn.__qualname__)
-Frozen_SetPackageTests, Source_SetPackageTests = test_util.test_both(
- SetPackageTests, util=[frozen_util, source_util])
+
+(Frozen_SetPackageTests,
+ Source_SetPackageTests
+ ) = util.test_both(SetPackageTests, util=importlib_util)
class SetLoaderTests:
"""Tests importlib.util.set_loader()."""
- class DummyLoader:
- @util.set_loader
- def load_module(self, module):
- return self.module
+ @property
+ def DummyLoader(self):
+ # Set DummyLoader on the class lazily.
+ class DummyLoader:
+ @self.util.set_loader
+ def load_module(self, module):
+ return self.module
+ self.__class__.DummyLoader = DummyLoader
+ return DummyLoader
def test_no_attribute(self):
loader = self.DummyLoader()
@@ -262,17 +358,10 @@ class SetLoaderTests:
warnings.simplefilter('ignore', DeprecationWarning)
self.assertEqual(42, loader.load_module('blah').__loader__)
-class Frozen_SetLoaderTests(SetLoaderTests, unittest.TestCase):
- class DummyLoader:
- @frozen_util.set_loader
- def load_module(self, module):
- return self.module
-class Source_SetLoaderTests(SetLoaderTests, unittest.TestCase):
- class DummyLoader:
- @source_util.set_loader
- def load_module(self, module):
- return self.module
+(Frozen_SetLoaderTests,
+ Source_SetLoaderTests
+ ) = util.test_both(SetLoaderTests, util=importlib_util)
class ResolveNameTests:
@@ -307,9 +396,10 @@ class ResolveNameTests:
with self.assertRaises(ValueError):
self.util.resolve_name('..bacon', 'spam')
-Frozen_ResolveNameTests, Source_ResolveNameTests = test_util.test_both(
- ResolveNameTests,
- util=[frozen_util, source_util])
+
+(Frozen_ResolveNameTests,
+ Source_ResolveNameTests
+ ) = util.test_both(ResolveNameTests, util=importlib_util)
class FindSpecTests:
@@ -320,7 +410,7 @@ class FindSpecTests:
def test_sys_modules(self):
name = 'some_mod'
- with test_util.uncache(name):
+ with util.uncache(name):
module = types.ModuleType(name)
loader = 'a loader!'
spec = self.machinery.ModuleSpec(name, loader)
@@ -332,7 +422,7 @@ class FindSpecTests:
def test_sys_modules_without___loader__(self):
name = 'some_mod'
- with test_util.uncache(name):
+ with util.uncache(name):
module = types.ModuleType(name)
del module.__loader__
loader = 'a loader!'
@@ -344,7 +434,7 @@ class FindSpecTests:
def test_sys_modules_spec_is_None(self):
name = 'some_mod'
- with test_util.uncache(name):
+ with util.uncache(name):
module = types.ModuleType(name)
module.__spec__ = None
sys.modules[name] = module
@@ -353,7 +443,7 @@ class FindSpecTests:
def test_sys_modules_loader_is_None(self):
name = 'some_mod'
- with test_util.uncache(name):
+ with util.uncache(name):
module = types.ModuleType(name)
spec = self.machinery.ModuleSpec(name, None)
module.__spec__ = spec
@@ -363,7 +453,7 @@ class FindSpecTests:
def test_sys_modules_spec_is_not_set(self):
name = 'some_mod'
- with test_util.uncache(name):
+ with util.uncache(name):
module = types.ModuleType(name)
try:
del module.__spec__
@@ -375,20 +465,11 @@ class FindSpecTests:
def test_success(self):
name = 'some_mod'
- with test_util.uncache(name):
- with test_util.import_state(meta_path=[self.FakeMetaFinder]):
+ with util.uncache(name):
+ with util.import_state(meta_path=[self.FakeMetaFinder]):
self.assertEqual((name, None, None),
self.util.find_spec(name))
-# def test_success_path(self):
-# # Searching on a path should work.
-# name = 'some_mod'
-# path = 'path to some place'
-# with test_util.uncache(name):
-# with test_util.import_state(meta_path=[self.FakeMetaFinder]):
-# self.assertEqual((name, path, None),
-# self.util.find_spec(name, path))
-
def test_nothing(self):
# None is returned upon failure to find a loader.
self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule'))
@@ -396,8 +477,8 @@ class FindSpecTests:
def test_find_submodule(self):
name = 'spam'
subname = 'ham'
- with test_util.temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ with util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = util.submodule(name, subname, pkg_dir)
spec = self.util.find_spec(fullname)
self.assertIsNot(spec, None)
self.assertIn(name, sorted(sys.modules))
@@ -409,9 +490,9 @@ class FindSpecTests:
def test_find_submodule_parent_already_imported(self):
name = 'spam'
subname = 'ham'
- with test_util.temp_module(name, pkg=True) as pkg_dir:
+ with util.temp_module(name, pkg=True) as pkg_dir:
self.init.import_module(name)
- fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ fullname, _ = util.submodule(name, subname, pkg_dir)
spec = self.util.find_spec(fullname)
self.assertIsNot(spec, None)
self.assertIn(name, sorted(sys.modules))
@@ -423,8 +504,8 @@ class FindSpecTests:
def test_find_relative_module(self):
name = 'spam'
subname = 'ham'
- with test_util.temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ with util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = util.submodule(name, subname, pkg_dir)
relname = '.' + subname
spec = self.util.find_spec(relname, name)
self.assertIsNot(spec, None)
@@ -437,8 +518,8 @@ class FindSpecTests:
def test_find_relative_module_missing_package(self):
name = 'spam'
subname = 'ham'
- with test_util.temp_module(name, pkg=True) as pkg_dir:
- fullname, _ = test_util.submodule(name, subname, pkg_dir)
+ with util.temp_module(name, pkg=True) as pkg_dir:
+ fullname, _ = util.submodule(name, subname, pkg_dir)
relname = '.' + subname
with self.assertRaises(ValueError):
self.util.find_spec(relname)
@@ -446,15 +527,10 @@ class FindSpecTests:
self.assertNotIn(fullname, sorted(sys.modules))
-class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase):
- init = frozen_init
- machinery = frozen_machinery
- util = frozen_util
-
-class Source_FindSpecTests(FindSpecTests, unittest.TestCase):
- init = source_init
- machinery = source_machinery
- util = source_util
+(Frozen_FindSpecTests,
+ Source_FindSpecTests
+ ) = util.test_both(FindSpecTests, init=init, util=importlib_util,
+ machinery=machinery)
class MagicNumberTests:
@@ -467,8 +543,10 @@ class MagicNumberTests:
# The magic number uses \r\n to come out wrong when splitting on lines.
self.assertTrue(self.util.MAGIC_NUMBER.endswith(b'\r\n'))
-Frozen_MagicNumberTests, Source_MagicNumberTests = test_util.test_both(
- MagicNumberTests, util=[frozen_util, source_util])
+
+(Frozen_MagicNumberTests,
+ Source_MagicNumberTests
+ ) = util.test_both(MagicNumberTests, util=importlib_util)
class PEP3147Tests:
@@ -485,7 +563,8 @@ class PEP3147Tests:
path = os.path.join('foo', 'bar', 'baz', 'qux.py')
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
'qux.{}.pyc'.format(self.tag))
- self.assertEqual(self.util.cache_from_source(path, True), expect)
+ self.assertEqual(self.util.cache_from_source(path, optimization=''),
+ expect)
def test_cache_from_source_no_cache_tag(self):
# No cache tag means NotImplementedError.
@@ -498,43 +577,103 @@ class PEP3147Tests:
path = os.path.join('foo.bar', 'file')
expect = os.path.join('foo.bar', '__pycache__',
'file{}.pyc'.format(self.tag))
- self.assertEqual(self.util.cache_from_source(path, True), expect)
+ self.assertEqual(self.util.cache_from_source(path, optimization=''),
+ expect)
- def test_cache_from_source_optimized(self):
- # Given the path to a .py file, return the path to its PEP 3147
- # defined .pyo file (i.e. under __pycache__).
+ def test_cache_from_source_debug_override(self):
+ # Given the path to a .py file, return the path to its PEP 3147/PEP 488
+ # defined .pyc file (i.e. under __pycache__).
path = os.path.join('foo', 'bar', 'baz', 'qux.py')
- expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
- 'qux.{}.pyo'.format(self.tag))
- self.assertEqual(self.util.cache_from_source(path, False), expect)
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ self.assertEqual(self.util.cache_from_source(path, False),
+ self.util.cache_from_source(path, optimization=1))
+ self.assertEqual(self.util.cache_from_source(path, True),
+ self.util.cache_from_source(path, optimization=''))
+ with warnings.catch_warnings():
+ warnings.simplefilter('error')
+ with self.assertRaises(DeprecationWarning):
+ self.util.cache_from_source(path, False)
+ with self.assertRaises(DeprecationWarning):
+ self.util.cache_from_source(path, True)
def test_cache_from_source_cwd(self):
path = 'foo.py'
expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
- self.assertEqual(self.util.cache_from_source(path, True), expect)
+ self.assertEqual(self.util.cache_from_source(path, optimization=''),
+ expect)
def test_cache_from_source_override(self):
# When debug_override is not None, it can be any true-ish or false-ish
# value.
path = os.path.join('foo', 'bar', 'baz.py')
- partial_expect = os.path.join('foo', 'bar', '__pycache__',
- 'baz.{}.py'.format(self.tag))
- self.assertEqual(self.util.cache_from_source(path, []), partial_expect + 'o')
- self.assertEqual(self.util.cache_from_source(path, [17]),
- partial_expect + 'c')
# However if the bool-ishness can't be determined, the exception
# propagates.
class Bearish:
def __bool__(self): raise RuntimeError
- with self.assertRaises(RuntimeError):
- self.util.cache_from_source('/foo/bar/baz.py', Bearish())
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ self.assertEqual(self.util.cache_from_source(path, []),
+ self.util.cache_from_source(path, optimization=1))
+ self.assertEqual(self.util.cache_from_source(path, [17]),
+ self.util.cache_from_source(path, optimization=''))
+ with self.assertRaises(RuntimeError):
+ self.util.cache_from_source('/foo/bar/baz.py', Bearish())
+
+
+ def test_cache_from_source_optimization_empty_string(self):
+ # Setting 'optimization' to '' leads to no optimization tag (PEP 488).
+ path = 'foo.py'
+ expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag))
+ self.assertEqual(self.util.cache_from_source(path, optimization=''),
+ expect)
+
+ def test_cache_from_source_optimization_None(self):
+ # Setting 'optimization' to None uses the interpreter's optimization.
+ # (PEP 488)
+ path = 'foo.py'
+ optimization_level = sys.flags.optimize
+ almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
+ if optimization_level == 0:
+ expect = almost_expect + '.pyc'
+ elif optimization_level <= 2:
+ expect = almost_expect + '.opt-{}.pyc'.format(optimization_level)
+ else:
+ msg = '{!r} is a non-standard optimization level'.format(optimization_level)
+ self.skipTest(msg)
+ self.assertEqual(self.util.cache_from_source(path, optimization=None),
+ expect)
+
+ def test_cache_from_source_optimization_set(self):
+ # The 'optimization' parameter accepts anything that has a string repr
+ # that passes str.alnum().
+ path = 'foo.py'
+ valid_characters = string.ascii_letters + string.digits
+ almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag))
+ got = self.util.cache_from_source(path, optimization=valid_characters)
+ # Test all valid characters are accepted.
+ self.assertEqual(got,
+ almost_expect + '.opt-{}.pyc'.format(valid_characters))
+ # str() should be called on argument.
+ self.assertEqual(self.util.cache_from_source(path, optimization=42),
+ almost_expect + '.opt-42.pyc')
+ # Invalid characters raise ValueError.
+ with self.assertRaises(ValueError):
+ self.util.cache_from_source(path, optimization='path/is/bad')
+
+ def test_cache_from_source_debug_override_optimization_both_set(self):
+ # Can only set one of the optimization-related parameters.
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ with self.assertRaises(TypeError):
+ self.util.cache_from_source('foo.py', False, optimization='')
@unittest.skipUnless(os.sep == '\\' and os.altsep == '/',
'test meaningful only where os.altsep is defined')
def test_sep_altsep_and_sep_cache_from_source(self):
# Windows path and PEP 3147 where sep is right of altsep.
self.assertEqual(
- self.util.cache_from_source('\\foo\\bar\\baz/qux.py', True),
+ self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''),
'\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag))
@unittest.skipUnless(sys.implementation.cache_tag is not None,
@@ -572,7 +711,12 @@ class PEP3147Tests:
ValueError, self.util.source_from_cache, '__pycache__/foo.pyc')
def test_source_from_cache_too_many_dots(self):
- # Too many dots in final path component -> ValueError
+ with self.assertRaises(ValueError):
+ self.util.source_from_cache(
+ '__pycache__/foo.cpython-32.opt-1.foo.pyc')
+
+ def test_source_from_cache_not_opt(self):
+ # Non-`opt-` path component -> ValueError
self.assertRaises(
ValueError, self.util.source_from_cache,
'__pycache__/foo.cpython-32.foo.pyc')
@@ -583,9 +727,21 @@ class PEP3147Tests:
ValueError, self.util.source_from_cache,
'/foo/bar/foo.cpython-32.foo.pyc')
-Frozen_PEP3147Tests, Source_PEP3147Tests = test_util.test_both(
- PEP3147Tests,
- util=[frozen_util, source_util])
+ def test_source_from_cache_optimized_bytecode(self):
+ # Optimized bytecode is not an issue.
+ path = os.path.join('__pycache__', 'foo.{}.opt-1.pyc'.format(self.tag))
+ self.assertEqual(self.util.source_from_cache(path), 'foo.py')
+
+ def test_source_from_cache_missing_optimization(self):
+ # An empty optimization level is a no-no.
+ path = os.path.join('__pycache__', 'foo.{}.opt-.pyc'.format(self.tag))
+ with self.assertRaises(ValueError):
+ self.util.source_from_cache(path)
+
+
+(Frozen_PEP3147Tests,
+ Source_PEP3147Tests
+ ) = util.test_both(PEP3147Tests, util=importlib_util)
if __name__ == '__main__':
diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py
index 96b4adc..c893bcf 100644
--- a/Lib/test/test_importlib/test_windows.py
+++ b/Lib/test/test_importlib/test_windows.py
@@ -1,14 +1,64 @@
-from . import util
-frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
+from . import util as test_util
+machinery = test_util.import_importlib('importlib.machinery')
+import os
+import re
import sys
import unittest
+from test import support
+from distutils.util import get_platform
+from contextlib import contextmanager
+from .util import temp_module
+
+support.import_module('winreg', required_on=['win'])
+from winreg import (
+ CreateKey, HKEY_CURRENT_USER,
+ SetValue, REG_SZ, KEY_ALL_ACCESS,
+ EnumKey, CloseKey, DeleteKey, OpenKey
+)
+
+def delete_registry_tree(root, subkey):
+ try:
+ hkey = OpenKey(root, subkey, access=KEY_ALL_ACCESS)
+ except OSError:
+ # subkey does not exist
+ return
+ while True:
+ try:
+ subsubkey = EnumKey(hkey, 0)
+ except OSError:
+ # no more subkeys
+ break
+ delete_registry_tree(hkey, subsubkey)
+ CloseKey(hkey)
+ DeleteKey(root, subkey)
+
+@contextmanager
+def setup_module(machinery, name, path=None):
+ if machinery.WindowsRegistryFinder.DEBUG_BUILD:
+ root = machinery.WindowsRegistryFinder.REGISTRY_KEY_DEBUG
+ else:
+ root = machinery.WindowsRegistryFinder.REGISTRY_KEY
+ key = root.format(fullname=name,
+ sys_version=sys.version[:3])
+ try:
+ with temp_module(name, "a = 1") as location:
+ subkey = CreateKey(HKEY_CURRENT_USER, key)
+ if path is None:
+ path = location + ".py"
+ SetValue(subkey, "", REG_SZ, path)
+ yield
+ finally:
+ if machinery.WindowsRegistryFinder.DEBUG_BUILD:
+ key = os.path.dirname(key)
+ delete_registry_tree(HKEY_CURRENT_USER, key)
@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
class WindowsRegistryFinderTests:
-
- # XXX Need a test that finds the spec via the registry.
+ # The module name is process-specific, allowing for
+ # simultaneous runs of the same test on a single machine.
+ test_module = "spamham{}".format(os.getpid())
def test_find_spec_missing(self):
spec = self.machinery.WindowsRegistryFinder.find_spec('spam')
@@ -18,12 +68,42 @@ class WindowsRegistryFinderTests:
loader = self.machinery.WindowsRegistryFinder.find_module('spam')
self.assertIs(loader, None)
+ def test_module_found(self):
+ with setup_module(self.machinery, self.test_module):
+ loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
+ spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
+ self.assertIsNot(loader, None)
+ self.assertIsNot(spec, None)
+
+ def test_module_not_found(self):
+ with setup_module(self.machinery, self.test_module, path="."):
+ loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module)
+ spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module)
+ self.assertIsNone(loader)
+ self.assertIsNone(spec)
+
+(Frozen_WindowsRegistryFinderTests,
+ Source_WindowsRegistryFinderTests
+ ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery)
+
+@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows')
+class WindowsExtensionSuffixTests:
+ def test_tagged_suffix(self):
+ suffixes = self.machinery.EXTENSION_SUFFIXES
+ expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info,
+ re.sub('[^a-zA-Z0-9]', '_', get_platform()))
+ try:
+ untagged_i = suffixes.index(".pyd")
+ except ValueError:
+ untagged_i = suffixes.index("_d.pyd")
+ expected_tag = "_d" + expected_tag
-class Frozen_WindowsRegistryFinderTests(WindowsRegistryFinderTests,
- unittest.TestCase):
- machinery = frozen_machinery
+ self.assertIn(expected_tag, suffixes)
+ # Ensure the tags are in the correct order
+ tagged_i = suffixes.index(expected_tag)
+ self.assertLess(tagged_i, untagged_i)
-class Source_WindowsRegistryFinderTests(WindowsRegistryFinderTests,
- unittest.TestCase):
- machinery = source_machinery
+(Frozen_WindowsExtensionSuffixTests,
+ Source_WindowsExtensionSuffixTests
+ ) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery)
diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py
index 885cec3..aa4cd7e 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -1,31 +1,85 @@
-from contextlib import contextmanager
-from importlib import util, invalidate_caches
+import builtins
+import contextlib
+import errno
+import functools
+import importlib
+from importlib import machinery, util, invalidate_caches
+import os
import os.path
from test import support
import unittest
import sys
+import tempfile
import types
+BUILTINS = types.SimpleNamespace()
+BUILTINS.good_name = None
+BUILTINS.bad_name = None
+if 'errno' in sys.builtin_module_names:
+ BUILTINS.good_name = 'errno'
+if 'importlib' not in sys.builtin_module_names:
+ BUILTINS.bad_name = 'importlib'
+
+EXTENSIONS = types.SimpleNamespace()
+EXTENSIONS.path = None
+EXTENSIONS.ext = None
+EXTENSIONS.filename = None
+EXTENSIONS.file_path = None
+EXTENSIONS.name = '_testcapi'
+
+def _extension_details():
+ global EXTENSIONS
+ for path in sys.path:
+ for ext in machinery.EXTENSION_SUFFIXES:
+ filename = EXTENSIONS.name + ext
+ file_path = os.path.join(path, filename)
+ if os.path.exists(file_path):
+ EXTENSIONS.path = path
+ EXTENSIONS.ext = ext
+ EXTENSIONS.filename = filename
+ EXTENSIONS.file_path = file_path
+ return
+
+_extension_details()
+
+
def import_importlib(module_name):
"""Import a module from importlib both w/ and w/o _frozen_importlib."""
fresh = ('importlib',) if '.' in module_name else ()
frozen = support.import_fresh_module(module_name)
source = support.import_fresh_module(module_name, fresh=fresh,
blocked=('_frozen_importlib',))
+ return {'Frozen': frozen, 'Source': source}
+
+
+def specialize_class(cls, kind, base=None, **kwargs):
+ # XXX Support passing in submodule names--load (and cache) them?
+ # That would clean up the test modules a bit more.
+ if base is None:
+ base = unittest.TestCase
+ elif not isinstance(base, type):
+ base = base[kind]
+ name = '{}_{}'.format(kind, cls.__name__)
+ bases = (cls, base)
+ specialized = types.new_class(name, bases)
+ specialized.__module__ = cls.__module__
+ specialized._NAME = cls.__name__
+ specialized._KIND = kind
+ for attr, values in kwargs.items():
+ value = values[kind]
+ setattr(specialized, attr, value)
+ return specialized
+
+
+def split_frozen(cls, base=None, **kwargs):
+ frozen = specialize_class(cls, 'Frozen', base, **kwargs)
+ source = specialize_class(cls, 'Source', base, **kwargs)
return frozen, source
-def test_both(test_class, **kwargs):
- frozen_tests = types.new_class('Frozen_'+test_class.__name__,
- (test_class, unittest.TestCase))
- source_tests = types.new_class('Source_'+test_class.__name__,
- (test_class, unittest.TestCase))
- frozen_tests.__module__ = source_tests.__module__ = test_class.__module__
- for attr, (frozen_value, source_value) in kwargs.items():
- setattr(frozen_tests, attr, frozen_value)
- setattr(source_tests, attr, source_value)
- return frozen_tests, source_tests
+def test_both(test_class, base=None, **kwargs):
+ return split_frozen(test_class, base, **kwargs)
CASE_INSENSITIVE_FS = True
@@ -38,6 +92,10 @@ if sys.platform not in ('win32', 'cygwin'):
if not os.path.exists(changed_name):
CASE_INSENSITIVE_FS = False
+source_importlib = import_importlib('importlib')['Source']
+__import__ = {'Frozen': staticmethod(builtins.__import__),
+ 'Source': staticmethod(source_importlib.__import__)}
+
def case_insensitive_tests(test):
"""Class decorator that nullifies tests requiring a case-insensitive
@@ -53,7 +111,7 @@ def submodule(parent, name, pkg_dir, content=''):
return '{}.{}'.format(parent, name), path
-@contextmanager
+@contextlib.contextmanager
def uncache(*names):
"""Uncache a module from sys.modules.
@@ -79,7 +137,7 @@ def uncache(*names):
pass
-@contextmanager
+@contextlib.contextmanager
def temp_module(name, content='', *, pkg=False):
conflicts = [n for n in sys.modules if n.partition('.')[0] == name]
with support.temp_cwd(None) as cwd:
@@ -103,7 +161,7 @@ def temp_module(name, content='', *, pkg=False):
yield location
-@contextmanager
+@contextlib.contextmanager
def import_state(**kwargs):
"""Context manager to manage the various importers and stored state in the
sys module.
@@ -198,6 +256,7 @@ class mock_modules(_ImporterMock):
raise
return self.modules[fullname]
+
class mock_spec(_ImporterMock):
"""Importer mock using PEP 451 APIs."""
@@ -223,3 +282,99 @@ class mock_spec(_ImporterMock):
self.module_code[module.__spec__.name]()
except KeyError:
pass
+
+
+def writes_bytecode_files(fxn):
+ """Decorator to protect sys.dont_write_bytecode from mutation and to skip
+ tests that require it to be set to False."""
+ if sys.dont_write_bytecode:
+ return lambda *args, **kwargs: None
+ @functools.wraps(fxn)
+ def wrapper(*args, **kwargs):
+ original = sys.dont_write_bytecode
+ sys.dont_write_bytecode = False
+ try:
+ to_return = fxn(*args, **kwargs)
+ finally:
+ sys.dont_write_bytecode = original
+ return to_return
+ return wrapper
+
+
+def ensure_bytecode_path(bytecode_path):
+ """Ensure that the __pycache__ directory for PEP 3147 pyc file exists.
+
+ :param bytecode_path: File system path to PEP 3147 pyc file.
+ """
+ try:
+ os.mkdir(os.path.dirname(bytecode_path))
+ except OSError as error:
+ if error.errno != errno.EEXIST:
+ raise
+
+
+@contextlib.contextmanager
+def create_modules(*names):
+ """Temporarily create each named module with an attribute (named 'attr')
+ that contains the name passed into the context manager that caused the
+ creation of the module.
+
+ All files are created in a temporary directory returned by
+ tempfile.mkdtemp(). This directory is inserted at the beginning of
+ sys.path. When the context manager exits all created files (source and
+ bytecode) are explicitly deleted.
+
+ No magic is performed when creating packages! This means that if you create
+ a module within a package you must also create the package's __init__ as
+ well.
+
+ """
+ source = 'attr = {0!r}'
+ created_paths = []
+ mapping = {}
+ state_manager = None
+ uncache_manager = None
+ try:
+ temp_dir = tempfile.mkdtemp()
+ mapping['.root'] = temp_dir
+ import_names = set()
+ for name in names:
+ if not name.endswith('__init__'):
+ import_name = name
+ else:
+ import_name = name[:-len('.__init__')]
+ import_names.add(import_name)
+ if import_name in sys.modules:
+ del sys.modules[import_name]
+ name_parts = name.split('.')
+ file_path = temp_dir
+ for directory in name_parts[:-1]:
+ file_path = os.path.join(file_path, directory)
+ if not os.path.exists(file_path):
+ os.mkdir(file_path)
+ created_paths.append(file_path)
+ file_path = os.path.join(file_path, name_parts[-1] + '.py')
+ with open(file_path, 'w') as file:
+ file.write(source.format(name))
+ created_paths.append(file_path)
+ mapping[name] = file_path
+ uncache_manager = uncache(*import_names)
+ uncache_manager.__enter__()
+ state_manager = import_state(path=[temp_dir])
+ state_manager.__enter__()
+ yield mapping
+ finally:
+ if state_manager is not None:
+ state_manager.__exit__(None, None, None)
+ if uncache_manager is not None:
+ uncache_manager.__exit__(None, None, None)
+ support.rmtree(temp_dir)
+
+
+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