Kaydet (Commit) 732ac654 authored tarafından Brett Cannon's avatar Brett Cannon

Issue #19721: Consolidate test_importlib utility code into a single

module.
üst 91795c8e
from .. import abc from .. import abc
from .. import util from .. import util
from . import util as builtin_util
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
...@@ -8,14 +7,15 @@ import sys ...@@ -8,14 +7,15 @@ import sys
import unittest import unittest
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class FindSpecTests(abc.FinderTests): class FindSpecTests(abc.FinderTests):
"""Test find_spec() for built-in modules.""" """Test find_spec() for built-in modules."""
def test_module(self): def test_module(self):
# Common case. # Common case.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
found = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME) found = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name)
self.assertTrue(found) self.assertTrue(found)
self.assertEqual(found.origin, 'built-in') self.assertEqual(found.origin, 'built-in')
...@@ -39,8 +39,8 @@ class FindSpecTests(abc.FinderTests): ...@@ -39,8 +39,8 @@ class FindSpecTests(abc.FinderTests):
def test_ignore_path(self): def test_ignore_path(self):
# The value for 'path' should always trigger a failed import. # The value for 'path' should always trigger a failed import.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
spec = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME, spec = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name,
['pkg']) ['pkg'])
self.assertIsNone(spec) self.assertIsNone(spec)
...@@ -48,14 +48,15 @@ Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests, ...@@ -48,14 +48,15 @@ Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests,
machinery=[frozen_machinery, source_machinery]) machinery=[frozen_machinery, source_machinery])
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class FinderTests(abc.FinderTests): class FinderTests(abc.FinderTests):
"""Test find_module() for built-in modules.""" """Test find_module() for built-in modules."""
def test_module(self): def test_module(self):
# Common case. # Common case.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
found = self.machinery.BuiltinImporter.find_module(builtin_util.NAME) found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name)
self.assertTrue(found) self.assertTrue(found)
self.assertTrue(hasattr(found, 'load_module')) self.assertTrue(hasattr(found, 'load_module'))
...@@ -72,8 +73,8 @@ class FinderTests(abc.FinderTests): ...@@ -72,8 +73,8 @@ class FinderTests(abc.FinderTests):
def test_ignore_path(self): def test_ignore_path(self):
# The value for 'path' should always trigger a failed import. # The value for 'path' should always trigger a failed import.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
loader = self.machinery.BuiltinImporter.find_module(builtin_util.NAME, loader = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name,
['pkg']) ['pkg'])
self.assertIsNone(loader) self.assertIsNone(loader)
......
from .. import abc from .. import abc
from .. import util from .. import util
from . import util as builtin_util
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
...@@ -8,7 +7,7 @@ import sys ...@@ -8,7 +7,7 @@ import sys
import types import types
import unittest import unittest
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class LoaderTests(abc.LoaderTests): class LoaderTests(abc.LoaderTests):
"""Test load_module() for built-in modules.""" """Test load_module() for built-in modules."""
...@@ -29,8 +28,8 @@ class LoaderTests(abc.LoaderTests): ...@@ -29,8 +28,8 @@ class LoaderTests(abc.LoaderTests):
def test_module(self): def test_module(self):
# Common case. # Common case.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
module = self.load_module(builtin_util.NAME) module = self.load_module(util.BUILTINS.good_name)
self.verify(module) self.verify(module)
# Built-in modules cannot be a package. # Built-in modules cannot be a package.
...@@ -41,9 +40,9 @@ class LoaderTests(abc.LoaderTests): ...@@ -41,9 +40,9 @@ class LoaderTests(abc.LoaderTests):
def test_module_reuse(self): def test_module_reuse(self):
# Test that the same module is used in a reload. # Test that the same module is used in a reload.
with util.uncache(builtin_util.NAME): with util.uncache(util.BUILTINS.good_name):
module1 = self.load_module(builtin_util.NAME) module1 = self.load_module(util.BUILTINS.good_name)
module2 = self.load_module(builtin_util.NAME) module2 = self.load_module(util.BUILTINS.good_name)
self.assertIs(module1, module2) self.assertIs(module1, module2)
def test_unloadable(self): def test_unloadable(self):
...@@ -70,32 +69,34 @@ Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests, ...@@ -70,32 +69,34 @@ Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests,
machinery=[frozen_machinery, source_machinery]) machinery=[frozen_machinery, source_machinery])
@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
class InspectLoaderTests: class InspectLoaderTests:
"""Tests for InspectLoader methods for BuiltinImporter.""" """Tests for InspectLoader methods for BuiltinImporter."""
def test_get_code(self): def test_get_code(self):
# There is no code object. # 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) self.assertIsNone(result)
def test_get_source(self): def test_get_source(self):
# There is no source. # 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) self.assertIsNone(result)
def test_is_package(self): def test_is_package(self):
# Cannot be a package. # 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) self.assertTrue(not result)
@unittest.skipIf(util.BUILTINS.bad_name is None, 'all modules are built in')
def test_not_builtin(self): def test_not_builtin(self):
# Modules not built-in should raise ImportError. # Modules not built-in should raise ImportError.
for meth_name in ('get_code', 'get_source', 'is_package'): for meth_name in ('get_code', 'get_source', 'is_package'):
method = getattr(self.machinery.BuiltinImporter, meth_name) method = getattr(self.machinery.BuiltinImporter, meth_name)
with self.assertRaises(ImportError) as cm: with self.assertRaises(ImportError) as cm:
method(builtin_util.BAD_NAME) method(util.BUILTINS.bad_name)
self.assertRaises(builtin_util.BAD_NAME) self.assertRaises(util.BUILTINS.bad_name)
Frozen_InspectLoaderTests, Source_InspectLoaderTests = util.test_both( Frozen_InspectLoaderTests, Source_InspectLoaderTests = util.test_both(
InspectLoaderTests, InspectLoaderTests,
......
import sys
assert 'errno' in sys.builtin_module_names
NAME = 'errno'
assert 'importlib' not in sys.builtin_module_names
BAD_NAME = 'importlib'
...@@ -4,22 +4,21 @@ from test import support ...@@ -4,22 +4,21 @@ from test import support
import unittest import unittest
from .. import util from .. import util
from . import util as ext_util
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
# XXX find_spec tests # 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 @util.case_insensitive_tests
class ExtensionModuleCaseSensitivityTest: class ExtensionModuleCaseSensitivityTest:
def find_module(self): def find_module(self):
good_name = ext_util.NAME good_name = util.EXTENSIONS.name
bad_name = good_name.upper() bad_name = good_name.upper()
assert good_name != bad_name assert good_name != bad_name
finder = self.machinery.FileFinder(ext_util.PATH, finder = self.machinery.FileFinder(util.EXTENSIONS.path,
(self.machinery.ExtensionFileLoader, (self.machinery.ExtensionFileLoader,
self.machinery.EXTENSION_SUFFIXES)) self.machinery.EXTENSION_SUFFIXES))
return finder.find_module(bad_name) return finder.find_module(bad_name)
......
from .. import abc 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 unittest
import warnings import warnings
...@@ -14,7 +13,7 @@ class FinderTests(abc.FinderTests): ...@@ -14,7 +13,7 @@ class FinderTests(abc.FinderTests):
"""Test the finder for extension modules.""" """Test the finder for extension modules."""
def find_module(self, fullname): def find_module(self, fullname):
importer = self.machinery.FileFinder(util.PATH, importer = self.machinery.FileFinder(util.EXTENSIONS.path,
(self.machinery.ExtensionFileLoader, (self.machinery.ExtensionFileLoader,
self.machinery.EXTENSION_SUFFIXES)) self.machinery.EXTENSION_SUFFIXES))
with warnings.catch_warnings(): with warnings.catch_warnings():
...@@ -22,7 +21,7 @@ class FinderTests(abc.FinderTests): ...@@ -22,7 +21,7 @@ class FinderTests(abc.FinderTests):
return importer.find_module(fullname) return importer.find_module(fullname)
def test_module(self): 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. # No extension module as an __init__ available for testing.
test_package = test_package_in_package = None test_package = test_package_in_package = None
...@@ -36,7 +35,7 @@ class FinderTests(abc.FinderTests): ...@@ -36,7 +35,7 @@ class FinderTests(abc.FinderTests):
def test_failure(self): def test_failure(self):
self.assertIsNone(self.find_module('asdfjkl;')) self.assertIsNone(self.find_module('asdfjkl;'))
Frozen_FinderTests, Source_FinderTests = test_util.test_both( Frozen_FinderTests, Source_FinderTests = util.test_both(
FinderTests, machinery=machinery) FinderTests, machinery=machinery)
......
from . import util as ext_util
from .. import abc from .. import abc
from .. import util from .. import util
...@@ -15,8 +14,8 @@ class LoaderTests(abc.LoaderTests): ...@@ -15,8 +14,8 @@ class LoaderTests(abc.LoaderTests):
"""Test load_module() for extension modules.""" """Test load_module() for extension modules."""
def setUp(self): def setUp(self):
self.loader = self.machinery.ExtensionFileLoader(ext_util.NAME, self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
ext_util.FILEPATH) util.EXTENSIONS.file_path)
def load_module(self, fullname): def load_module(self, fullname):
return self.loader.load_module(fullname) return self.loader.load_module(fullname)
...@@ -29,23 +28,23 @@ class LoaderTests(abc.LoaderTests): ...@@ -29,23 +28,23 @@ class LoaderTests(abc.LoaderTests):
self.load_module('XXX') self.load_module('XXX')
def test_equality(self): def test_equality(self):
other = self.machinery.ExtensionFileLoader(ext_util.NAME, other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name,
ext_util.FILEPATH) util.EXTENSIONS.file_path)
self.assertEqual(self.loader, other) self.assertEqual(self.loader, other)
def test_inequality(self): def test_inequality(self):
other = self.machinery.ExtensionFileLoader('_' + ext_util.NAME, other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name,
ext_util.FILEPATH) util.EXTENSIONS.file_path)
self.assertNotEqual(self.loader, other) self.assertNotEqual(self.loader, other)
def test_module(self): def test_module(self):
with util.uncache(ext_util.NAME): with util.uncache(util.EXTENSIONS.name):
module = self.load_module(ext_util.NAME) module = self.load_module(util.EXTENSIONS.name)
for attr, value in [('__name__', ext_util.NAME), for attr, value in [('__name__', util.EXTENSIONS.name),
('__file__', ext_util.FILEPATH), ('__file__', util.EXTENSIONS.file_path),
('__package__', '')]: ('__package__', '')]:
self.assertEqual(getattr(module, attr), value) 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.assertIsInstance(module.__loader__,
self.machinery.ExtensionFileLoader) self.machinery.ExtensionFileLoader)
...@@ -56,9 +55,9 @@ class LoaderTests(abc.LoaderTests): ...@@ -56,9 +55,9 @@ class LoaderTests(abc.LoaderTests):
test_lacking_parent = None test_lacking_parent = None
def test_module_reuse(self): def test_module_reuse(self):
with util.uncache(ext_util.NAME): with util.uncache(util.EXTENSIONS.name):
module1 = self.load_module(ext_util.NAME) module1 = self.load_module(util.EXTENSIONS.name)
module2 = self.load_module(ext_util.NAME) module2 = self.load_module(util.EXTENSIONS.name)
self.assertIs(module1, module2) self.assertIs(module1, module2)
# No easy way to trigger a failure after a successful import. # No easy way to trigger a failure after a successful import.
...@@ -71,7 +70,7 @@ class LoaderTests(abc.LoaderTests): ...@@ -71,7 +70,7 @@ class LoaderTests(abc.LoaderTests):
self.assertEqual(cm.exception.name, name) self.assertEqual(cm.exception.name, name)
def test_is_package(self): 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: for suffix in self.machinery.EXTENSION_SUFFIXES:
path = os.path.join('some', 'path', 'pkg', '__init__' + suffix) path = os.path.join('some', 'path', 'pkg', '__init__' + suffix)
loader = self.machinery.ExtensionFileLoader('pkg', path) loader = self.machinery.ExtensionFileLoader('pkg', path)
......
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 collections
import sys import sys
...@@ -22,9 +21,9 @@ class PathHookTests: ...@@ -22,9 +21,9 @@ class PathHookTests:
def test_success(self): def test_success(self):
# Path hook should handle a directory where a known extension module # Path hook should handle a directory where a known extension module
# exists. # 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) PathHookTests, machinery=machinery)
......
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
...@@ -4,7 +4,6 @@ import types ...@@ -4,7 +4,6 @@ import types
import unittest import unittest
from .. import util from .. import util
from . import util as import_util
class SpecLoaderMock: class SpecLoaderMock:
...@@ -25,7 +24,7 @@ class SpecLoaderAttributeTests: ...@@ -25,7 +24,7 @@ class SpecLoaderAttributeTests:
self.assertEqual(loader, module.__loader__) self.assertEqual(loader, module.__loader__)
Frozen_SpecTests, Source_SpecTests = util.test_both( Frozen_SpecTests, Source_SpecTests = util.test_both(
SpecLoaderAttributeTests, __import__=import_util.__import__) SpecLoaderAttributeTests, __import__=util.__import__)
class LoaderMock: class LoaderMock:
...@@ -63,7 +62,7 @@ class LoaderAttributeTests: ...@@ -63,7 +62,7 @@ class LoaderAttributeTests:
Frozen_Tests, Source_Tests = util.test_both(LoaderAttributeTests, Frozen_Tests, Source_Tests = util.test_both(LoaderAttributeTests,
__import__=import_util.__import__) __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -6,7 +6,6 @@ of using the typical __path__/__name__ test). ...@@ -6,7 +6,6 @@ of using the typical __path__/__name__ test).
""" """
import unittest import unittest
from .. import util from .. import util
from . import util as import_util
class Using__package__: class Using__package__:
...@@ -74,13 +73,13 @@ class Using__package__PEP302(Using__package__): ...@@ -74,13 +73,13 @@ class Using__package__PEP302(Using__package__):
mock_modules = util.mock_modules mock_modules = util.mock_modules
Frozen_UsingPackagePEP302, Source_UsingPackagePEP302 = util.test_both( 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__): class Using__package__PEP302(Using__package__):
mock_modules = util.mock_spec mock_modules = util.mock_spec
Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both( Frozen_UsingPackagePEP451, Source_UsingPackagePEP451 = util.test_both(
Using__package__PEP302, __import__=import_util.__import__) Using__package__PEP302, __import__=util.__import__)
class Setting__package__: class Setting__package__:
...@@ -95,7 +94,7 @@ class Setting__package__: ...@@ -95,7 +94,7 @@ class Setting__package__:
""" """
__import__ = import_util.__import__[1] __import__ = util.__import__[1]
# [top-level] # [top-level]
def test_top_level(self): def test_top_level(self):
......
from .. import util from .. import util
from . import util as import_util
from importlib import machinery from importlib import machinery
import sys import sys
...@@ -80,14 +79,14 @@ class OldAPITests(APITest): ...@@ -80,14 +79,14 @@ class OldAPITests(APITest):
bad_finder_loader = BadLoaderFinder bad_finder_loader = BadLoaderFinder
Frozen_OldAPITests, Source_OldAPITests = util.test_both( Frozen_OldAPITests, Source_OldAPITests = util.test_both(
OldAPITests, __import__=import_util.__import__) OldAPITests, __import__=util.__import__)
class SpecAPITests(APITest): class SpecAPITests(APITest):
bad_finder_loader = BadSpecFinderLoader bad_finder_loader = BadSpecFinderLoader
Frozen_SpecAPITests, Source_SpecAPITests = util.test_both( Frozen_SpecAPITests, Source_SpecAPITests = util.test_both(
SpecAPITests, __import__=import_util.__import__) SpecAPITests, __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
"""Test that sys.modules is used properly by import.""" """Test that sys.modules is used properly by import."""
from .. import util from .. import util
from . import util as import_util
import sys import sys
from types import MethodType from types import MethodType
import unittest import unittest
...@@ -40,14 +39,14 @@ class UseCache: ...@@ -40,14 +39,14 @@ class UseCache:
self.assertEqual(cm.exception.name, name) self.assertEqual(cm.exception.name, name)
Frozen_UseCache, Source_UseCache = util.test_both( Frozen_UseCache, Source_UseCache = util.test_both(
UseCache, __import__=import_util.__import__) UseCache, __import__=util.__import__)
class ImportlibUseCache(UseCache, unittest.TestCase): class ImportlibUseCache(UseCache, unittest.TestCase):
# Pertinent only to PEP 302; exec_module() doesn't return a module. # 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): def create_mock(self, *names, return_=None):
mock = util.mock_modules(*names) mock = util.mock_modules(*names)
......
"""Test that the semantics relating to the 'fromlist' argument are correct.""" """Test that the semantics relating to the 'fromlist' argument are correct."""
from .. import util from .. import util
from . import util as import_util
import unittest import unittest
...@@ -30,7 +29,7 @@ class ReturnValue: ...@@ -30,7 +29,7 @@ class ReturnValue:
self.assertEqual(module.__name__, 'pkg.module') self.assertEqual(module.__name__, 'pkg.module')
Frozen_ReturnValue, Source_ReturnValue = util.test_both( Frozen_ReturnValue, Source_ReturnValue = util.test_both(
ReturnValue, __import__=import_util.__import__) ReturnValue, __import__=util.__import__)
class HandlingFromlist: class HandlingFromlist:
...@@ -122,7 +121,7 @@ class HandlingFromlist: ...@@ -122,7 +121,7 @@ class HandlingFromlist:
self.assertEqual(module.module2.__name__, 'pkg.module2') self.assertEqual(module.module2.__name__, 'pkg.module2')
Frozen_FromList, Source_FromList = util.test_both( Frozen_FromList, Source_FromList = util.test_both(
HandlingFromlist, __import__=import_util.__import__) HandlingFromlist, __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
from .. import util from .. import util
from . import util as import_util
import importlib._bootstrap import importlib._bootstrap
import sys import sys
from types import MethodType from types import MethodType
...@@ -47,7 +46,7 @@ class CallingOrder: ...@@ -47,7 +46,7 @@ class CallingOrder:
self.assertTrue(issubclass(w[-1].category, ImportWarning)) self.assertTrue(issubclass(w[-1].category, ImportWarning))
Frozen_CallingOrder, Source_CallingOrder = util.test_both( Frozen_CallingOrder, Source_CallingOrder = util.test_both(
CallingOrder, __import__=import_util.__import__) CallingOrder, __import__=util.__import__)
class CallSignature: class CallSignature:
...@@ -105,14 +104,14 @@ class CallSignaturePEP302(CallSignature): ...@@ -105,14 +104,14 @@ class CallSignaturePEP302(CallSignature):
finder_name = 'find_module' finder_name = 'find_module'
Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both( Frozen_CallSignaturePEP302, Source_CallSignaturePEP302 = util.test_both(
CallSignaturePEP302, __import__=import_util.__import__) CallSignaturePEP302, __import__=util.__import__)
class CallSignaturePEP451(CallSignature): class CallSignaturePEP451(CallSignature):
mock_modules = util.mock_spec mock_modules = util.mock_spec
finder_name = 'find_spec' finder_name = 'find_spec'
Frozen_CallSignaturePEP451, Source_CallSignaturePEP451 = util.test_both( Frozen_CallSignaturePEP451, Source_CallSignaturePEP451 = util.test_both(
CallSignaturePEP451, __import__=import_util.__import__) CallSignaturePEP451, __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
from .. import util from .. import util
from . import util as import_util
import sys import sys
import unittest import unittest
import importlib import importlib
...@@ -103,7 +102,7 @@ class ParentModuleTests: ...@@ -103,7 +102,7 @@ class ParentModuleTests:
support.unload(subname) support.unload(subname)
Frozen_ParentTests, Source_ParentTests = util.test_both( Frozen_ParentTests, Source_ParentTests = util.test_both(
ParentModuleTests, __import__=import_util.__import__) ParentModuleTests, __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
from .. import util from .. import util
from . import util as import_util
importlib = util.import_importlib('importlib') importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery') machinery = util.import_importlib('importlib.machinery')
...@@ -58,7 +57,7 @@ class FinderTests: ...@@ -58,7 +57,7 @@ class FinderTests:
module = '<test module>' module = '<test module>'
path = '<test path>' path = '<test path>'
importer = util.mock_spec(module) 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]): with util.import_state(path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module, [path]) loader = self.machinery.PathFinder.find_module(module, [path])
self.assertIs(loader, importer) self.assertIs(loader, importer)
...@@ -83,7 +82,7 @@ class FinderTests: ...@@ -83,7 +82,7 @@ class FinderTests:
path = '' path = ''
module = '<test module>' module = '<test module>'
importer = util.mock_spec(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]): with util.import_state(path=[path], path_hooks=[hook]):
loader = self.machinery.PathFinder.find_module(module) loader = self.machinery.PathFinder.find_module(module)
self.assertIs(loader, importer) self.assertIs(loader, importer)
......
"""Test relative imports (PEP 328).""" """Test relative imports (PEP 328)."""
from .. import util from .. import util
from . import util as import_util
import sys import sys
import unittest import unittest
...@@ -209,7 +208,7 @@ class RelativeImports: ...@@ -209,7 +208,7 @@ class RelativeImports:
self.__import__('sys', level=1) self.__import__('sys', level=1)
Frozen_RelativeImports, Source_RelativeImports = util.test_both( Frozen_RelativeImports, Source_RelativeImports = util.test_both(
RelativeImports, __import__=import_util.__import__) RelativeImports, __import__=util.__import__)
if __name__ == '__main__': if __name__ == '__main__':
......
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
"""Test case-sensitivity (PEP 235).""" """Test case-sensitivity (PEP 235)."""
from .. import util from .. import util
from . import util as source_util
importlib = util.import_importlib('importlib') importlib = util.import_importlib('importlib')
machinery = util.import_importlib('importlib.machinery') machinery = util.import_importlib('importlib.machinery')
...@@ -32,7 +31,7 @@ class CaseSensitivityTest: ...@@ -32,7 +31,7 @@ class CaseSensitivityTest:
"""Look for a module with matching and non-matching sensitivity.""" """Look for a module with matching and non-matching sensitivity."""
sensitive_pkg = 'sensitive.{0}'.format(self.name) sensitive_pkg = 'sensitive.{0}'.format(self.name)
insensitive_pkg = 'insensitive.{0}'.format(self.name.lower()) 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: with context as mapping:
sensitive_path = os.path.join(mapping['.root'], 'sensitive') sensitive_path = os.path.join(mapping['.root'], 'sensitive')
insensitive_path = os.path.join(mapping['.root'], 'insensitive') insensitive_path = os.path.join(mapping['.root'], 'insensitive')
......
from .. import abc from .. import abc
from .. import util from .. import util
from . import util as source_util
machinery = util.import_importlib('importlib.machinery') machinery = util.import_importlib('importlib.machinery')
...@@ -60,7 +59,7 @@ class FinderTests(abc.FinderTests): ...@@ -60,7 +59,7 @@ class FinderTests(abc.FinderTests):
""" """
if create is None: if create is None:
create = {test} create = {test}
with source_util.create_modules(*create) as mapping: with util.create_modules(*create) as mapping:
if compile_: if compile_:
for name in compile_: for name in compile_:
py_compile.compile(mapping[name]) py_compile.compile(mapping[name])
...@@ -100,14 +99,14 @@ class FinderTests(abc.FinderTests): ...@@ -100,14 +99,14 @@ class FinderTests(abc.FinderTests):
# [sub module] # [sub module]
def test_module_in_package(self): 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__']) pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub') loader = self.import_(pkg_dir, 'pkg.sub')
self.assertTrue(hasattr(loader, 'load_module')) self.assertTrue(hasattr(loader, 'load_module'))
# [sub package] # [sub package]
def test_package_in_package(self): 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: with context as mapping:
pkg_dir = os.path.dirname(mapping['pkg.__init__']) pkg_dir = os.path.dirname(mapping['pkg.__init__'])
loader = self.import_(pkg_dir, 'pkg.sub') loader = self.import_(pkg_dir, 'pkg.sub')
...@@ -120,7 +119,7 @@ class FinderTests(abc.FinderTests): ...@@ -120,7 +119,7 @@ class FinderTests(abc.FinderTests):
self.assertIn('__init__', loader.get_filename(name)) self.assertIn('__init__', loader.get_filename(name))
def test_failure(self): 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') nothing = self.import_(mapping['.root'], 'sdfsadsadf')
self.assertIsNone(nothing) self.assertIsNone(nothing)
...@@ -147,7 +146,7 @@ class FinderTests(abc.FinderTests): ...@@ -147,7 +146,7 @@ class FinderTests(abc.FinderTests):
# Regression test for http://bugs.python.org/issue14846 # Regression test for http://bugs.python.org/issue14846
def test_dir_removal_handling(self): def test_dir_removal_handling(self):
mod = 'mod' mod = 'mod'
with source_util.create_modules(mod) as mapping: with util.create_modules(mod) as mapping:
finder = self.get_finder(mapping['.root']) finder = self.get_finder(mapping['.root'])
found = self._find(finder, 'mod', loader_only=True) found = self._find(finder, 'mod', loader_only=True)
self.assertIsNotNone(found) self.assertIsNotNone(found)
......
from .. import util from .. import util
from . import util as source_util
machinery = util.import_importlib('importlib.machinery') machinery = util.import_importlib('importlib.machinery')
...@@ -15,7 +14,7 @@ class PathHookTest: ...@@ -15,7 +14,7 @@ class PathHookTest:
self.machinery.SOURCE_SUFFIXES)) self.machinery.SOURCE_SUFFIXES))
def test_success(self): 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']), self.assertTrue(hasattr(self.path_hook()(mapping['.root']),
'find_module')) 'find_module'))
......
from .. import util from .. import util
from . import util as source_util
machinery = util.import_importlib('importlib.machinery') machinery = util.import_importlib('importlib.machinery')
...@@ -37,7 +36,7 @@ class EncodingTest: ...@@ -37,7 +36,7 @@ class EncodingTest:
module_name = '_temp' module_name = '_temp'
def run_test(self, source): 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: with open(mapping[self.module_name], 'wb') as file:
file.write(source) file.write(source)
loader = self.machinery.SourceFileLoader(self.module_name, loader = self.machinery.SourceFileLoader(self.module_name,
...@@ -120,7 +119,7 @@ class LineEndingTest: ...@@ -120,7 +119,7 @@ class LineEndingTest:
module_name = '_temp' module_name = '_temp'
source_lines = [b"a = 42", b"b = -13", b''] source_lines = [b"a = 42", b"b = -13", b'']
source = line_ending.join(source_lines) 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: with open(mapping[module_name], 'wb') as file:
file.write(source) file.write(source)
loader = self.machinery.SourceFileLoader(module_name, loader = self.machinery.SourceFileLoader(module_name,
......
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)
from contextlib import contextmanager import builtins
from importlib import util, invalidate_caches import contextlib
import errno
import functools
import importlib
from importlib import machinery, util, invalidate_caches
import os
import os.path import os.path
from test import support from test import support
import unittest import unittest
import sys import sys
import tempfile
import types 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): def import_importlib(module_name):
"""Import a module from importlib both w/ and w/o _frozen_importlib.""" """Import a module from importlib both w/ and w/o _frozen_importlib."""
fresh = ('importlib',) if '.' in module_name else () fresh = ('importlib',) if '.' in module_name else ()
...@@ -38,6 +75,9 @@ if sys.platform not in ('win32', 'cygwin'): ...@@ -38,6 +75,9 @@ if sys.platform not in ('win32', 'cygwin'):
if not os.path.exists(changed_name): if not os.path.exists(changed_name):
CASE_INSENSITIVE_FS = False CASE_INSENSITIVE_FS = False
_, source_importlib = import_importlib('importlib')
__import__ = staticmethod(builtins.__import__), staticmethod(source_importlib.__import__)
def case_insensitive_tests(test): def case_insensitive_tests(test):
"""Class decorator that nullifies tests requiring a case-insensitive """Class decorator that nullifies tests requiring a case-insensitive
...@@ -53,7 +93,7 @@ def submodule(parent, name, pkg_dir, content=''): ...@@ -53,7 +93,7 @@ def submodule(parent, name, pkg_dir, content=''):
return '{}.{}'.format(parent, name), path return '{}.{}'.format(parent, name), path
@contextmanager @contextlib.contextmanager
def uncache(*names): def uncache(*names):
"""Uncache a module from sys.modules. """Uncache a module from sys.modules.
...@@ -79,7 +119,7 @@ def uncache(*names): ...@@ -79,7 +119,7 @@ def uncache(*names):
pass pass
@contextmanager @contextlib.contextmanager
def temp_module(name, content='', *, pkg=False): def temp_module(name, content='', *, pkg=False):
conflicts = [n for n in sys.modules if n.partition('.')[0] == name] conflicts = [n for n in sys.modules if n.partition('.')[0] == name]
with support.temp_cwd(None) as cwd: with support.temp_cwd(None) as cwd:
...@@ -103,7 +143,7 @@ def temp_module(name, content='', *, pkg=False): ...@@ -103,7 +143,7 @@ def temp_module(name, content='', *, pkg=False):
yield location yield location
@contextmanager @contextlib.contextmanager
def import_state(**kwargs): def import_state(**kwargs):
"""Context manager to manage the various importers and stored state in the """Context manager to manage the various importers and stored state in the
sys module. sys module.
...@@ -198,6 +238,7 @@ class mock_modules(_ImporterMock): ...@@ -198,6 +238,7 @@ class mock_modules(_ImporterMock):
raise raise
return self.modules[fullname] return self.modules[fullname]
class mock_spec(_ImporterMock): class mock_spec(_ImporterMock):
"""Importer mock using PEP 451 APIs.""" """Importer mock using PEP 451 APIs."""
...@@ -223,3 +264,99 @@ class mock_spec(_ImporterMock): ...@@ -223,3 +264,99 @@ class mock_spec(_ImporterMock):
self.module_code[module.__spec__.name]() self.module_code[module.__spec__.name]()
except KeyError: except KeyError:
pass 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment