diff options
Diffstat (limited to 'Lib/importlib/test/source')
| -rw-r--r-- | Lib/importlib/test/source/test_abc_loader.py | 28 | ||||
| -rw-r--r-- | Lib/importlib/test/source/test_case_sensitivity.py | 18 | ||||
| -rw-r--r-- | Lib/importlib/test/source/test_file_loader.py | 117 | ||||
| -rw-r--r-- | Lib/importlib/test/source/test_finder.py | 27 | ||||
| -rw-r--r-- | Lib/importlib/test/source/test_path_hook.py | 12 | ||||
| -rw-r--r-- | Lib/importlib/test/source/test_source_encoding.py | 8 |
6 files changed, 155 insertions, 55 deletions
diff --git a/Lib/importlib/test/source/test_abc_loader.py b/Lib/importlib/test/source/test_abc_loader.py index 3245907..b1b1204 100644 --- a/Lib/importlib/test/source/test_abc_loader.py +++ b/Lib/importlib/test/source/test_abc_loader.py @@ -40,8 +40,10 @@ class SourceLoaderMock(SourceOnlyLoaderMock): def __init__(self, path, magic=imp.get_magic()): super().__init__(path) self.bytecode_path = imp.cache_from_source(self.path) + self.source_size = len(self.source) data = bytearray(magic) - data.extend(marshal._w_long(self.source_mtime)) + data.extend(importlib._w_long(self.source_mtime)) + data.extend(importlib._w_long(self.source_size)) code_object = compile(self.source, self.path, 'exec', dont_inherit=True) data.extend(marshal.dumps(code_object)) @@ -56,9 +58,9 @@ class SourceLoaderMock(SourceOnlyLoaderMock): else: raise IOError - def path_mtime(self, path): + def path_stats(self, path): assert path == self.path - return self.source_mtime + return {'mtime': self.source_mtime, 'size': self.source_size} def set_data(self, path, data): self.written[path] = bytes(data) @@ -102,7 +104,7 @@ class PyLoaderMock(abc.PyLoader): warnings.simplefilter("always") path = super().get_filename(name) assert len(w) == 1 - assert issubclass(w[0].category, PendingDeprecationWarning) + assert issubclass(w[0].category, DeprecationWarning) return path @@ -198,7 +200,7 @@ class PyPycLoaderMock(abc.PyPycLoader, PyLoaderMock): warnings.simplefilter("always") code_object = super().get_code(name) assert len(w) == 1 - assert issubclass(w[0].category, PendingDeprecationWarning) + assert issubclass(w[0].category, DeprecationWarning) return code_object class PyLoaderTests(testing_abc.LoaderTests): @@ -469,8 +471,9 @@ class BadBytecodeFailureTests(unittest.TestCase): {'path': os.path.join('path', 'to', 'mod'), 'magic': bad_magic}} mock = PyPycLoaderMock({name: None}, bc) - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) + self.assertEqual(cm.exception.name, name) def test_no_bytecode(self): # Missing code object bytecode should lead to an EOFError. @@ -514,8 +517,9 @@ class MissingPathsTests(unittest.TestCase): # If all *_path methods return None, raise ImportError. name = 'mod' mock = PyPycLoaderMock({name: None}) - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) + self.assertEqual(cm.exception.name, name) def test_source_path_ImportError(self): # An ImportError from source_path should trigger an ImportError. @@ -531,7 +535,7 @@ class MissingPathsTests(unittest.TestCase): mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) bad_meth = types.MethodType(raise_ImportError, mock) mock.bytecode_path = bad_meth - with util.uncache(name), self.assertRaises(ImportError): + with util.uncache(name), self.assertRaises(ImportError) as cm: mock.load_module(name) @@ -592,8 +596,9 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness): def raise_IOError(path): raise IOError self.loader.get_data = raise_IOError - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.loader.get_source(self.name) + self.assertEqual(cm.exception.name, self.name) def test_is_package(self): # Properly detect when loading a package. @@ -656,7 +661,8 @@ class SourceLoaderBytecodeTests(SourceLoaderTestHarness): if bytecode_written: self.assertIn(self.cached, self.loader.written) data = bytearray(imp.get_magic()) - data.extend(marshal._w_long(self.loader.source_mtime)) + data.extend(importlib._w_long(self.loader.source_mtime)) + data.extend(importlib._w_long(self.loader.source_size)) data.extend(marshal.dumps(code_object)) self.assertEqual(self.loader.written[self.cached], bytes(data)) @@ -847,7 +853,7 @@ class AbstractMethodImplTests(unittest.TestCase): # Required abstractmethods. self.raises_NotImplementedError(ins, 'get_filename', 'get_data') # Optional abstractmethods. - self.raises_NotImplementedError(ins,'path_mtime', 'set_data') + self.raises_NotImplementedError(ins,'path_stats', 'set_data') def test_PyLoader(self): self.raises_NotImplementedError(self.PyLoader(), 'source_path', diff --git a/Lib/importlib/test/source/test_case_sensitivity.py b/Lib/importlib/test/source/test_case_sensitivity.py index 73777de..21a4378 100644 --- a/Lib/importlib/test/source/test_case_sensitivity.py +++ b/Lib/importlib/test/source/test_case_sensitivity.py @@ -1,7 +1,9 @@ """Test case-sensitivity (PEP 235).""" from importlib import _bootstrap +from importlib import machinery from .. import util from . import util as source_util +import imp import os import sys from test import support as test_support @@ -19,9 +21,13 @@ class CaseSensitivityTest(unittest.TestCase): assert name != name.lower() def find(self, path): - finder = _bootstrap._FileFinder(path, - _bootstrap._SourceFinderDetails(), - _bootstrap._SourcelessFinderDetails()) + finder = machinery.FileFinder(path, + (machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES, + True), + (machinery.SourcelessFileLoader, + machinery.BYTECODE_SUFFIXES, + True)) return finder.find_module(self.name) def sensitivity_test(self): @@ -37,6 +43,9 @@ class CaseSensitivityTest(unittest.TestCase): def test_sensitive(self): with test_support.EnvironmentVarGuard() as env: env.unset('PYTHONCASEOK') + if b'PYTHONCASEOK' in _bootstrap._os.environ: + self.skipTest('os.environ changes not reflected in ' + '_os.environ') sensitive, insensitive = self.sensitivity_test() self.assertTrue(hasattr(sensitive, 'load_module')) self.assertIn(self.name, sensitive.get_filename(self.name)) @@ -45,6 +54,9 @@ class CaseSensitivityTest(unittest.TestCase): def test_insensitive(self): with test_support.EnvironmentVarGuard() as env: env.set('PYTHONCASEOK', '1') + if b'PYTHONCASEOK' not in _bootstrap._os.environ: + self.skipTest('os.environ changes not reflected in ' + '_os.environ') sensitive, insensitive = self.sensitivity_test() self.assertTrue(hasattr(sensitive, 'load_module')) self.assertIn(self.name, sensitive.get_filename(self.name)) diff --git a/Lib/importlib/test/source/test_file_loader.py b/Lib/importlib/test/source/test_file_loader.py index c7a7d8f..ffa0c24 100644 --- a/Lib/importlib/test/source/test_file_loader.py +++ b/Lib/importlib/test/source/test_file_loader.py @@ -1,5 +1,6 @@ +from ... import _bootstrap import importlib -from importlib import _bootstrap +import importlib.abc from .. import abc from .. import util from . import util as source_util @@ -24,10 +25,44 @@ class SimpleTest(unittest.TestCase): """ + def test_load_module_API(self): + # If fullname is not specified that assume self.name is desired. + class TesterMixin(importlib.abc.Loader): + def load_module(self, fullname): return fullname + + class Tester(importlib.abc.FileLoader, TesterMixin): + def get_code(self, _): pass + def get_source(self, _): pass + def is_package(self, _): pass + + name = 'mod_name' + loader = Tester(name, 'some_path') + self.assertEqual(name, loader.load_module()) + self.assertEqual(name, loader.load_module(None)) + self.assertEqual(name, loader.load_module(name)) + with self.assertRaises(ImportError): + loader.load_module(loader.name + 'XXX') + + def test_get_filename_API(self): + # If fullname is not set then assume self.path is desired. + class Tester(importlib.abc.FileLoader): + def get_code(self, _): pass + def get_source(self, _): pass + def is_package(self, _): pass + + path = 'some_path' + name = 'some_name' + loader = Tester(name, path) + self.assertEqual(path, loader.get_filename(name)) + self.assertEqual(path, loader.get_filename()) + self.assertEqual(path, loader.get_filename(None)) + with self.assertRaises(ImportError): + loader.get_filename(name + 'XXX') + # [basic] def test_module(self): with source_util.create_modules('_temp') as mapping: - loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp']) + loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp']) module = loader.load_module('_temp') self.assertTrue('_temp' in sys.modules) check = {'__name__': '_temp', '__file__': mapping['_temp'], @@ -37,7 +72,7 @@ class SimpleTest(unittest.TestCase): def test_package(self): with source_util.create_modules('_pkg.__init__') as mapping: - loader = _bootstrap._SourceFileLoader('_pkg', + loader = _bootstrap.SourceFileLoader('_pkg', mapping['_pkg.__init__']) module = loader.load_module('_pkg') self.assertTrue('_pkg' in sys.modules) @@ -50,7 +85,7 @@ class SimpleTest(unittest.TestCase): def test_lacking_parent(self): with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping: - loader = _bootstrap._SourceFileLoader('_pkg.mod', + loader = _bootstrap.SourceFileLoader('_pkg.mod', mapping['_pkg.mod']) module = loader.load_module('_pkg.mod') self.assertTrue('_pkg.mod' in sys.modules) @@ -65,17 +100,12 @@ class SimpleTest(unittest.TestCase): def test_module_reuse(self): with source_util.create_modules('_temp') as mapping: - loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp']) + loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp']) module = loader.load_module('_temp') module_id = id(module) module_dict_id = id(module.__dict__) with open(mapping['_temp'], 'w') as file: file.write("testing_var = 42\n") - # For filesystems where the mtime is only to a second granularity, - # everything that has happened above can be too fast; - # force an mtime on the source that is guaranteed to be different - # than the original mtime. - loader.path_mtime = self.fake_mtime(loader.path_mtime) module = loader.load_module('_temp') self.assertTrue('testing_var' in module.__dict__, "'testing_var' not in " @@ -95,7 +125,7 @@ class SimpleTest(unittest.TestCase): setattr(orig_module, attr, value) with open(mapping[name], 'w') as file: file.write('+++ bad syntax +++') - loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp']) + loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): loader.load_module(name) for attr in attributes: @@ -106,7 +136,7 @@ class SimpleTest(unittest.TestCase): with source_util.create_modules('_temp') as mapping: with open(mapping['_temp'], 'w') as file: file.write('=') - loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp']) + loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): loader.load_module('_temp') self.assertTrue('_temp' not in sys.modules) @@ -119,7 +149,7 @@ class SimpleTest(unittest.TestCase): file.write("# test file for importlib") try: with util.uncache('_temp'): - loader = _bootstrap._SourceFileLoader('_temp', file_path) + loader = _bootstrap.SourceFileLoader('_temp', file_path) mod = loader.load_module('_temp') self.assertEqual(file_path, mod.__file__) self.assertEqual(imp.cache_from_source(file_path), @@ -145,7 +175,7 @@ class SimpleTest(unittest.TestCase): if e.errno != getattr(errno, 'EOVERFLOW', None): raise self.skipTest("cannot set modification time to large integer ({})".format(e)) - loader = _bootstrap._SourceFileLoader('_temp', mapping['_temp']) + loader = _bootstrap.SourceFileLoader('_temp', mapping['_temp']) mod = loader.load_module('_temp') # Sanity checks. self.assertEqual(mod.__cached__, compiled) @@ -215,10 +245,17 @@ class BadBytecodeTest(unittest.TestCase): del_source=del_source) test('_temp', mapping, bc_path) + def _test_partial_size(self, test, *, del_source=False): + with source_util.create_modules('_temp') as mapping: + bc_path = self.manipulate_bytecode('_temp', mapping, + lambda bc: bc[:11], + del_source=del_source) + test('_temp', mapping, bc_path) + def _test_no_marshal(self, *, del_source=False): with source_util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, - lambda bc: bc[:8], + lambda bc: bc[:12], del_source=del_source) file_path = mapping['_temp'] if not del_source else bc_path with self.assertRaises(EOFError): @@ -227,16 +264,18 @@ class BadBytecodeTest(unittest.TestCase): def _test_non_code_marshal(self, *, del_source=False): with source_util.create_modules('_temp') as mapping: bytecode_path = self.manipulate_bytecode('_temp', mapping, - lambda bc: bc[:8] + marshal.dumps(b'abcd'), + lambda bc: bc[:12] + marshal.dumps(b'abcd'), del_source=del_source) file_path = mapping['_temp'] if not del_source else bytecode_path - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(file_path, '_temp') + self.assertEqual(cm.exception.name, '_temp') + self.assertEqual(cm.exception.path, bytecode_path) def _test_bad_marshal(self, *, del_source=False): with source_util.create_modules('_temp') as mapping: bytecode_path = self.manipulate_bytecode('_temp', mapping, - lambda bc: bc[:8] + b'<test>', + lambda bc: bc[:12] + b'<test>', del_source=del_source) file_path = mapping['_temp'] if not del_source else bytecode_path with self.assertRaises(EOFError): @@ -251,7 +290,7 @@ class BadBytecodeTest(unittest.TestCase): class SourceLoaderBadBytecodeTest(BadBytecodeTest): - loader = _bootstrap._SourceFileLoader + loader = _bootstrap.SourceFileLoader @source_util.writes_bytecode_files def test_empty_file(self): @@ -260,7 +299,7 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): def test(name, mapping, bytecode_path): self.import_(mapping[name], name) with open(bytecode_path, 'rb') as file: - self.assertGreater(len(file.read()), 8) + self.assertGreater(len(file.read()), 12) self._test_empty_file(test) @@ -268,7 +307,7 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): def test(name, mapping, bytecode_path): self.import_(mapping[name], name) with open(bytecode_path, 'rb') as file: - self.assertGreater(len(file.read()), 8) + self.assertGreater(len(file.read()), 12) self._test_partial_magic(test) @@ -279,7 +318,7 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): def test(name, mapping, bytecode_path): self.import_(mapping[name], name) with open(bytecode_path, 'rb') as file: - self.assertGreater(len(file.read()), 8) + self.assertGreater(len(file.read()), 12) self._test_magic_only(test) @@ -301,11 +340,22 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): def test(name, mapping, bc_path): self.import_(mapping[name], name) with open(bc_path, 'rb') as file: - self.assertGreater(len(file.read()), 8) + self.assertGreater(len(file.read()), 12) self._test_partial_timestamp(test) @source_util.writes_bytecode_files + def test_partial_size(self): + # When the size is partial, regenerate the .pyc, else + # raise EOFError. + def test(name, mapping, bc_path): + self.import_(mapping[name], name) + with open(bc_path, 'rb') as file: + self.assertGreater(len(file.read()), 12) + + self._test_partial_size(test) + + @source_util.writes_bytecode_files def test_no_marshal(self): # When there is only the magic number and timestamp, raise EOFError. self._test_no_marshal() @@ -364,19 +414,23 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): - loader = _bootstrap._SourcelessFileLoader + loader = _bootstrap.SourcelessFileLoader def test_empty_file(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_empty_file(test, del_source=True) def test_partial_magic(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_partial_magic(test, del_source=True) def test_magic_only(self): @@ -388,8 +442,10 @@ class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): def test_bad_magic(self): def test(name, mapping, bytecode_path): - with self.assertRaises(ImportError): + with self.assertRaises(ImportError) as cm: self.import_(bytecode_path, name) + self.assertEqual(cm.exception.name, name) + self.assertEqual(cm.exception.path, bytecode_path) self._test_bad_magic(test, del_source=True) @@ -400,6 +456,13 @@ class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): self._test_partial_timestamp(test, del_source=True) + def test_partial_size(self): + def test(name, mapping, bytecode_path): + with self.assertRaises(EOFError): + self.import_(bytecode_path, name) + + self._test_partial_size(test, del_source=True) + def test_no_marshal(self): self._test_no_marshal(del_source=True) diff --git a/Lib/importlib/test/source/test_finder.py b/Lib/importlib/test/source/test_finder.py index 7b9088d..bbe0163 100644 --- a/Lib/importlib/test/source/test_finder.py +++ b/Lib/importlib/test/source/test_finder.py @@ -1,10 +1,12 @@ -from importlib import _bootstrap from .. import abc from . import util as source_util -from test.support import make_legacy_pyc -import os + +from importlib import machinery import errno +import imp +import os import py_compile +from test.support import make_legacy_pyc import unittest import warnings @@ -34,9 +36,11 @@ class FinderTests(abc.FinderTests): """ def import_(self, root, module): - finder = _bootstrap._FileFinder(root, - _bootstrap._SourceFinderDetails(), - _bootstrap._SourcelessFinderDetails()) + loader_details = [(machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES, True), + (machinery.SourcelessFileLoader, + machinery.BYTECODE_SUFFIXES, True)] + finder = machinery.FileFinder(root, *loader_details) return finder.find_module(module) def run_test(self, test, create=None, *, compile_=None, unlink=None): @@ -134,7 +138,8 @@ class FinderTests(abc.FinderTests): def test_empty_string_for_dir(self): # The empty string from sys.path means to search in the cwd. - finder = _bootstrap._FileFinder('', _bootstrap._SourceFinderDetails()) + finder = machinery.FileFinder('', (machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES, True)) with open('mod.py', 'w') as file: file.write("# test file for importlib") try: @@ -143,6 +148,14 @@ class FinderTests(abc.FinderTests): finally: os.unlink('mod.py') + def test_invalidate_caches(self): + # invalidate_caches() should reset the mtime. + finder = machinery.FileFinder('', (machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES, True)) + finder._path_mtime = 42 + finder.invalidate_caches() + self.assertEqual(finder._path_mtime, -1) + def test_main(): from test.support import run_unittest diff --git a/Lib/importlib/test/source/test_path_hook.py b/Lib/importlib/test/source/test_path_hook.py index 374f7b6..54c0699 100644 --- a/Lib/importlib/test/source/test_path_hook.py +++ b/Lib/importlib/test/source/test_path_hook.py @@ -1,5 +1,7 @@ -from importlib import _bootstrap from . import util as source_util + +from importlib import machinery +import imp import unittest @@ -7,14 +9,18 @@ class PathHookTest(unittest.TestCase): """Test the path hook for source.""" + def path_hook(self): + return machinery.FileFinder.path_hook((machinery.SourceFileLoader, + machinery.SOURCE_SUFFIXES, True)) + def test_success(self): with source_util.create_modules('dummy') as mapping: - self.assertTrue(hasattr(_bootstrap._file_path_hook(mapping['.root']), + self.assertTrue(hasattr(self.path_hook()(mapping['.root']), 'find_module')) def test_empty_string(self): # The empty string represents the cwd. - self.assertTrue(hasattr(_bootstrap._file_path_hook(''), 'find_module')) + self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) def test_main(): diff --git a/Lib/importlib/test/source/test_source_encoding.py b/Lib/importlib/test/source/test_source_encoding.py index 794a3df..0ca5195 100644 --- a/Lib/importlib/test/source/test_source_encoding.py +++ b/Lib/importlib/test/source/test_source_encoding.py @@ -1,6 +1,6 @@ -from importlib import _bootstrap from . import util as source_util +from importlib import _bootstrap import codecs import re import sys @@ -35,8 +35,8 @@ class EncodingTest(unittest.TestCase): with source_util.create_modules(self.module_name) as mapping: with open(mapping[self.module_name], 'wb') as file: file.write(source) - loader = _bootstrap._SourceFileLoader(self.module_name, - mapping[self.module_name]) + loader = _bootstrap.SourceFileLoader(self.module_name, + mapping[self.module_name]) return loader.load_module(self.module_name) def create_source(self, encoding): @@ -97,7 +97,7 @@ class LineEndingTest(unittest.TestCase): with source_util.create_modules(module_name) as mapping: with open(mapping[module_name], 'wb') as file: file.write(source) - loader = _bootstrap._SourceFileLoader(module_name, + loader = _bootstrap.SourceFileLoader(module_name, mapping[module_name]) return loader.load_module(module_name) |
