From 9ea8eda127b824f9cffb64deadbb420244a301c2 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 8 Nov 2013 14:25:37 -0500 Subject: [PATCH] Issue #16803: test.test_importlib.source now tests frozen and source code --- .../source/test_case_sensitivity.py | 28 ++++---- .../test_importlib/source/test_file_loader.py | 70 ++++++++++++------- Lib/test/test_importlib/source/test_finder.py | 30 ++++---- .../test_importlib/source/test_path_hook.py | 17 +++-- .../source/test_source_encoding.py | 20 +++--- 5 files changed, 91 insertions(+), 74 deletions(-) diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py index bb78d2ed866..b3e9d25bb26 100644 --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -2,8 +2,9 @@ from .. import util from . import util as source_util -from importlib import _bootstrap -from importlib import machinery +importlib = util.import_importlib('importlib') +machinery = util.import_importlib('importlib.machinery') + import os import sys from test import support as test_support @@ -11,7 +12,7 @@ import unittest @util.case_insensitive_tests -class CaseSensitivityTest(unittest.TestCase): +class CaseSensitivityTest: """PEP 235 dictates that on case-preserving, case-insensitive file systems that imports are case-sensitive unless the PYTHONCASEOK environment @@ -21,11 +22,11 @@ class CaseSensitivityTest(unittest.TestCase): assert name != name.lower() def find(self, path): - finder = machinery.FileFinder(path, - (machinery.SourceFileLoader, - machinery.SOURCE_SUFFIXES), - (machinery.SourcelessFileLoader, - machinery.BYTECODE_SUFFIXES)) + finder = self.machinery.FileFinder(path, + (self.machinery.SourceFileLoader, + self.machinery.SOURCE_SUFFIXES), + (self.machinery.SourcelessFileLoader, + self.machinery.BYTECODE_SUFFIXES)) return finder.find_module(self.name) def sensitivity_test(self): @@ -41,7 +42,7 @@ class CaseSensitivityTest(unittest.TestCase): def test_sensitive(self): with test_support.EnvironmentVarGuard() as env: env.unset('PYTHONCASEOK') - if b'PYTHONCASEOK' in _bootstrap._os.environ: + if b'PYTHONCASEOK' in self.importlib._bootstrap._os.environ: self.skipTest('os.environ changes not reflected in ' '_os.environ') sensitive, insensitive = self.sensitivity_test() @@ -52,7 +53,7 @@ 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: + if b'PYTHONCASEOK' not in self.importlib._bootstrap._os.environ: self.skipTest('os.environ changes not reflected in ' '_os.environ') sensitive, insensitive = self.sensitivity_test() @@ -61,10 +62,9 @@ class CaseSensitivityTest(unittest.TestCase): self.assertTrue(hasattr(insensitive, 'load_module')) self.assertIn(self.name, insensitive.get_filename(self.name)) - -def test_main(): - test_support.run_unittest(CaseSensitivityTest) +Frozen_CaseSensitivityTest, Source_CaseSensitivityTest = util.test_both( + CaseSensitivityTest, importlib=importlib, machinery=machinery) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 9e035ea97be..f1e2713a971 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -1,11 +1,12 @@ -from importlib import machinery -import importlib -import importlib.abc -import importlib.util from .. import abc from .. import util from . import util as source_util +importlib = util.import_importlib('importlib') +importlib_abc = util.import_importlib('importlib.abc') +machinery = util.import_importlib('importlib.machinery') +importlib_util = util.import_importlib('importlib.util') + import errno import marshal import os @@ -19,7 +20,7 @@ import unittest from test.support import make_legacy_pyc, unload -class SimpleTest(unittest.TestCase, abc.LoaderTests): +class SimpleTest(abc.LoaderTests): """Should have no issue importing a source module [basic]. And if there is a syntax error, it should raise a SyntaxError [syntax error]. @@ -27,7 +28,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): """ def test_load_module_API(self): - class Tester(importlib.abc.FileLoader): + class Tester(self.abc.FileLoader): def get_source(self, _): return 'attr = 42' def is_package(self, _): return False @@ -37,7 +38,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): def test_get_filename_API(self): # If fullname is not set then assume self.path is desired. - class Tester(importlib.abc.FileLoader): + class Tester(self.abc.FileLoader): def get_code(self, _): pass def get_source(self, _): pass def is_package(self, _): pass @@ -55,7 +56,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): # [basic] def test_module(self): with source_util.create_modules('_temp') as mapping: - loader = machinery.SourceFileLoader('_temp', mapping['_temp']) + loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) module = loader.load_module('_temp') self.assertIn('_temp', sys.modules) check = {'__name__': '_temp', '__file__': mapping['_temp'], @@ -65,7 +66,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): def test_package(self): with source_util.create_modules('_pkg.__init__') as mapping: - loader = machinery.SourceFileLoader('_pkg', + loader = self.machinery.SourceFileLoader('_pkg', mapping['_pkg.__init__']) module = loader.load_module('_pkg') self.assertIn('_pkg', sys.modules) @@ -78,7 +79,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): def test_lacking_parent(self): with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping: - loader = machinery.SourceFileLoader('_pkg.mod', + loader = self.machinery.SourceFileLoader('_pkg.mod', mapping['_pkg.mod']) module = loader.load_module('_pkg.mod') self.assertIn('_pkg.mod', sys.modules) @@ -93,7 +94,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): def test_module_reuse(self): with source_util.create_modules('_temp') as mapping: - loader = machinery.SourceFileLoader('_temp', mapping['_temp']) + loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) module = loader.load_module('_temp') module_id = id(module) module_dict_id = id(module.__dict__) @@ -118,7 +119,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): setattr(orig_module, attr, value) with open(mapping[name], 'w') as file: file.write('+++ bad syntax +++') - loader = machinery.SourceFileLoader('_temp', mapping['_temp']) + loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): loader.load_module(name) for attr in attributes: @@ -129,7 +130,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): with source_util.create_modules('_temp') as mapping: with open(mapping['_temp'], 'w') as file: file.write('=') - loader = machinery.SourceFileLoader('_temp', mapping['_temp']) + loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): loader.load_module('_temp') self.assertNotIn('_temp', sys.modules) @@ -142,14 +143,14 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): file.write("# test file for importlib") try: with util.uncache('_temp'): - loader = machinery.SourceFileLoader('_temp', file_path) + loader = self.machinery.SourceFileLoader('_temp', file_path) mod = loader.load_module('_temp') self.assertEqual(file_path, mod.__file__) - self.assertEqual(importlib.util.cache_from_source(file_path), + self.assertEqual(self.util.cache_from_source(file_path), mod.__cached__) finally: os.unlink(file_path) - pycache = os.path.dirname(importlib.util.cache_from_source(file_path)) + pycache = os.path.dirname(self.util.cache_from_source(file_path)) if os.path.exists(pycache): shutil.rmtree(pycache) @@ -158,7 +159,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): # truncated rather than raise an OverflowError. with source_util.create_modules('_temp') as mapping: source = mapping['_temp'] - compiled = importlib.util.cache_from_source(source) + compiled = self.util.cache_from_source(source) with open(source, 'w') as f: f.write("x = 5") try: @@ -169,7 +170,7 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): if e.errno != getattr(errno, 'EOVERFLOW', None): raise self.skipTest("cannot set modification time to large integer ({})".format(e)) - loader = machinery.SourceFileLoader('_temp', mapping['_temp']) + loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) mod = loader.load_module('_temp') # Sanity checks. self.assertEqual(mod.__cached__, compiled) @@ -178,12 +179,16 @@ class SimpleTest(unittest.TestCase, abc.LoaderTests): os.stat(compiled) def test_unloadable(self): - loader = machinery.SourceFileLoader('good name', {}) + loader = self.machinery.SourceFileLoader('good name', {}) with self.assertRaises(ImportError): loader.load_module('bad name') +Frozen_SimpleTest, Source_SimpleTest = util.test_both( + SimpleTest, importlib=importlib, machinery=machinery, abc=importlib_abc, + util=importlib_util) -class BadBytecodeTest(unittest.TestCase): + +class BadBytecodeTest: def import_(self, file, module_name): loader = self.loader(module_name, file) @@ -200,7 +205,7 @@ class BadBytecodeTest(unittest.TestCase): pass py_compile.compile(mapping[name]) if not del_source: - bytecode_path = importlib.util.cache_from_source(mapping[name]) + bytecode_path = self.util.cache_from_source(mapping[name]) else: os.unlink(mapping[name]) bytecode_path = make_legacy_pyc(mapping[name]) @@ -289,7 +294,9 @@ class BadBytecodeTest(unittest.TestCase): class SourceLoaderBadBytecodeTest(BadBytecodeTest): - loader = machinery.SourceFileLoader + @classmethod + def setUpClass(cls): + cls.loader = cls.machinery.SourceFileLoader @source_util.writes_bytecode_files def test_empty_file(self): @@ -329,7 +336,7 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): self.import_(mapping[name], name) with open(bytecode_path, 'rb') as bytecode_file: self.assertEqual(bytecode_file.read(4), - importlib.util.MAGIC_NUMBER) + self.util.MAGIC_NUMBER) self._test_bad_magic(test) @@ -379,13 +386,13 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): zeros = b'\x00\x00\x00\x00' with source_util.create_modules('_temp') as mapping: py_compile.compile(mapping['_temp']) - bytecode_path = importlib.util.cache_from_source(mapping['_temp']) + bytecode_path = self.util.cache_from_source(mapping['_temp']) with open(bytecode_path, 'r+b') as bytecode_file: bytecode_file.seek(4) bytecode_file.write(zeros) self.import_(mapping['_temp'], '_temp') source_mtime = os.path.getmtime(mapping['_temp']) - source_timestamp = importlib._w_long(source_mtime) + source_timestamp = self.importlib._w_long(source_mtime) with open(bytecode_path, 'rb') as bytecode_file: bytecode_file.seek(4) self.assertEqual(bytecode_file.read(4), source_timestamp) @@ -397,7 +404,7 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): with source_util.create_modules('_temp') as mapping: # Create bytecode that will need to be re-created. py_compile.compile(mapping['_temp']) - bytecode_path = importlib.util.cache_from_source(mapping['_temp']) + bytecode_path = self.util.cache_from_source(mapping['_temp']) with open(bytecode_path, 'r+b') as bytecode_file: bytecode_file.seek(0) bytecode_file.write(b'\x00\x00\x00\x00') @@ -411,10 +418,16 @@ class SourceLoaderBadBytecodeTest(BadBytecodeTest): # Make writable for eventual clean-up. os.chmod(bytecode_path, stat.S_IWUSR) +Frozen_SourceBadBytecode, Source_SourceBadBytecode = util.test_both( + SourceLoaderBadBytecodeTest, importlib=importlib, machinery=machinery, + abc=importlib_abc, util=importlib_util) + class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): - loader = machinery.SourcelessFileLoader + @classmethod + def setUpClass(cls): + cls.loader = cls.machinery.SourcelessFileLoader def test_empty_file(self): def test(name, mapping, bytecode_path): @@ -469,6 +482,9 @@ class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): def test_non_code_marshal(self): self._test_non_code_marshal(del_source=True) +Frozen_SourcelessBadBytecode, Source_SourcelessBadBytecode = util.test_both( + SourcelessLoaderBadBytecodeTest, importlib=importlib, + machinery=machinery, abc=importlib_abc, util=importlib_util) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index 9d6cec05103..8bf8cb78808 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -1,7 +1,9 @@ from .. import abc +from .. import util from . import util as source_util -from importlib import machinery +machinery = util.import_importlib('importlib.machinery') + import errno import os import py_compile @@ -13,7 +15,7 @@ import unittest import warnings -class FinderTests(unittest.TestCase, abc.FinderTests): +class FinderTests(abc.FinderTests): """For a top-level module, it should just be found directly in the directory being searched. This is true for a directory with source @@ -38,11 +40,11 @@ class FinderTests(unittest.TestCase, abc.FinderTests): """ def get_finder(self, root): - loader_details = [(machinery.SourceFileLoader, - machinery.SOURCE_SUFFIXES), - (machinery.SourcelessFileLoader, - machinery.BYTECODE_SUFFIXES)] - return machinery.FileFinder(root, *loader_details) + loader_details = [(self.machinery.SourceFileLoader, + self.machinery.SOURCE_SUFFIXES), + (self.machinery.SourcelessFileLoader, + self.machinery.BYTECODE_SUFFIXES)] + return self.machinery.FileFinder(root, *loader_details) def import_(self, root, module): return self.get_finder(root).find_module(module) @@ -123,8 +125,8 @@ class FinderTests(unittest.TestCase, abc.FinderTests): def test_empty_string_for_dir(self): # The empty string from sys.path means to search in the cwd. - finder = machinery.FileFinder('', (machinery.SourceFileLoader, - machinery.SOURCE_SUFFIXES)) + finder = self.machinery.FileFinder('', (self.machinery.SourceFileLoader, + self.machinery.SOURCE_SUFFIXES)) with open('mod.py', 'w') as file: file.write("# test file for importlib") try: @@ -135,8 +137,8 @@ class FinderTests(unittest.TestCase, abc.FinderTests): def test_invalidate_caches(self): # invalidate_caches() should reset the mtime. - finder = machinery.FileFinder('', (machinery.SourceFileLoader, - machinery.SOURCE_SUFFIXES)) + finder = self.machinery.FileFinder('', (self.machinery.SourceFileLoader, + self.machinery.SOURCE_SUFFIXES)) finder._path_mtime = 42 finder.invalidate_caches() self.assertEqual(finder._path_mtime, -1) @@ -180,11 +182,9 @@ class FinderTests(unittest.TestCase, abc.FinderTests): finder = self.get_finder(file_obj.name) self.assertEqual((None, []), finder.find_loader('doesnotexist')) +Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests, machinery=machinery) -def test_main(): - from test.support import run_unittest - run_unittest(FinderTests) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py index d320f8e025b..92da77265b5 100644 --- a/Lib/test/test_importlib/source/test_path_hook.py +++ b/Lib/test/test_importlib/source/test_path_hook.py @@ -1,16 +1,18 @@ +from .. import util from . import util as source_util -from importlib import machinery +machinery = util.import_importlib('importlib.machinery') + import unittest -class PathHookTest(unittest.TestCase): +class PathHookTest: """Test the path hook for source.""" def path_hook(self): - return machinery.FileFinder.path_hook((machinery.SourceFileLoader, - machinery.SOURCE_SUFFIXES)) + return self.machinery.FileFinder.path_hook((self.machinery.SourceFileLoader, + self.machinery.SOURCE_SUFFIXES)) def test_success(self): with source_util.create_modules('dummy') as mapping: @@ -21,11 +23,8 @@ class PathHookTest(unittest.TestCase): # The empty string represents the cwd. self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) - -def test_main(): - from test.support import run_unittest - run_unittest(PathHookTest) +Frozen_PathHookTest, Source_PathHooktest = util.test_both(PathHookTest, machinery=machinery) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_importlib/source/test_source_encoding.py b/Lib/test/test_importlib/source/test_source_encoding.py index ba02b442743..654f4c2b2f6 100644 --- a/Lib/test/test_importlib/source/test_source_encoding.py +++ b/Lib/test/test_importlib/source/test_source_encoding.py @@ -1,6 +1,8 @@ +from .. import util from . import util as source_util -from importlib import _bootstrap +machinery = util.import_importlib('importlib.machinery') + import codecs import re import sys @@ -13,7 +15,7 @@ import unittest CODING_RE = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) -class EncodingTest(unittest.TestCase): +class EncodingTest: """PEP 3120 makes UTF-8 the default encoding for source code [default encoding]. @@ -35,7 +37,7 @@ 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, + loader = self.machinery.SourceFileLoader(self.module_name, mapping[self.module_name]) return loader.load_module(self.module_name) @@ -84,8 +86,10 @@ class EncodingTest(unittest.TestCase): with self.assertRaises(SyntaxError): self.run_test(source) +Frozen_EncodingTest, Source_EncodingTest = util.test_both(EncodingTest, machinery=machinery) -class LineEndingTest(unittest.TestCase): + +class LineEndingTest: r"""Source written with the three types of line endings (\n, \r\n, \r) need to be readable [cr][crlf][lf].""" @@ -97,7 +101,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 = self.machinery.SourceFileLoader(module_name, mapping[module_name]) return loader.load_module(module_name) @@ -113,11 +117,9 @@ class LineEndingTest(unittest.TestCase): def test_lf(self): self.run_test(b'\n') +Frozen_LineEndings, Source_LineEndings = util.test_both(LineEndingTest, machinery=machinery) -def test_main(): - from test.support import run_unittest - run_unittest(EncodingTest, LineEndingTest) if __name__ == '__main__': - test_main() + unittest.main()