summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_importlib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2014-05-09 18:32:57 (GMT)
committerBrett Cannon <brett@python.org>2014-05-09 18:32:57 (GMT)
commit732ac654c8a3e5f9048a53efaee7380e1775a630 (patch)
tree29f2569faa5c7c968c3201b8074dc32f6fe06d5f /Lib/test/test_importlib
parent91795c8e34cdae5616b4dd56fe616476dfdc1267 (diff)
downloadcpython-732ac654c8a3e5f9048a53efaee7380e1775a630.zip
cpython-732ac654c8a3e5f9048a53efaee7380e1775a630.tar.gz
cpython-732ac654c8a3e5f9048a53efaee7380e1775a630.tar.bz2
Issue #19721: Consolidate test_importlib utility code into a single
module.
Diffstat (limited to 'Lib/test/test_importlib')
-rw-r--r--Lib/test/test_importlib/builtin/test_finder.py19
-rw-r--r--Lib/test/test_importlib/builtin/test_loader.py25
-rw-r--r--Lib/test/test_importlib/builtin/util.py7
-rw-r--r--Lib/test/test_importlib/extension/test_case_sensitivity.py7
-rw-r--r--Lib/test/test_importlib/extension/test_finder.py11
-rw-r--r--Lib/test/test_importlib/extension/test_loader.py31
-rw-r--r--Lib/test/test_importlib/extension/test_path_hook.py9
-rw-r--r--Lib/test/test_importlib/extension/util.py19
-rw-r--r--Lib/test/test_importlib/import_/test___loader__.py5
-rw-r--r--Lib/test/test_importlib/import_/test___package__.py7
-rw-r--r--Lib/test/test_importlib/import_/test_api.py5
-rw-r--r--Lib/test/test_importlib/import_/test_caching.py5
-rw-r--r--Lib/test/test_importlib/import_/test_fromlist.py5
-rw-r--r--Lib/test/test_importlib/import_/test_meta_path.py7
-rw-r--r--Lib/test/test_importlib/import_/test_packages.py3
-rw-r--r--Lib/test/test_importlib/import_/test_path.py5
-rw-r--r--Lib/test/test_importlib/import_/test_relative_imports.py3
-rw-r--r--Lib/test/test_importlib/import_/util.py20
-rw-r--r--Lib/test/test_importlib/source/test_case_sensitivity.py3
-rw-r--r--Lib/test/test_importlib/source/test_file_loader.py61
-rw-r--r--Lib/test/test_importlib/source/test_finder.py11
-rw-r--r--Lib/test/test_importlib/source/test_path_hook.py3
-rw-r--r--Lib/test/test_importlib/source/test_source_encoding.py5
-rw-r--r--Lib/test/test_importlib/source/util.py96
-rw-r--r--Lib/test/test_importlib/util.py147
25 files changed, 249 insertions, 270 deletions
diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py
index 934562f..648ae95 100644
--- a/Lib/test/test_importlib/builtin/test_finder.py
+++ b/Lib/test/test_importlib/builtin/test_finder.py
@@ -1,6 +1,5 @@
from .. import abc
from .. import util
-from . import util as builtin_util
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
@@ -8,14 +7,15 @@ 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,8 +39,8 @@ 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)
@@ -48,14 +48,15 @@ Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests,
machinery=[frozen_machinery, source_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,8 +73,8 @@ 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)
diff --git a/Lib/test/test_importlib/builtin/test_loader.py b/Lib/test/test_importlib/builtin/test_loader.py
index a636f77..04fc6ef 100644
--- a/Lib/test/test_importlib/builtin/test_loader.py
+++ b/Lib/test/test_importlib/builtin/test_loader.py
@@ -1,6 +1,5 @@
from .. import abc
from .. import util
-from . import util as builtin_util
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
@@ -8,7 +7,7 @@ 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):
@@ -70,32 +69,34 @@ Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests,
machinery=[frozen_machinery, source_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.assertTrue(not 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,
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..989ad1d 100644
--- a/Lib/test/test_importlib/extension/test_case_sensitivity.py
+++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py
@@ -4,22 +4,21 @@ from test import support
import unittest
from .. import util
-from . import util as ext_util
frozen_machinery, source_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)
diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py
index 990f29c..be5887a 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,7 +35,7 @@ class FinderTests(abc.FinderTests):
def test_failure(self):
self.assertIsNone(self.find_module('asdfjkl;'))
-Frozen_FinderTests, Source_FinderTests = test_util.test_both(
+Frozen_FinderTests, Source_FinderTests = util.test_both(
FinderTests, machinery=machinery)
diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py
index fd9abf2..6a4e6ae 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,7 +70,7 @@ 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)
diff --git a/Lib/test/test_importlib/extension/test_path_hook.py b/Lib/test/test_importlib/extension/test_path_hook.py
index 49d6734..911d88a 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,9 +21,9 @@ 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(
+Frozen_PathHooksTests, Source_PathHooksTests = util.test_both(
PathHookTests, machinery=machinery)
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/import_/test___loader__.py b/Lib/test/test_importlib/import_/test___loader__.py
index 6df8010..5c02f9a 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:
@@ -25,7 +24,7 @@ class SpecLoaderAttributeTests:
self.assertEqual(loader, module.__loader__)
Frozen_SpecTests, Source_SpecTests = util.test_both(
- SpecLoaderAttributeTests, __import__=import_util.__import__)
+ SpecLoaderAttributeTests, __import__=util.__import__)
class LoaderMock:
@@ -63,7 +62,7 @@ class LoaderAttributeTests:
Frozen_Tests, Source_Tests = util.test_both(LoaderAttributeTests,
- __import__=import_util.__import__)
+ __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..8d3da98a 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__:
@@ -74,13 +73,13 @@ 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__)
+ Using__package__PEP302, __import__=util.__import__)
class Using__package__PEP302(Using__package__):
mock_modules = util.mock_spec
Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both(
- Using__package__PEP302, __import__=import_util.__import__)
+ Using__package__PEP302, __import__=util.__import__)
class Setting__package__:
@@ -95,7 +94,7 @@ class Setting__package__:
"""
- __import__ = import_util.__import__[1]
+ __import__ = util.__import__[1]
# [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..e1b280c 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
@@ -80,14 +79,14 @@ class OldAPITests(APITest):
bad_finder_loader = BadLoaderFinder
Frozen_OldAPITests, Source_OldAPITests = util.test_both(
- OldAPITests, __import__=import_util.__import__)
+ OldAPITests, __import__=util.__import__)
class SpecAPITests(APITest):
bad_finder_loader = BadSpecFinderLoader
Frozen_SpecAPITests, Source_SpecAPITests = util.test_both(
- SpecAPITests, __import__=import_util.__import__)
+ 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..2145d40 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
@@ -40,14 +39,14 @@ class UseCache:
self.assertEqual(cm.exception.name, name)
Frozen_UseCache, Source_UseCache = util.test_both(
- UseCache, __import__=import_util.__import__)
+ 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__[1]
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 58f244b..02dc805 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
@@ -30,7 +29,7 @@ class ReturnValue:
self.assertEqual(module.__name__, 'pkg.module')
Frozen_ReturnValue, Source_ReturnValue = util.test_both(
- ReturnValue, __import__=import_util.__import__)
+ ReturnValue, __import__=util.__import__)
class HandlingFromlist:
@@ -122,7 +121,7 @@ class HandlingFromlist:
self.assertEqual(module.module2.__name__, 'pkg.module2')
Frozen_FromList, Source_FromList = util.test_both(
- HandlingFromlist, __import__=import_util.__import__)
+ 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 dc45420..0a807ee 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
@@ -47,7 +46,7 @@ class CallingOrder:
self.assertTrue(issubclass(w[-1].category, ImportWarning))
Frozen_CallingOrder, Source_CallingOrder = util.test_both(
- CallingOrder, __import__=import_util.__import__)
+ CallingOrder, __import__=util.__import__)
class CallSignature:
@@ -105,14 +104,14 @@ class CallSignaturePEP302(CallSignature):
finder_name = 'find_module'
Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both(
- CallSignaturePEP302, __import__=import_util.__import__)
+ 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__)
+ 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..75abafc 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
@@ -103,7 +102,7 @@ class ParentModuleTests:
support.unload(subname)
Frozen_ParentTests, Source_ParentTests = util.test_both(
- ParentModuleTests, __import__=import_util.__import__)
+ 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 fa24ae3..23c8de6 100644
--- a/Lib/test/test_importlib/import_/test_path.py
+++ b/Lib/test/test_importlib/import_/test_path.py
@@ -1,5 +1,4 @@
from .. import util
-from . import util as import_util
importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery')
@@ -58,7 +57,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 +82,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)
diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py
index b216e9c..cc334d8 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
@@ -209,7 +208,7 @@ class RelativeImports:
self.__import__('sys', level=1)
Frozen_RelativeImports, Source_RelativeImports = util.test_both(
- RelativeImports, __import__=import_util.__import__)
+ 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..927e453 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')
diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py
index 2d415f9..5a0646c 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:
@@ -275,45 +274,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 +321,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 +332,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,7 +341,7 @@ 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)
@@ -371,7 +370,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 +389,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 +400,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 +412,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 +423,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 +434,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 +470,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'])
diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py
index 473297b..dbf422d 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)
diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py
index 92da772..08ba018 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'))
diff --git a/Lib/test/test_importlib/source/test_source_encoding.py b/Lib/test/test_importlib/source/test_source_encoding.py
index c62dfa1..28c75db 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,
@@ -120,7 +119,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,
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/util.py b/Lib/test/test_importlib/util.py
index 885cec3..056293e 100644
--- a/Lib/test/test_importlib/util.py
+++ b/Lib/test/test_importlib/util.py
@@ -1,12 +1,49 @@
-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 ()
@@ -38,6 +75,9 @@ if sys.platform not in ('win32', 'cygwin'):
if not os.path.exists(changed_name):
CASE_INSENSITIVE_FS = False
+_, source_importlib = import_importlib('importlib')
+__import__ = staticmethod(builtins.__import__), staticmethod(source_importlib.__import__)
+
def case_insensitive_tests(test):
"""Class decorator that nullifies tests requiring a case-insensitive
@@ -53,7 +93,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 +119,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 +143,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 +238,7 @@ class mock_modules(_ImporterMock):
raise
return self.modules[fullname]
+
class mock_spec(_ImporterMock):
"""Importer mock using PEP 451 APIs."""
@@ -223,3 +264,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