diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2013-11-22 09:05:39 -0700 |
---|---|---|
committer | Eric Snow <ericsnowcurrently@gmail.com> | 2013-11-22 09:05:39 -0700 |
commit | b523f8433a8982e10eb41a3e2b37ee0e6d6a6e00 (patch) | |
tree | b38661db4903b7edc4042e7562b32720dd3687bf /Lib/test | |
parent | 9e6097ebe7bb99a4a22b949ef4b1563b21ad7166 (diff) | |
download | cpython-git-b523f8433a8982e10eb41a3e2b37ee0e6d6a6e00.tar.gz |
Implement PEP 451 (ModuleSpec).
Diffstat (limited to 'Lib/test')
22 files changed, 1451 insertions, 455 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 4c2aec3be5..5aa4b0aa84 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -2259,7 +2259,7 @@ order (MRO) for bases """ minstance.b = 2 minstance.a = 1 default_attributes = ['__name__', '__doc__', '__package__', - '__loader__'] + '__loader__', '__spec__'] names = [x for x in dir(minstance) if x not in default_attributes] self.assertEqual(names, ['a', 'b']) diff --git a/Lib/test/test_frozen.py b/Lib/test/test_frozen.py deleted file mode 100644 index 4c50cb7510..0000000000 --- a/Lib/test/test_frozen.py +++ /dev/null @@ -1,77 +0,0 @@ -# Test the frozen module defined in frozen.c. - -from test.support import captured_stdout, run_unittest -import unittest -import sys - -class FrozenTests(unittest.TestCase): - - module_attrs = frozenset(['__builtins__', '__cached__', '__doc__', - '__loader__', '__name__', - '__package__']) - package_attrs = frozenset(list(module_attrs) + ['__path__']) - - def test_frozen(self): - with captured_stdout() as stdout: - try: - import __hello__ - except ImportError as x: - self.fail("import __hello__ failed:" + str(x)) - self.assertEqual(__hello__.initialized, True) - expect = set(self.module_attrs) - expect.add('initialized') - self.assertEqual(set(dir(__hello__)), expect) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - with captured_stdout() as stdout: - try: - import __phello__ - except ImportError as x: - self.fail("import __phello__ failed:" + str(x)) - self.assertEqual(__phello__.initialized, True) - expect = set(self.package_attrs) - expect.add('initialized') - if not "__phello__.spam" in sys.modules: - self.assertEqual(set(dir(__phello__)), expect) - else: - expect.add('spam') - self.assertEqual(set(dir(__phello__)), expect) - self.assertEqual(__phello__.__path__, []) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - with captured_stdout() as stdout: - try: - import __phello__.spam - except ImportError as x: - self.fail("import __phello__.spam failed:" + str(x)) - self.assertEqual(__phello__.spam.initialized, True) - spam_expect = set(self.module_attrs) - spam_expect.add('initialized') - self.assertEqual(set(dir(__phello__.spam)), spam_expect) - phello_expect = set(self.package_attrs) - phello_expect.add('initialized') - phello_expect.add('spam') - self.assertEqual(set(dir(__phello__)), phello_expect) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - try: - import __phello__.foo - except ImportError: - pass - else: - self.fail("import __phello__.foo should have failed") - - try: - import __phello__.foo - except ImportError: - pass - else: - self.fail("import __phello__.foo should have failed") - - del sys.modules['__hello__'] - del sys.modules['__phello__'] - del sys.modules['__phello__.spam'] - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py index ae8e1601fe..bda1541fdb 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -1036,11 +1036,14 @@ class ImportTracebackTests(unittest.TestCase): # away from the traceback. self.create_module("foo", "") importlib = sys.modules['_frozen_importlib'] - old_load_module = importlib.SourceLoader.load_module + if 'load_module' in vars(importlib.SourceLoader): + old_exec_module = importlib.SourceLoader.exec_module + else: + old_exec_module = None try: - def load_module(*args): + def exec_module(*args): 1/0 - importlib.SourceLoader.load_module = load_module + importlib.SourceLoader.exec_module = exec_module try: import foo except ZeroDivisionError as e: @@ -1049,7 +1052,10 @@ class ImportTracebackTests(unittest.TestCase): self.fail("ZeroDivisionError should have been raised") self.assert_traceback(tb, [__file__, '<frozen importlib', __file__]) finally: - importlib.SourceLoader.load_module = old_load_module + if old_exec_module is None: + del importlib.SourceLoader.exec_module + else: + importlib.SourceLoader.exec_module = old_exec_module @unittest.skipUnless(TESTFN_UNENCODABLE, 'need TESTFN_UNENCODABLE') def test_unencodable_filename(self): diff --git a/Lib/test/test_importlib/abc.py b/Lib/test/test_importlib/abc.py index b9ff3448f7..2070dadc23 100644 --- a/Lib/test/test_importlib/abc.py +++ b/Lib/test/test_importlib/abc.py @@ -81,11 +81,6 @@ class LoaderTests(metaclass=abc.ABCMeta): pass @abc.abstractmethod - def test_module_reuse(self): - """If a module is already in sys.modules, it should be reused.""" - pass - - @abc.abstractmethod def test_state_after_failure(self): """If a module is already in sys.modules and a reload fails (e.g. a SyntaxError), the module should be in the state it was before diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py index aa1ea423d0..934562feb6 100644 --- a/Lib/test/test_importlib/builtin/test_finder.py +++ b/Lib/test/test_importlib/builtin/test_finder.py @@ -8,6 +8,46 @@ import sys import unittest +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) + self.assertTrue(found) + self.assertEqual(found.origin, 'built-in') + + # Built-in modules cannot be a package. + test_package = None + + # Built-in modules cannobt be in a package. + test_module_in_package = None + + # Built-in modules cannot be a package. + test_package_in_package = None + + # Built-in modules cannot be a package. + test_package_over_module = None + + def test_failure(self): + name = 'importlib' + assert name not in sys.builtin_module_names + spec = self.machinery.BuiltinImporter.find_spec(name) + self.assertIsNone(spec) + + 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, + ['pkg']) + self.assertIsNone(spec) + +Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests, + machinery=[frozen_machinery, source_machinery]) + + class FinderTests(abc.FinderTests): """Test find_module() for built-in modules.""" @@ -17,22 +57,13 @@ class FinderTests(abc.FinderTests): with util.uncache(builtin_util.NAME): found = self.machinery.BuiltinImporter.find_module(builtin_util.NAME) self.assertTrue(found) + self.assertTrue(hasattr(found, 'load_module')) - def test_package(self): - # Built-in modules cannot be a package. - pass - - def test_module_in_package(self): - # Built-in modules cannobt be in a package. - pass - - def test_package_in_package(self): - # Built-in modules cannot be a package. - pass + # Built-in modules cannot be a package. + test_package = test_package_in_package = test_package_over_module = None - def test_package_over_module(self): - # Built-in modules cannot be a package. - pass + # Built-in modules cannot be in a package. + test_module_in_package = None def test_failure(self): assert 'importlib' not in sys.builtin_module_names diff --git a/Lib/test/test_importlib/builtin/test_loader.py b/Lib/test/test_importlib/builtin/test_loader.py index 4ee8dc488a..200188fc8f 100644 --- a/Lib/test/test_importlib/builtin/test_loader.py +++ b/Lib/test/test_importlib/builtin/test_loader.py @@ -9,6 +9,70 @@ import types import unittest +class ExecModTests(abc.LoaderTests): + + """Test exec_module() for built-in modules.""" + + @classmethod + def setUpClass(cls): + cls.verification = {'__name__': 'errno', '__package__': '', + '__loader__': cls.machinery.BuiltinImporter} + + def verify(self, module): + """Verify that the module matches against what it should have.""" + self.assertIsInstance(module, types.ModuleType) + for attr, value in self.verification.items(): + self.assertEqual(getattr(module, attr), value) + self.assertIn(module.__name__, sys.modules) + self.assertTrue(hasattr(module, '__spec__')) + self.assertEqual(module.__spec__.origin, 'built-in') + + def load_spec(self, name): + spec = self.machinery.ModuleSpec(name, self.machinery.BuiltinImporter, + origin='built-in') + module = types.ModuleType(name) + module.__spec__ = spec + self.machinery.BuiltinImporter.exec_module(module) + # Strictly not what exec_module() is supposed to do, but since + # _imp.init_builtin() does this we can't get around it. + return sys.modules[name] + + def test_module(self): + # Common case. + with util.uncache(builtin_util.NAME): + module = self.load_spec(builtin_util.NAME) + self.verify(module) + self.assertIn('built-in', str(module)) + + # Built-in modules cannot be a package. + test_package = None + + # Built-in modules cannot be a package. + test_lacking_parent = None + + # Not way to force an import failure. + test_state_after_failure = None + + def test_unloadable(self): + name = 'dssdsdfff' + assert name not in sys.builtin_module_names + with self.assertRaises(ImportError) as cm: + self.load_spec(name) + self.assertEqual(cm.exception.name, name) + + def test_already_imported(self): + # Using the name of a module already imported but not a built-in should + # still fail. + assert hasattr(unittest, '__file__') # Not a built-in. + with self.assertRaises(ImportError) as cm: + self.load_spec('unittest') + self.assertEqual(cm.exception.name, 'unittest') + + +Frozen_ExecModTests, Source_ExecModTests = util.test_both(ExecModTests, + machinery=[frozen_machinery, source_machinery]) + + class LoaderTests(abc.LoaderTests): """Test load_module() for built-in modules.""" @@ -33,17 +97,11 @@ class LoaderTests(abc.LoaderTests): module = self.load_module(builtin_util.NAME) self.verify(module) - def test_package(self): - # Built-in modules cannot be a package. - pass - - def test_lacking_parent(self): - # Built-in modules cannot be a package. - pass + # Built-in modules cannot be a package. + test_package = test_lacking_parent = None - def test_state_after_failure(self): - # Not way to force an imoprt failure. - pass + # No way to force an import failure. + test_state_after_failure = None def test_module_reuse(self): # Test that the same module is used in a reload. diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py index bb743212e9..bb2528e626 100644 --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -9,6 +9,8 @@ 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') @util.case_insensitive_tests class ExtensionModuleCaseSensitivityTest: diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py index 10e78cc522..d0c8bb0994 100644 --- a/Lib/test/test_importlib/extension/test_finder.py +++ b/Lib/test/test_importlib/extension/test_finder.py @@ -6,6 +6,7 @@ machinery = test_util.import_importlib('importlib.machinery') import unittest +# XXX find_spec tests class FinderTests(abc.FinderTests): @@ -20,21 +21,14 @@ class FinderTests(abc.FinderTests): def test_module(self): self.assertTrue(self.find_module(util.NAME)) - def test_package(self): - # No extension module as an __init__ available for testing. - pass + # No extension module as an __init__ available for testing. + test_package = test_package_in_package = None - def test_module_in_package(self): - # No extension module in a package available for testing. - pass + # No extension module in a package available for testing. + test_module_in_package = None - def test_package_in_package(self): - # No extension module as an __init__ available for testing. - pass - - def test_package_over_module(self): - # Extension modules cannot be an __init__ for a package. - pass + # Extension modules cannot be an __init__ for a package. + test_package_over_module = None def test_failure(self): self.assertIsNone(self.find_module('asdfjkl;')) diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index 1e8afba702..58bd09fc59 100644 --- a/Lib/test/test_importlib/extension/test_loader.py +++ b/Lib/test/test_importlib/extension/test_loader.py @@ -6,9 +6,75 @@ machinery = util.import_importlib('importlib.machinery') import os.path import sys +import types import unittest +class ExecModuleTests(abc.LoaderTests): + + """Test load_module() for extension modules.""" + + def setUp(self): + self.loader = self.machinery.ExtensionFileLoader(ext_util.NAME, + ext_util.FILEPATH) + + def exec_module(self, fullname): + module = types.ModuleType(fullname) + module.__spec__ = self.machinery.ModuleSpec(fullname, self.loader) + self.loader.exec_module(module) + return sys.modules[fullname] + + def test_exec_module_API(self): + with self.assertRaises(ImportError): + self.exec_module('XXX') + + + def test_module(self): + with util.uncache(ext_util.NAME): + module = self.exec_module(ext_util.NAME) + for attr, value in [('__name__', ext_util.NAME), + ('__file__', ext_util.FILEPATH), + ('__package__', '')]: + given = getattr(module, attr) + self.assertEqual(given, value, + '{}: {!r} != {!r}'.format(attr, given, value)) + self.assertIn(ext_util.NAME, sys.modules) + self.assertIsInstance(module.__loader__, + self.machinery.ExtensionFileLoader) + + # No extension module as __init__ available for testing. + test_package = None + + # No extension module in a package available for testing. + test_lacking_parent = None + + def test_module_reuse(self): + with util.uncache(ext_util.NAME): + module1 = self.exec_module(ext_util.NAME) + module2 = self.exec_module(ext_util.NAME) + self.assertIs(module1, module2) + + def test_state_after_failure(self): + # No easy way to trigger a failure after a successful import. + pass + + def test_unloadable(self): + name = 'asdfjkl;' + with self.assertRaises(ImportError) as cm: + self.exec_module(name) + self.assertEqual(cm.exception.name, name) + + def test_is_package(self): + self.assertFalse(self.loader.is_package(ext_util.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_ExecModuleTests, Source_ExecModuleTests = util.test_both( + ExecModuleTests, machinery=machinery) + + class LoaderTests(abc.LoaderTests): """Test load_module() for extension modules.""" @@ -39,13 +105,11 @@ class LoaderTests(abc.LoaderTests): self.assertIsInstance(module.__loader__, self.machinery.ExtensionFileLoader) - def test_package(self): - # No extension module as __init__ available for testing. - pass + # No extension module as __init__ available for testing. + test_package = None - def test_lacking_parent(self): - # No extension module in a package available for testing. - pass + # No extension module in a package available for testing. + test_lacking_parent = None def test_module_reuse(self): with util.uncache(ext_util.NAME): @@ -53,9 +117,8 @@ class LoaderTests(abc.LoaderTests): module2 = self.load_module(ext_util.NAME) self.assertIs(module1, module2) - def test_state_after_failure(self): - # No easy way to trigger a failure after a successful import. - pass + # No easy way to trigger a failure after a successful import. + test_state_after_failure = None def test_unloadable(self): name = 'asdfjkl;' diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py index 9e629bf9d0..f9f97f3851 100644 --- a/Lib/test/test_importlib/frozen/test_finder.py +++ b/Lib/test/test_importlib/frozen/test_finder.py @@ -6,6 +6,41 @@ machinery = util.import_importlib('importlib.machinery') import unittest +class FindSpecTests(abc.FinderTests): + + """Test finding frozen modules.""" + + def find(self, name, path=None): + finder = self.machinery.FrozenImporter + return finder.find_spec(name, path) + + def test_module(self): + name = '__hello__' + spec = self.find(name) + self.assertEqual(spec.origin, 'frozen') + + def test_package(self): + spec = self.find('__phello__') + self.assertIsNotNone(spec) + + def test_module_in_package(self): + spec = self.find('__phello__.spam', ['__phello__']) + self.assertIsNotNone(spec) + + # No frozen package within another package to test with. + test_package_in_package = None + + # No easy way to test. + test_package_over_module = None + + def test_failure(self): + spec = self.find('<not real>') + self.assertIsNone(spec) + +Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests, + machinery=machinery) + + class FinderTests(abc.FinderTests): """Test finding frozen modules.""" @@ -27,13 +62,11 @@ class FinderTests(abc.FinderTests): loader = self.find('__phello__.spam', ['__phello__']) self.assertTrue(hasattr(loader, 'load_module')) - def test_package_in_package(self): - # No frozen package within another package to test with. - pass + # No frozen package within another package to test with. + test_package_in_package = None - def test_package_over_module(self): - # No easy way to test. - pass + # No easy way to test. + test_package_over_module = None def test_failure(self): loader = self.find('<not real>') diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index be8dc3c07a..2abbe929bc 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -3,9 +3,81 @@ from .. import util machinery = util.import_importlib('importlib.machinery') -import unittest + +import sys from test.support import captured_stdout import types +import unittest + + +class ExecModuleTests(abc.LoaderTests): + + def exec_module(self, name): + with util.uncache(name), captured_stdout() as stdout: + spec = self.machinery.ModuleSpec( + name, self.machinery.FrozenImporter, origin='frozen', + is_package=self.machinery.FrozenImporter.is_package(name)) + module = types.ModuleType(name) + module.__spec__ = spec + assert not hasattr(module, 'initialized') + self.machinery.FrozenImporter.exec_module(module) + self.assertTrue(module.initialized) + self.assertTrue(hasattr(module, '__spec__')) + self.assertEqual(module.__spec__.origin, 'frozen') + return module, stdout.getvalue() + + def test_module(self): + name = '__hello__' + module, output = self.exec_module(name) + check = {'__name__': name} + for attr, value in check.items(): + self.assertEqual(getattr(module, attr), value) + self.assertEqual(output, 'Hello world!\n') + self.assertTrue(hasattr(module, '__spec__')) + + def test_package(self): + name = '__phello__' + module, output = self.exec_module(name) + check = {'__name__': name} + for attr, value in check.items(): + attr_value = getattr(module, attr) + self.assertEqual(attr_value, value, + 'for {name}.{attr}, {given!r} != {expected!r}'.format( + name=name, attr=attr, given=attr_value, + expected=value)) + self.assertEqual(output, 'Hello world!\n') + + def test_lacking_parent(self): + name = '__phello__.spam' + with util.uncache('__phello__'): + module, output = self.exec_module(name) + check = {'__name__': name} + for attr, value in check.items(): + attr_value = getattr(module, attr) + self.assertEqual(attr_value, value, + 'for {name}.{attr}, {given} != {expected!r}'.format( + name=name, attr=attr, given=attr_value, + expected=value)) + self.assertEqual(output, 'Hello world!\n') + + + def test_module_repr(self): + name = '__hello__' + module, output = self.exec_module(name) + self.assertEqual(repr(module), + "<module '__hello__' (frozen)>") + + # No way to trigger an error in a frozen module. + test_state_after_failure = None + + def test_unloadable(self): + assert self.machinery.FrozenImporter.find_module('_not_real') is None + with self.assertRaises(ImportError) as cm: + self.exec_module('_not_real') + self.assertEqual(cm.exception.name, '_not_real') + +Frozen_ExecModuleTests, Source_ExecModuleTests = util.test_both(ExecModuleTests, + machinery=machinery) class LoaderTests(abc.LoaderTests): @@ -68,9 +140,8 @@ class LoaderTests(abc.LoaderTests): self.assertEqual(repr(module), "<module '__hello__' (frozen)>") - def test_state_after_failure(self): - # No way to trigger an error in a frozen module. - pass + # No way to trigger an error in a frozen module. + test_state_after_failure = None def test_unloadable(self): assert self.machinery.FrozenImporter.find_module('_not_real') is None diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py index 74afd1b704..a56253ddde 100644 --- a/Lib/test/test_importlib/import_/test_meta_path.py +++ b/Lib/test/test_importlib/import_/test_meta_path.py @@ -46,8 +46,8 @@ class CallingOrder: with util.import_state(meta_path=[]): with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') - self.assertIsNone(importlib._bootstrap._find_module('nothing', - None)) + self.assertIsNone(importlib._bootstrap._find_spec('nothing', + None)) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, ImportWarning)) diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 979a481b6b..ba8d60542b 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -284,22 +284,6 @@ class ExecutionLoaderDefaultsTests: tests = make_return_value_tests(ExecutionLoader, InspectLoaderDefaultsTests) Frozen_ELDefaultTests, Source_ELDefaultsTests = tests -##### Loader concrete methods ################################################## -class LoaderConcreteMethodTests: - - def test_init_module_attrs(self): - loader = self.LoaderSubclass() - module = types.ModuleType('blah') - loader.init_module_attrs(module) - self.assertEqual(module.__loader__, loader) - - -class Frozen_LoaderConcreateMethodTests(LoaderConcreteMethodTests, unittest.TestCase): - LoaderSubclass = Frozen_L - -class Source_LoaderConcreateMethodTests(LoaderConcreteMethodTests, unittest.TestCase): - LoaderSubclass = Source_L - ##### InspectLoader concrete methods ########################################### class InspectLoaderSourceToCodeTests: @@ -385,60 +369,6 @@ class Source_ILGetCodeTests(InspectLoaderGetCodeTests, unittest.TestCase): InspectLoaderSubclass = Source_IL -class InspectLoaderInitModuleTests: - - def mock_is_package(self, return_value): - return mock.patch.object(self.InspectLoaderSubclass, 'is_package', - return_value=return_value) - - def init_module_attrs(self, name): - loader = self.InspectLoaderSubclass() - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertEqual(module.__loader__, loader) - return module - - def test_package(self): - # If a package, then __package__ == __name__, __path__ == [] - with self.mock_is_package(True): - name = 'blah' - module = self.init_module_attrs(name) - self.assertEqual(module.__package__, name) - self.assertEqual(module.__path__, []) - - def test_toplevel(self): - # If a module is top-level, __package__ == '' - with self.mock_is_package(False): - name = 'blah' - module = self.init_module_attrs(name) - self.assertEqual(module.__package__, '') - - def test_submodule(self): - # If a module is contained within a package then set __package__ to the - # package name. - with self.mock_is_package(False): - name = 'pkg.mod' - module = self.init_module_attrs(name) - self.assertEqual(module.__package__, 'pkg') - - def test_is_package_ImportError(self): - # If is_package() raises ImportError, __package__ should be None and - # __path__ should not be set. - with self.mock_is_package(False) as mocked_method: - mocked_method.side_effect = ImportError - name = 'mod' - module = self.init_module_attrs(name) - self.assertIsNone(module.__package__) - self.assertFalse(hasattr(module, '__path__')) - - -class Frozen_ILInitModuleTests(InspectLoaderInitModuleTests, unittest.TestCase): - InspectLoaderSubclass = Frozen_IL - -class Source_ILInitModuleTests(InspectLoaderInitModuleTests, unittest.TestCase): - InspectLoaderSubclass = Source_IL - - class InspectLoaderLoadModuleTests: """Test InspectLoader.load_module().""" @@ -550,80 +480,6 @@ class Source_ELGetCodeTests(ExecutionLoaderGetCodeTests, unittest.TestCase): ExecutionLoaderSubclass = Source_EL -class ExecutionLoaderInitModuleTests: - - def mock_is_package(self, return_value): - return mock.patch.object(self.ExecutionLoaderSubclass, 'is_package', - return_value=return_value) - - @contextlib.contextmanager - def mock_methods(self, is_package, filename): - is_package_manager = self.mock_is_package(is_package) - get_filename_manager = mock.patch.object(self.ExecutionLoaderSubclass, - 'get_filename', return_value=filename) - with is_package_manager as mock_is_package: - with get_filename_manager as mock_get_filename: - yield {'is_package': mock_is_package, - 'get_filename': mock_get_filename} - - def test_toplevel(self): - # Verify __loader__, __file__, and __package__; no __path__. - name = 'blah' - path = os.path.join('some', 'path', '{}.py'.format(name)) - with self.mock_methods(False, path): - loader = self.ExecutionLoaderSubclass() - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__file__, path) - self.assertEqual(module.__package__, '') - self.assertFalse(hasattr(module, '__path__')) - - def test_package(self): - # Verify __loader__, __file__, __package__, and __path__. - name = 'pkg' - path = os.path.join('some', 'pkg', '__init__.py') - with self.mock_methods(True, path): - loader = self.ExecutionLoaderSubclass() - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__file__, path) - self.assertEqual(module.__package__, 'pkg') - self.assertEqual(module.__path__, [os.path.dirname(path)]) - - def test_submodule(self): - # Verify __package__ and not __path__; test_toplevel() takes care of - # other attributes. - name = 'pkg.submodule' - path = os.path.join('some', 'pkg', 'submodule.py') - with self.mock_methods(False, path): - loader = self.ExecutionLoaderSubclass() - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertEqual(module.__package__, 'pkg') - self.assertEqual(module.__file__, path) - self.assertFalse(hasattr(module, '__path__')) - - def test_get_filename_ImportError(self): - # If get_filename() raises ImportError, don't set __file__. - name = 'blah' - path = 'blah.py' - with self.mock_methods(False, path) as mocked_methods: - mocked_methods['get_filename'].side_effect = ImportError - loader = self.ExecutionLoaderSubclass() - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertFalse(hasattr(module, '__file__')) - - -class Frozen_ELInitModuleTests(ExecutionLoaderInitModuleTests, unittest.TestCase): - ExecutionLoaderSubclass = Frozen_EL - -class Source_ELInitModuleTests(ExecutionLoaderInitModuleTests, unittest.TestCase): - ExecutionLoaderSubclass = Source_EL - - ##### SourceLoader concrete methods ############################################ class SourceLoader: @@ -952,58 +808,5 @@ class Source_SourceOnlyLGetSourceTests(SourceLoaderGetSourceTests, unittest.Test SourceOnlyLoaderMock = Source_SourceOnlyL -class SourceLoaderInitModuleAttrTests: - - """Tests for importlib.abc.SourceLoader.init_module_attrs().""" - - def test_init_module_attrs(self): - # If __file__ set, __cached__ == importlib.util.cached_from_source(__file__). - name = 'blah' - path = 'blah.py' - loader = self.SourceOnlyLoaderMock(path) - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertEqual(module.__loader__, loader) - self.assertEqual(module.__package__, '') - self.assertEqual(module.__file__, path) - self.assertEqual(module.__cached__, self.util.cache_from_source(path)) - - def test_no_get_filename(self): - # No __file__, no __cached__. - with mock.patch.object(self.SourceOnlyLoaderMock, 'get_filename') as mocked: - mocked.side_effect = ImportError - name = 'blah' - loader = self.SourceOnlyLoaderMock('blah.py') - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertFalse(hasattr(module, '__file__')) - self.assertFalse(hasattr(module, '__cached__')) - - -class Frozen_SLInitModuleAttrTests(SourceLoaderInitModuleAttrTests, unittest.TestCase): - SourceOnlyLoaderMock = Frozen_SourceOnlyL - util = frozen_util - - # Difficult to test under source thanks to cross-module mocking needs. - @mock.patch('importlib._bootstrap.cache_from_source') - def test_cache_from_source_NotImplementedError(self, mock_cache_from_source): - # If importlib.util.cache_from_source() raises NotImplementedError don't set - # __cached__. - mock_cache_from_source.side_effect = NotImplementedError - name = 'blah' - path = 'blah.py' - loader = self.SourceOnlyLoaderMock(path) - module = types.ModuleType(name) - loader.init_module_attrs(module) - self.assertEqual(module.__file__, path) - self.assertFalse(hasattr(module, '__cached__')) - - -class Source_SLInitModuleAttrTests(SourceLoaderInitModuleAttrTests, unittest.TestCase): - SourceOnlyLoaderMock = Source_SourceOnlyL - util = source_util - - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 51266345bc..c6c2d47051 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -165,6 +165,96 @@ class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase): init = source_init +class FindSpecTests: + + class FakeMetaFinder: + @staticmethod + def find_spec(name, path=None, target=None): return name, path, target + + def test_sys_modules(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + loader = 'a loader!' + spec = self.machinery.ModuleSpec(name, loader) + module.__loader__ = loader + module.__spec__ = spec + sys.modules[name] = module + found = self.init.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_without___loader__(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + del module.__loader__ + loader = 'a loader!' + spec = self.machinery.ModuleSpec(name, loader) + module.__spec__ = spec + sys.modules[name] = module + found = self.init.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_spec_is_None(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + module.__spec__ = None + sys.modules[name] = module + with self.assertRaises(ValueError): + self.init.find_spec(name) + + def test_sys_modules_loader_is_None(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + spec = self.machinery.ModuleSpec(name, None) + module.__spec__ = spec + sys.modules[name] = module + found = self.init.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_spec_is_not_set(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + try: + del module.__spec__ + except AttributeError: + pass + sys.modules[name] = module + with self.assertRaises(ValueError): + self.init.find_spec(name) + + def test_success(self): + name = 'some_mod' + with util.uncache(name): + with util.import_state(meta_path=[self.FakeMetaFinder]): + self.assertEqual((name, None, None), + self.init.find_spec(name)) + + def test_success_path(self): + # 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]): + self.assertEqual((name, path, None), + self.init.find_spec(name, path)) + + def test_nothing(self): + # None is returned upon failure to find a loader. + self.assertIsNone(self.init.find_spec('nevergoingtofindthismodule')) + +class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase): + init = frozen_init + machinery = frozen_machinery + +class Source_FindSpecTests(FindSpecTests, unittest.TestCase): + init = source_init + machinery = source_machinery + + class ReloadTests: """Test module reloading for builtin and extension modules.""" @@ -219,6 +309,7 @@ class ReloadTests: with support.temp_cwd(None) as cwd: with util.uncache('spam'): with support.DirsOnSysPath(cwd): + # Start as a plain module. self.init.invalidate_caches() path = os.path.join(cwd, name + '.py') cached = self.util.cache_from_source(path) @@ -232,11 +323,14 @@ class ReloadTests: support.create_empty_file(path) module = self.init.import_module(name) ns = vars(module) - del ns['__initializing__'] loader = ns.pop('__loader__') + spec = ns.pop('__spec__') + self.assertEqual(spec.name, name) + self.assertEqual(spec.loader, loader) self.assertEqual(loader.path, path) self.assertEqual(ns, expected) + # Change to a package. self.init.invalidate_caches() init_path = os.path.join(cwd, name, '__init__.py') cached = self.util.cache_from_source(init_path) @@ -252,18 +346,21 @@ class ReloadTests: os.rename(path, init_path) reloaded = self.init.reload(module) ns = vars(reloaded) - del ns['__initializing__'] loader = ns.pop('__loader__') + spec = ns.pop('__spec__') + self.assertEqual(spec.name, name) + self.assertEqual(spec.loader, loader) self.assertIs(reloaded, module) self.assertEqual(loader.path, init_path) + self.maxDiff = None self.assertEqual(ns, expected) def test_reload_namespace_changed(self): - self.maxDiff = None name = 'spam' with support.temp_cwd(None) as cwd: with util.uncache('spam'): with support.DirsOnSysPath(cwd): + # Start as a namespace package. self.init.invalidate_caches() bad_path = os.path.join(cwd, name, '__init.py') cached = self.util.cache_from_source(bad_path) @@ -276,9 +373,12 @@ class ReloadTests: init_file.write('eggs = None') module = self.init.import_module(name) ns = vars(module) - del ns['__initializing__'] loader = ns.pop('__loader__') path = ns.pop('__path__') + spec = ns.pop('__spec__') + self.assertEqual(spec.name, name) + self.assertIs(spec.loader, None) + self.assertIsNot(loader, None) self.assertEqual(set(path), set([os.path.dirname(bad_path)])) with self.assertRaises(AttributeError): @@ -286,6 +386,7 @@ class ReloadTests: loader.path self.assertEqual(ns, expected) + # Change to a regular package. self.init.invalidate_caches() init_path = os.path.join(cwd, name, '__init__.py') cached = self.util.cache_from_source(init_path) @@ -301,8 +402,10 @@ class ReloadTests: os.rename(bad_path, init_path) reloaded = self.init.reload(module) ns = vars(reloaded) - del ns['__initializing__'] loader = ns.pop('__loader__') + spec = ns.pop('__spec__') + self.assertEqual(spec.name, name) + self.assertEqual(spec.loader, loader) self.assertIs(reloaded, module) self.assertEqual(loader.path, init_path) self.assertEqual(ns, expected) @@ -371,12 +474,23 @@ class StartupTests: # Issue #17098: all modules should have __loader__ defined. for name, module in sys.modules.items(): if isinstance(module, types.ModuleType): - self.assertTrue(hasattr(module, '__loader__'), - '{!r} lacks a __loader__ attribute'.format(name)) - if self.machinery.BuiltinImporter.find_module(name): - self.assertIsNot(module.__loader__, None) - elif self.machinery.FrozenImporter.find_module(name): - self.assertIsNot(module.__loader__, None) + with self.subTest(name=name): + self.assertTrue(hasattr(module, '__loader__'), + '{!r} lacks a __loader__ attribute'.format(name)) + if self.machinery.BuiltinImporter.find_module(name): + self.assertIsNot(module.__loader__, None) + elif self.machinery.FrozenImporter.find_module(name): + self.assertIsNot(module.__loader__, None) + + def test_everyone_has___spec__(self): + for name, module in sys.modules.items(): + if isinstance(module, types.ModuleType): + with self.subTest(name=name): + self.assertTrue(hasattr(module, '__spec__')) + if self.machinery.BuiltinImporter.find_module(name): + self.assertIsNot(module.__spec__, None) + elif self.machinery.FrozenImporter.find_module(name): + self.assertIsNot(module.__spec__, None) class Frozen_StartupTests(StartupTests, unittest.TestCase): machinery = frozen_machinery diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py new file mode 100644 index 0000000000..e4ef39fd29 --- /dev/null +++ b/Lib/test/test_importlib/test_spec.py @@ -0,0 +1,968 @@ +from . import 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') + +import os.path +from test.support import CleanImport +import unittest +import sys + + + +class TestLoader: + + def __init__(self, path=None, is_package=None): +# if path: +# if is_package: +# if not path.endswith('.py'): +# path = os.path.join(path, '__init__.py') +# elif is_package is None: +# is_package = path.endswith('__init__.py') + + self.path = path + self.package = is_package + + def __repr__(self): + return '<TestLoader object>' + + def __getattr__(self, name): + if name == 'get_filename' and self.path is not None: + return self._get_filename + if name == 'is_package': + return self._is_package + raise AttributeError(name) + + def _get_filename(self, name): + return self.path + + def _is_package(self, name): + return self.package + + +class NewLoader(TestLoader): + + EGGS = 1 + + def exec_module(self, module): + module.eggs = self.EGGS + + +class LegacyLoader(TestLoader): + + HAM = -1 + + @frozen_util.module_for_loader + def load_module(self, module): + module.ham = self.HAM + return module + + +class ModuleSpecTests: + + def setUp(self): + self.name = 'spam' + self.path = 'spam.py' + self.cached = self.util.cache_from_source(self.path) + self.loader = TestLoader() + self.spec = self.machinery.ModuleSpec(self.name, self.loader) + self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader, + origin=self.path) + self.loc_spec._set_fileattr = True + + def test_default(self): + spec = self.machinery.ModuleSpec(self.name, self.loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_default_no_loader(self): + spec = self.machinery.ModuleSpec(self.name, None) + + self.assertEqual(spec.name, self.name) + self.assertIs(spec.loader, None) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_default_is_package_false(self): + spec = self.machinery.ModuleSpec(self.name, self.loader, + is_package=False) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_default_is_package_true(self): + spec = self.machinery.ModuleSpec(self.name, self.loader, + is_package=True) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, []) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_equality(self): + other = type(sys.implementation)(name=self.name, + loader=self.loader, + origin=None, + submodule_search_locations=None, + has_location=False, + cached=None, + ) + + self.assertTrue(self.spec == other) + + def test_equality_location(self): + other = type(sys.implementation)(name=self.name, + loader=self.loader, + origin=self.path, + submodule_search_locations=None, + has_location=True, + cached=self.cached, + ) + + self.assertEqual(self.loc_spec, other) + + def test_inequality(self): + other = type(sys.implementation)(name='ham', + loader=self.loader, + origin=None, + submodule_search_locations=None, + has_location=False, + cached=None, + ) + + self.assertNotEqual(self.spec, other) + + def test_inequality_incomplete(self): + other = type(sys.implementation)(name=self.name, + loader=self.loader, + ) + + self.assertNotEqual(self.spec, other) + + def test_package(self): + spec = self.machinery.ModuleSpec('spam.eggs', self.loader) + + self.assertEqual(spec.parent, 'spam') + + def test_package_is_package(self): + spec = self.machinery.ModuleSpec('spam.eggs', self.loader, + is_package=True) + + self.assertEqual(spec.parent, 'spam.eggs') + + # cached + + def test_cached_set(self): + before = self.spec.cached + self.spec.cached = 'there' + after = self.spec.cached + + self.assertIs(before, None) + self.assertEqual(after, 'there') + + def test_cached_no_origin(self): + spec = self.machinery.ModuleSpec(self.name, self.loader) + + self.assertIs(spec.cached, None) + + def test_cached_with_origin_not_location(self): + spec = self.machinery.ModuleSpec(self.name, self.loader, + origin=self.path) + + self.assertIs(spec.cached, None) + + def test_cached_source(self): + expected = self.util.cache_from_source(self.path) + + self.assertEqual(self.loc_spec.cached, expected) + + def test_cached_source_unknown_suffix(self): + self.loc_spec.origin = 'spam.spamspamspam' + + self.assertIs(self.loc_spec.cached, None) + + def test_cached_source_missing_cache_tag(self): + original = sys.implementation.cache_tag + sys.implementation.cache_tag = None + try: + cached = self.loc_spec.cached + finally: + sys.implementation.cache_tag = original + + self.assertIs(cached, None) + + def test_cached_sourceless(self): + self.loc_spec.origin = 'spam.pyc' + + 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 + + +class ModuleSpecMethodsTests: + + def setUp(self): + self.name = 'spam' + self.path = 'spam.py' + self.cached = self.util.cache_from_source(self.path) + self.loader = TestLoader() + self.spec = self.machinery.ModuleSpec(self.name, self.loader) + self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader, + 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() + sys.modules[self.name] = module + self.assertFalse(hasattr(module, 'eggs')) + self.bootstrap._SpecMethods(self.spec).exec(module) + + self.assertEqual(module.eggs, 1) + + # load() + + def test_load(self): + self.spec.loader = NewLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + installed = sys.modules[self.spec.name] + + self.assertEqual(loaded.eggs, 1) + self.assertIs(loaded, installed) + + def test_load_replaced(self): + replacement = object() + class ReplacingLoader(TestLoader): + def exec_module(self, module): + sys.modules[module.__name__] = replacement + self.spec.loader = ReplacingLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + installed = sys.modules[self.spec.name] + + self.assertIs(loaded, replacement) + self.assertIs(installed, replacement) + + def test_load_failed(self): + class FailedLoader(TestLoader): + def exec_module(self, module): + raise RuntimeError + self.spec.loader = FailedLoader() + with CleanImport(self.spec.name): + with self.assertRaises(RuntimeError): + loaded = self.bootstrap._SpecMethods(self.spec).load() + self.assertNotIn(self.spec.name, sys.modules) + + def test_load_failed_removed(self): + class FailedLoader(TestLoader): + def exec_module(self, module): + del sys.modules[module.__name__] + raise RuntimeError + self.spec.loader = FailedLoader() + with CleanImport(self.spec.name): + with self.assertRaises(RuntimeError): + loaded = self.bootstrap._SpecMethods(self.spec).load() + self.assertNotIn(self.spec.name, sys.modules) + + def test_load_existing(self): + existing = type(sys)('ham') + existing.count = 5 + self.spec.loader = NewLoader() + with CleanImport(self.name): + sys.modules[self.name] = existing + assert self.spec.name == self.name + loaded = self.bootstrap._SpecMethods(self.spec).load() + + self.assertEqual(loaded.eggs, 1) + self.assertFalse(hasattr(loaded, 'ham')) + + def test_load_legacy(self): + self.spec.loader = LegacyLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + + 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() + + self.assertIs(loaded.__loader__, self.spec.loader) + self.assertEqual(loaded.__package__, self.spec.parent) + self.assertIs(loaded.__spec__, self.spec) + + def test_load_legacy_attributes_immutable(self): + module = object() + class ImmutableLoader(TestLoader): + def load_module(self, name): + sys.modules[name] = module + return module + self.spec.loader = ImmutableLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + + self.assertIs(sys.modules[self.spec.name], module) + + # reload() + + 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) + installed = sys.modules[self.spec.name] + + self.assertEqual(loaded.eggs, 1) + self.assertIs(reloaded, loaded) + self.assertIs(installed, loaded) + + def test_reload_modified(self): + self.spec.loader = NewLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded.eggs = 2 + reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + + self.assertEqual(loaded.eggs, 1) + self.assertIs(reloaded, loaded) + + def test_reload_extra_attributes(self): + self.spec.loader = NewLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded.available = False + reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + + self.assertFalse(loaded.available) + self.assertIs(reloaded, loaded) + + def test_reload_init_module_attrs(self): + self.spec.loader = NewLoader() + with CleanImport(self.spec.name): + loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded.__name__ = 'ham' + del loaded.__loader__ + del loaded.__package__ + del loaded.__spec__ + self.bootstrap._SpecMethods(self.spec).exec(loaded) + + self.assertEqual(loaded.__name__, self.spec.name) + self.assertIs(loaded.__loader__, self.spec.loader) + self.assertEqual(loaded.__package__, self.spec.parent) + self.assertIs(loaded.__spec__, self.spec) + self.assertFalse(hasattr(loaded, '__path__')) + self.assertFalse(hasattr(loaded, '__file__')) + self.assertFalse(hasattr(loaded, '__cached__')) + + 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) + installed = sys.modules[self.spec.name] + + self.assertEqual(loaded.ham, -1) + self.assertIs(reloaded, loaded) + 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 + + +class ModuleReprTests: + + # XXX Add more tests for repr(module) once ModuleSpec._module_repr() + # is in place? + + def setUp(self): + self.module = type(os)('spam') + self.spec = self.machinery.ModuleSpec('spam', TestLoader()) + + def test_module___loader___module_repr(self): + class Loader: + def module_repr(self, module): + return '<delicious {}>'.format(module.__name__) + self.module.__loader__ = Loader() + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, '<delicious spam>') + + def test_module___loader___module_repr_bad(self): + class Loader(TestLoader): + def module_repr(self, module): + raise Exception + self.module.__loader__ = Loader() + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, + '<module {!r} (<TestLoader object>)>'.format('spam')) + + def test_module___spec__(self): + origin = 'in a hole, in the ground' + self.spec.origin = origin + self.module.__spec__ = self.spec + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, '<module {!r} ({})>'.format('spam', origin)) + + def test_module___spec___location(self): + location = 'in_a_galaxy_far_far_away.py' + self.spec.origin = location + self.spec._set_fileattr = True + self.module.__spec__ = self.spec + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, + '<module {!r} from {!r}>'.format('spam', location)) + + def test_module___spec___no_origin(self): + self.spec.loader = TestLoader() + self.module.__spec__ = self.spec + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, + '<module {!r} (<TestLoader object>)>'.format('spam')) + + def test_module___spec___no_origin_no_loader(self): + self.spec.loader = None + self.module.__spec__ = self.spec + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, '<module {!r}>'.format('spam')) + + def test_module_no_name(self): + del self.module.__name__ + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, '<module {!r}>'.format('?')) + + def test_module_with_file(self): + filename = 'e/i/e/i/o/spam.py' + self.module.__file__ = filename + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, + '<module {!r} from {!r}>'.format('spam', filename)) + + def test_module_no_file(self): + self.module.__loader__ = TestLoader() + modrepr = self.bootstrap._module_repr(self.module) + + self.assertEqual(modrepr, + '<module {!r} (<TestLoader object>)>'.format('spam')) + + def test_module_no_file_no_loader(self): + modrepr = self.bootstrap._module_repr(self.module) + + 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 + + +class FactoryTests: + + def setUp(self): + self.name = 'spam' + self.path = 'spam.py' + self.cached = self.util.cache_from_source(self.path) + self.loader = TestLoader() + self.fileloader = TestLoader(self.path) + self.pkgloader = TestLoader(self.path, True) + + # spec_from_loader() + + def test_spec_from_loader_default(self): + spec = self.util.spec_from_loader(self.name, self.loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_default_with_bad_is_package(self): + class Loader: + def is_package(self, name): + raise ImportError + loader = Loader() + spec = self.util.spec_from_loader(self.name, loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_origin(self): + origin = 'somewhere over the rainbow' + spec = self.util.spec_from_loader(self.name, self.loader, + origin=origin) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, origin) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_is_package_false(self): + spec = self.util.spec_from_loader(self.name, self.loader, + is_package=False) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_is_package_true(self): + spec = self.util.spec_from_loader(self.name, self.loader, + is_package=True) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, []) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_origin_and_is_package(self): + origin = 'where the streets have no name' + spec = self.util.spec_from_loader(self.name, self.loader, + origin=origin, is_package=True) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertIs(spec.origin, origin) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, []) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_is_package_with_loader_false(self): + loader = TestLoader(is_package=False) + spec = self.util.spec_from_loader(self.name, loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_is_package_with_loader_true(self): + loader = TestLoader(is_package=True) + spec = self.util.spec_from_loader(self.name, loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertIs(spec.origin, None) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, []) + self.assertIs(spec.cached, None) + self.assertFalse(spec.has_location) + + def test_spec_from_loader_default_with_file_loader(self): + spec = self.util.spec_from_loader(self.name, self.fileloader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_loader_is_package_false_with_fileloader(self): + spec = self.util.spec_from_loader(self.name, self.fileloader, + is_package=False) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_loader_is_package_true_with_fileloader(self): + spec = self.util.spec_from_loader(self.name, self.fileloader, + is_package=True) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, ['']) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + # 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) + self.assertIsInstance(spec.loader, + self.machinery.SourceFileLoader) + self.assertEqual(spec.loader.name, self.name) + self.assertEqual(spec.loader.path, self.path) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_default_without_location(self): + spec = self.util.spec_from_file_location(self.name) + + self.assertIs(spec, None) + + def test_spec_from_file_location_default_bad_suffix(self): + spec = self.util.spec_from_file_location(self.name, 'spam.eggs') + + self.assertIs(spec, None) + + def test_spec_from_file_location_loader_no_location(self): + spec = self.util.spec_from_file_location(self.name, + loader=self.fileloader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_loader_no_location_no_get_filename(self): + spec = self.util.spec_from_file_location(self.name, + loader=self.loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.loader) + self.assertEqual(spec.origin, '<unknown>') + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_loader_no_location_bad_get_filename(self): + class Loader: + def get_filename(self, name): + raise ImportError + loader = Loader() + spec = self.util.spec_from_file_location(self.name, loader=loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertEqual(spec.origin, '<unknown>') + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertIs(spec.cached, None) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_none(self): + spec = self.util.spec_from_file_location(self.name, self.path, + loader=self.fileloader, + submodule_search_locations=None) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_empty(self): + spec = self.util.spec_from_file_location(self.name, self.path, + loader=self.fileloader, + submodule_search_locations=[]) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, ['']) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_not_empty(self): + spec = self.util.spec_from_file_location(self.name, self.path, + loader=self.fileloader, + submodule_search_locations=['eggs']) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, ['eggs']) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_default(self): + spec = self.util.spec_from_file_location(self.name, self.path, + loader=self.pkgloader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.pkgloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertEqual(spec.submodule_search_locations, ['']) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_default_not_package(self): + class Loader: + def is_package(self, name): + return False + loader = Loader() + spec = self.util.spec_from_file_location(self.name, self.path, + loader=loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_default_no_is_package(self): + spec = self.util.spec_from_file_location(self.name, self.path, + loader=self.fileloader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, self.fileloader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + def test_spec_from_file_location_smsl_default_bad_is_package(self): + class Loader: + def is_package(self, name): + raise ImportError + loader = Loader() + spec = self.util.spec_from_file_location(self.name, self.path, + loader=loader) + + self.assertEqual(spec.name, self.name) + self.assertEqual(spec.loader, loader) + self.assertEqual(spec.origin, self.path) + self.assertIs(spec.loader_state, None) + self.assertIs(spec.submodule_search_locations, None) + self.assertEqual(spec.cached, self.cached) + self.assertTrue(spec.has_location) + + +class Frozen_FactoryTests(FactoryTests, unittest.TestCase): + util = frozen_util + machinery = frozen_machinery + + +class Source_FactoryTests(FactoryTests, unittest.TestCase): + util = source_util + machinery = source_machinery diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 2ac57df3ac..604e44d1b3 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -34,71 +34,6 @@ Frozen_DecodeSourceBytesTests, Source_DecodeSourceBytesTests = test_util.test_bo DecodeSourceBytesTests, util=[frozen_util, source_util]) -class ModuleToLoadTests: - - module_name = 'ModuleManagerTest_module' - - def setUp(self): - support.unload(self.module_name) - self.addCleanup(support.unload, self.module_name) - - def test_new_module(self): - # Test a new module is created, inserted into sys.modules, has - # __initializing__ set to True after entering the context manager, - # and __initializing__ set to False after exiting. - with self.util.module_to_load(self.module_name) as module: - self.assertIn(self.module_name, sys.modules) - self.assertIs(sys.modules[self.module_name], module) - self.assertTrue(module.__initializing__) - self.assertFalse(module.__initializing__) - - def test_new_module_failed(self): - # Test the module is removed from sys.modules. - try: - with self.util.module_to_load(self.module_name) as module: - self.assertIn(self.module_name, sys.modules) - raise exception - except Exception: - self.assertNotIn(self.module_name, sys.modules) - else: - self.fail('importlib.util.module_to_load swallowed an exception') - - def test_reload(self): - # Test that the same module is in sys.modules. - created_module = types.ModuleType(self.module_name) - sys.modules[self.module_name] = created_module - with self.util.module_to_load(self.module_name) as module: - self.assertIs(module, created_module) - - def test_reload_failed(self): - # Test that the module was left in sys.modules. - created_module = types.ModuleType(self.module_name) - sys.modules[self.module_name] = created_module - try: - with self.util.module_to_load(self.module_name) as module: - raise Exception - except Exception: - self.assertIn(self.module_name, sys.modules) - else: - self.fail('importlib.util.module_to_load swallowed an exception') - - def test_reset_name(self): - # If reset_name is true then module.__name__ = name, else leave it be. - odd_name = 'not your typical name' - created_module = types.ModuleType(self.module_name) - created_module.__name__ = odd_name - sys.modules[self.module_name] = created_module - with self.util.module_to_load(self.module_name) as module: - self.assertEqual(module.__name__, self.module_name) - created_module.__name__ = odd_name - with self.util.module_to_load(self.module_name, reset_name=False) as module: - self.assertEqual(module.__name__, odd_name) - -Frozen_ModuleToLoadTests, Source_ModuleToLoadTests = test_util.test_both( - ModuleToLoadTests, - util=[frozen_util, source_util]) - - class ModuleForLoaderTests: """Tests for importlib.util.module_for_loader.""" diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 5a9b503485..536f7cf632 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -37,8 +37,10 @@ class ModuleTests(unittest.TestCase): self.assertEqual(foo.__doc__, None) self.assertIs(foo.__loader__, None) self.assertIs(foo.__package__, None) + self.assertIs(foo.__spec__, None) self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": None, - "__loader__": None, "__package__": None}) + "__loader__": None, "__package__": None, + "__spec__": None}) def test_ascii_docstring(self): # ASCII docstring @@ -47,7 +49,8 @@ class ModuleTests(unittest.TestCase): self.assertEqual(foo.__doc__, "foodoc") self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc", - "__loader__": None, "__package__": None}) + "__loader__": None, "__package__": None, + "__spec__": None}) def test_unicode_docstring(self): # Unicode docstring @@ -56,7 +59,8 @@ class ModuleTests(unittest.TestCase): self.assertEqual(foo.__doc__, "foodoc\u1234") self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc\u1234", - "__loader__": None, "__package__": None}) + "__loader__": None, "__package__": None, + "__spec__": None}) def test_reinit(self): # Reinitialization should not replace the __dict__ @@ -69,7 +73,7 @@ class ModuleTests(unittest.TestCase): self.assertEqual(foo.bar, 42) self.assertEqual(foo.__dict__, {"__name__": "foo", "__doc__": "foodoc", "bar": 42, - "__loader__": None, "__package__": None}) + "__loader__": None, "__package__": None, "__spec__": None}) self.assertTrue(foo.__dict__ is d) def test_dont_clear_dict(self): diff --git a/Lib/test/test_namespace_pkgs.py b/Lib/test/test_namespace_pkgs.py index 4570bee568..6639612631 100644 --- a/Lib/test/test_namespace_pkgs.py +++ b/Lib/test/test_namespace_pkgs.py @@ -1,5 +1,4 @@ import contextlib -from importlib._bootstrap import NamespaceLoader import importlib.abc import importlib.machinery import os @@ -290,24 +289,5 @@ class ModuleAndNamespacePackageInSameDir(NamespacePackageTest): self.assertEqual(a_test.attr, 'in module') -class ABCTests(unittest.TestCase): - - def setUp(self): - self.loader = NamespaceLoader('foo', ['pkg'], - importlib.machinery.PathFinder) - - def test_is_package(self): - self.assertTrue(self.loader.is_package('foo')) - - def test_get_code(self): - self.assertTrue(isinstance(self.loader.get_code('foo'), types.CodeType)) - - def test_get_source(self): - self.assertEqual(self.loader.get_source('foo'), '') - - def test_abc_isinstance(self): - self.assertTrue(isinstance(self.loader, importlib.abc.InspectLoader)) - - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pkg.py b/Lib/test/test_pkg.py index 355efe7566..9883000945 100644 --- a/Lib/test/test_pkg.py +++ b/Lib/test/test_pkg.py @@ -199,14 +199,14 @@ class TestPkg(unittest.TestCase): import t5 self.assertEqual(fixdir(dir(t5)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', '__path__', 'foo', - 'string', 't5']) + '__name__', '__package__', '__path__', '__spec__', + 'foo', 'string', 't5']) self.assertEqual(fixdir(dir(t5.foo)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', 'string']) + '__name__', '__package__', '__spec__', 'string']) self.assertEqual(fixdir(dir(t5.string)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', 'spam']) + '__name__', '__package__', '__spec__', 'spam']) def test_6(self): hier = [ @@ -222,14 +222,15 @@ class TestPkg(unittest.TestCase): import t6 self.assertEqual(fixdir(dir(t6)), ['__all__', '__cached__', '__doc__', '__file__', - '__loader__', '__name__', '__package__', '__path__']) + '__loader__', '__name__', '__package__', '__path__', + '__spec__']) s = """ import t6 from t6 import * self.assertEqual(fixdir(dir(t6)), ['__all__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', - '__path__', 'eggs', 'ham', 'spam']) + '__path__', '__spec__', 'eggs', 'ham', 'spam']) self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6']) """ self.run_code(s) @@ -256,18 +257,19 @@ class TestPkg(unittest.TestCase): import t7 as tas self.assertEqual(fixdir(dir(tas)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', '__path__']) + '__name__', '__package__', '__path__', '__spec__']) self.assertFalse(t7) from t7 import sub as subpar self.assertEqual(fixdir(dir(subpar)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', '__path__']) + '__name__', '__package__', '__path__', '__spec__']) self.assertFalse(t7) self.assertFalse(sub) from t7.sub import subsub as subsubsub self.assertEqual(fixdir(dir(subsubsub)), ['__cached__', '__doc__', '__file__', '__loader__', - '__name__', '__package__', '__path__', 'spam']) + '__name__', '__package__', '__path__', '__spec__', + 'spam']) self.assertFalse(t7) self.assertFalse(sub) self.assertFalse(subsub) diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index 1f488534d7..52dd0bc73c 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -208,9 +208,16 @@ class ExtendPathTests(unittest.TestCase): importers = list(iter_importers(fullname)) expected_importer = get_importer(pathitem) for finder in importers: + loader = finder.find_module(fullname) + try: + loader = loader.loader + except AttributeError: + # For now we still allow raw loaders from + # find_module(). + pass self.assertIsInstance(finder, importlib.machinery.FileFinder) self.assertEqual(finder, expected_importer) - self.assertIsInstance(finder.find_module(fullname), + self.assertIsInstance(loader, importlib.machinery.SourceFileLoader) self.assertIsNone(finder.find_module(pkgname)) @@ -222,8 +229,11 @@ class ExtendPathTests(unittest.TestCase): finally: shutil.rmtree(dirname) del sys.path[0] - del sys.modules['spam'] - del sys.modules['spam.eggs'] + try: + del sys.modules['spam'] + del sys.modules['spam.eggs'] + except KeyError: + pass def test_mixed_namespace(self): diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index 104e3b5705..a504bde4e4 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -253,6 +253,7 @@ class LongReprTest(unittest.TestCase): print("cached_path_len =", cached_path_len) def test_module(self): + self.maxDiff = None self._check_path_limitations(self.pkgname) create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py')) importlib.invalidate_caches() diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 16e2e12090..f19c4ab7eb 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -47,6 +47,7 @@ implicit_namespace = { "__cached__": None, "__package__": None, "__doc__": None, +# "__spec__": None, # XXX Uncomment. } example_namespace = { "sys": sys, @@ -56,7 +57,7 @@ example_namespace = { "run_name_in_sys_modules": False, "module_in_sys_modules": False, "nested": dict(implicit_namespace, - x=1, __name__="<run>", __loader__=None), + x=1, __name__="<run>", __loader__=None, __spec__=None), } example_namespace.update(implicit_namespace) @@ -243,6 +244,7 @@ class RunModuleTestCase(unittest.TestCase, CodeExecutionMixin): "__name__": mod_name, "__file__": mod_fname, "__package__": mod_name.rpartition(".")[0], +# "__spec__": None, # XXX Needs to be set. }) if alter_sys: expected_ns.update({ @@ -279,6 +281,7 @@ class RunModuleTestCase(unittest.TestCase, CodeExecutionMixin): "__name__": mod_name, "__file__": mod_fname, "__package__": pkg_name, +# "__spec__": None, # XXX Needs to be set. }) if alter_sys: expected_ns.update({ |