diff options
author | Brett Cannon <brett@python.org> | 2015-04-13 18:21:02 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2015-04-13 18:21:02 (GMT) |
commit | f299abdafa0f2b6eb7abae274861b19b361c96bc (patch) | |
tree | afc3a2bf560e30c7725510eda3b57d71ceddba00 /Lib/test | |
parent | a63cc212348e276c8ede32773313c60ff7fda651 (diff) | |
download | cpython-f299abdafa0f2b6eb7abae274861b19b361c96bc.zip cpython-f299abdafa0f2b6eb7abae274861b19b361c96bc.tar.gz cpython-f299abdafa0f2b6eb7abae274861b19b361c96bc.tar.bz2 |
Issue #23731: Implement PEP 488.
The concept of .pyo files no longer exists. Now .pyc files have an
optional `opt-` tag which specifies if any extra optimizations beyond
the peepholer were applied.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/support/__init__.py | 20 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 2 | ||||
-rw-r--r-- | Lib/test/test_compileall.py | 21 | ||||
-rw-r--r-- | Lib/test/test_imp.py | 115 | ||||
-rw-r--r-- | Lib/test/test_import/__init__.py | 37 | ||||
-rw-r--r-- | Lib/test/test_importlib/test_util.py | 114 | ||||
-rw-r--r-- | Lib/test/test_py_compile.py | 4 | ||||
-rw-r--r-- | Lib/test/test_runpy.py | 2 | ||||
-rw-r--r-- | Lib/test/test_trace.py | 4 | ||||
-rw-r--r-- | Lib/test/test_tracemalloc.py | 6 | ||||
-rw-r--r-- | Lib/test/test_zipfile.py | 11 | ||||
-rw-r--r-- | Lib/test/test_zipimport.py | 2 |
12 files changed, 145 insertions, 193 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 0495121..1d0f11f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -376,36 +376,32 @@ def rmtree(path): pass def make_legacy_pyc(source): - """Move a PEP 3147 pyc/pyo file to its legacy pyc/pyo location. - - The choice of .pyc or .pyo extension is done based on the __debug__ flag - value. + """Move a PEP 3147/488 pyc file to its legacy pyc location. :param source: The file system path to the source file. The source file - does not need to exist, however the PEP 3147 pyc file must exist. + does not need to exist, however the PEP 3147/488 pyc file must exist. :return: The file system path to the legacy pyc file. """ pyc_file = importlib.util.cache_from_source(source) up_one = os.path.dirname(os.path.abspath(source)) - legacy_pyc = os.path.join(up_one, source + ('c' if __debug__ else 'o')) + legacy_pyc = os.path.join(up_one, source + 'c') os.rename(pyc_file, legacy_pyc) return legacy_pyc def forget(modname): """'Forget' a module was ever imported. - This removes the module from sys.modules and deletes any PEP 3147 or - legacy .pyc and .pyo files. + This removes the module from sys.modules and deletes any PEP 3147/488 or + legacy .pyc files. """ unload(modname) for dirname in sys.path: source = os.path.join(dirname, modname + '.py') # It doesn't matter if they exist or not, unlink all possible - # combinations of PEP 3147 and legacy pyc and pyo files. + # combinations of PEP 3147/488 and legacy pyc files. unlink(source + 'c') - unlink(source + 'o') - unlink(importlib.util.cache_from_source(source, debug_override=True)) - unlink(importlib.util.cache_from_source(source, debug_override=False)) + for opt in ('', 1, 2): + unlink(importlib.util.cache_from_source(source, optimization=opt)) # Check whether a gui is actually available def _is_gui_available(): diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6116676..3d33bb5 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -425,7 +425,7 @@ if 1: def test_compile_ast(self): fname = __file__ - if fname.lower().endswith(('pyc', 'pyo')): + if fname.lower().endswith('pyc'): fname = fname[:-1] with open(fname, 'r') as f: fcontents = f.read() diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 7506c70..07756f6 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -101,16 +101,16 @@ class CompileallTests(unittest.TestCase): def test_optimize(self): # make sure compiling with different optimization settings than the # interpreter's creates the correct file names - optimize = 1 if __debug__ else 0 + optimize, opt = (1, 1) if __debug__ else (0, '') compileall.compile_dir(self.directory, quiet=True, optimize=optimize) cached = importlib.util.cache_from_source(self.source_path, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached)) cached2 = importlib.util.cache_from_source(self.source_path2, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached2)) cached3 = importlib.util.cache_from_source(self.source_path3, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached3)) @mock.patch('compileall.ProcessPoolExecutor') @@ -237,11 +237,11 @@ class CommandLineTests(unittest.TestCase): self.assertNotIn(b'Listing ', quiet) # Ensure that the default behavior of compileall's CLI is to create - # PEP 3147 pyc/pyo files. + # PEP 3147/PEP 488 pyc files. for name, ext, switch in [ ('normal', 'pyc', []), - ('optimize', 'pyo', ['-O']), - ('doubleoptimize', 'pyo', ['-OO']), + ('optimize', 'opt-1.pyc', ['-O']), + ('doubleoptimize', 'opt-2.pyc', ['-OO']), ]: def f(self, ext=ext, switch=switch): script_helper.assert_python_ok(*(switch + @@ -258,13 +258,12 @@ class CommandLineTests(unittest.TestCase): def test_legacy_paths(self): # Ensure that with the proper switch, compileall leaves legacy - # pyc/pyo files, and no __pycache__ directory. + # pyc files, and no __pycache__ directory. self.assertRunOK('-b', '-q', self.pkgdir) # Verify the __pycache__ directory contents. self.assertFalse(os.path.exists(self.pkgdir_cachedir)) - opt = 'c' if __debug__ else 'o' - expected = sorted(['__init__.py', '__init__.py' + opt, 'bar.py', - 'bar.py' + opt]) + expected = sorted(['__init__.py', '__init__.pyc', 'bar.py', + 'bar.pyc']) self.assertEqual(sorted(os.listdir(self.pkgdir)), expected) def test_multiple_runs(self): diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 80b9ec3..47bf1de 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -111,7 +111,6 @@ class ImportTests(unittest.TestCase): del sys.path[0] support.unlink(temp_mod_name + '.py') support.unlink(temp_mod_name + '.pyc') - support.unlink(temp_mod_name + '.pyo') def test_issue5604(self): # Test cannot cover imp.load_compiled function. @@ -194,7 +193,7 @@ class ImportTests(unittest.TestCase): self.assertEqual(package.b, 2) finally: del sys.path[0] - for ext in ('.py', '.pyc', '.pyo'): + for ext in ('.py', '.pyc'): support.unlink(temp_mod_name + ext) support.unlink(init_file_name + ext) support.rmtree(test_package_name) @@ -346,56 +345,6 @@ class PEP3147Tests(unittest.TestCase): 'qux.{}.pyc'.format(self.tag)) self.assertEqual(imp.cache_from_source(path, True), expect) - def test_cache_from_source_no_cache_tag(self): - # Non cache tag means NotImplementedError. - with support.swap_attr(sys.implementation, 'cache_tag', None): - with self.assertRaises(NotImplementedError): - imp.cache_from_source('whatever.py') - - def test_cache_from_source_no_dot(self): - # Directory with a dot, filename without dot. - path = os.path.join('foo.bar', 'file') - expect = os.path.join('foo.bar', '__pycache__', - 'file{}.pyc'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, True), expect) - - def test_cache_from_source_optimized(self): - # Given the path to a .py file, return the path to its PEP 3147 - # defined .pyo file (i.e. under __pycache__). - path = os.path.join('foo', 'bar', 'baz', 'qux.py') - expect = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyo'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, False), expect) - - def test_cache_from_source_cwd(self): - path = 'foo.py' - expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, True), expect) - - def test_cache_from_source_override(self): - # When debug_override is not None, it can be any true-ish or false-ish - # value. - path = os.path.join('foo', 'bar', 'baz.py') - partial_expect = os.path.join('foo', 'bar', '__pycache__', - 'baz.{}.py'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, []), partial_expect + 'o') - self.assertEqual(imp.cache_from_source(path, [17]), - partial_expect + 'c') - # However if the bool-ishness can't be determined, the exception - # propagates. - class Bearish: - def __bool__(self): raise RuntimeError - with self.assertRaises(RuntimeError): - imp.cache_from_source('/foo/bar/baz.py', Bearish()) - - @unittest.skipUnless(os.sep == '\\' and os.altsep == '/', - 'test meaningful only where os.altsep is defined') - def test_sep_altsep_and_sep_cache_from_source(self): - # Windows path and PEP 3147 where sep is right of altsep. - self.assertEqual( - imp.cache_from_source('\\foo\\bar\\baz/qux.py', True), - '\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag)) - @unittest.skipUnless(sys.implementation.cache_tag is not None, 'requires sys.implementation.cache_tag to not be ' 'None') @@ -407,68 +356,6 @@ class PEP3147Tests(unittest.TestCase): expect = os.path.join('foo', 'bar', 'baz', 'qux.py') self.assertEqual(imp.source_from_cache(path), expect) - def test_source_from_cache_no_cache_tag(self): - # If sys.implementation.cache_tag is None, raise NotImplementedError. - path = os.path.join('blah', '__pycache__', 'whatever.pyc') - with support.swap_attr(sys.implementation, 'cache_tag', None): - with self.assertRaises(NotImplementedError): - imp.source_from_cache(path) - - def test_source_from_cache_bad_path(self): - # When the path to a pyc file is not in PEP 3147 format, a ValueError - # is raised. - self.assertRaises( - ValueError, imp.source_from_cache, '/foo/bar/bazqux.pyc') - - def test_source_from_cache_no_slash(self): - # No slashes at all in path -> ValueError - self.assertRaises( - ValueError, imp.source_from_cache, 'foo.cpython-32.pyc') - - def test_source_from_cache_too_few_dots(self): - # Too few dots in final path component -> ValueError - self.assertRaises( - ValueError, imp.source_from_cache, '__pycache__/foo.pyc') - - def test_source_from_cache_too_many_dots(self): - # Too many dots in final path component -> ValueError - self.assertRaises( - ValueError, imp.source_from_cache, - '__pycache__/foo.cpython-32.foo.pyc') - - def test_source_from_cache_no__pycache__(self): - # Another problem with the path -> ValueError - self.assertRaises( - ValueError, imp.source_from_cache, - '/foo/bar/foo.cpython-32.foo.pyc') - - def test_package___file__(self): - try: - m = __import__('pep3147') - except ImportError: - pass - else: - self.fail("pep3147 module already exists: %r" % (m,)) - # Test that a package's __file__ points to the right source directory. - os.mkdir('pep3147') - sys.path.insert(0, os.curdir) - def cleanup(): - if sys.path[0] == os.curdir: - del sys.path[0] - shutil.rmtree('pep3147') - self.addCleanup(cleanup) - # Touch the __init__.py file. - support.create_empty_file('pep3147/__init__.py') - importlib.invalidate_caches() - expected___file__ = os.sep.join(('.', 'pep3147', '__init__.py')) - m = __import__('pep3147') - self.assertEqual(m.__file__, expected___file__, (m.__file__, m.__path__, sys.path, sys.path_importer_cache)) - # Ensure we load the pyc file. - support.unload('pep3147') - m = __import__('pep3147') - support.unload('pep3147') - self.assertEqual(m.__file__, expected___file__, (m.__file__, m.__path__, sys.path, sys.path_importer_cache)) - class NullImporterTests(unittest.TestCase): @unittest.skipIf(support.TESTFN_UNENCODABLE is None, diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index fd21fa2..5f87d89 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -32,7 +32,6 @@ skip_if_dont_write_bytecode = unittest.skipIf( def remove_files(name): for f in (name + ".py", name + ".pyc", - name + ".pyo", name + ".pyw", name + "$py.class"): unlink(f) @@ -84,7 +83,6 @@ class ImportTests(unittest.TestCase): def test_with_extension(ext): # The extension is normally ".py", perhaps ".pyw". source = TESTFN + ext - pyo = TESTFN + ".pyo" if is_jython: pyc = TESTFN + "$py.class" else: @@ -115,7 +113,6 @@ class ImportTests(unittest.TestCase): forget(TESTFN) unlink(source) unlink(pyc) - unlink(pyo) sys.path.insert(0, os.curdir) try: @@ -138,7 +135,7 @@ class ImportTests(unittest.TestCase): f.write(']') try: - # Compile & remove .py file; we only need .pyc (or .pyo). + # Compile & remove .py file; we only need .pyc. # Bytecode must be relocated from the PEP 3147 bytecode-only location. py_compile.compile(filename) finally: @@ -252,7 +249,7 @@ class ImportTests(unittest.TestCase): importlib.invalidate_caches() mod = __import__(TESTFN) base, ext = os.path.splitext(mod.__file__) - self.assertIn(ext, ('.pyc', '.pyo')) + self.assertEqual(ext, '.pyc') finally: del sys.path[0] remove_files(TESTFN) @@ -328,7 +325,7 @@ class ImportTests(unittest.TestCase): @skip_if_dont_write_bytecode class FilePermissionTests(unittest.TestCase): - # tests for file mode on cached .pyc/.pyo files + # tests for file mode on cached .pyc files @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") @@ -339,7 +336,7 @@ class FilePermissionTests(unittest.TestCase): module = __import__(name) if not os.path.exists(cached_path): self.fail("__import__ did not result in creation of " - "either a .pyc or .pyo file") + "a .pyc file") stat_info = os.stat(cached_path) # Check that the umask is respected, and the executable bits @@ -358,7 +355,7 @@ class FilePermissionTests(unittest.TestCase): __import__(name) if not os.path.exists(cached_path): self.fail("__import__ did not result in creation of " - "either a .pyc or .pyo file") + "a .pyc file") stat_info = os.stat(cached_path) self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(mode)) @@ -373,7 +370,7 @@ class FilePermissionTests(unittest.TestCase): __import__(name) if not os.path.exists(cached_path): self.fail("__import__ did not result in creation of " - "either a .pyc or .pyo file") + "a .pyc file") stat_info = os.stat(cached_path) expected = mode | 0o200 # Account for fix for issue #6074 @@ -404,10 +401,7 @@ class FilePermissionTests(unittest.TestCase): unlink(path) unload(name) importlib.invalidate_caches() - if __debug__: - bytecode_only = path + "c" - else: - bytecode_only = path + "o" + bytecode_only = path + "c" os.rename(importlib.util.cache_from_source(path), bytecode_only) m = __import__(name) self.assertEqual(m.x, 'rewritten') @@ -631,9 +625,7 @@ class OverridingImportBuiltinTests(unittest.TestCase): class PycacheTests(unittest.TestCase): - # Test the various PEP 3147 related behaviors. - - tag = sys.implementation.cache_tag + # Test the various PEP 3147/488-related behaviors. def _clean(self): forget(TESTFN) @@ -658,9 +650,10 @@ class PycacheTests(unittest.TestCase): self.assertFalse(os.path.exists('__pycache__')) __import__(TESTFN) self.assertTrue(os.path.exists('__pycache__')) - self.assertTrue(os.path.exists(os.path.join( - '__pycache__', '{}.{}.py{}'.format( - TESTFN, self.tag, 'c' if __debug__ else 'o')))) + pyc_path = importlib.util.cache_from_source(self.source) + self.assertTrue(os.path.exists(pyc_path), + 'bytecode file {!r} for {!r} does not ' + 'exist'.format(pyc_path, TESTFN)) @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") @@ -673,8 +666,10 @@ class PycacheTests(unittest.TestCase): with temp_umask(0o222): __import__(TESTFN) self.assertTrue(os.path.exists('__pycache__')) - self.assertFalse(os.path.exists(os.path.join( - '__pycache__', '{}.{}.pyc'.format(TESTFN, self.tag)))) + pyc_path = importlib.util.cache_from_source(self.source) + self.assertFalse(os.path.exists(pyc_path), + 'bytecode file {!r} for {!r} ' + 'exists'.format(pyc_path, TESTFN)) @skip_if_dont_write_bytecode def test_missing_source(self): diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 5d35d14..69466b2 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -5,6 +5,7 @@ machinery = util.import_importlib('importlib.machinery') importlib_util = util.import_importlib('importlib.util') import os +import string import sys from test import support import types @@ -562,7 +563,8 @@ class PEP3147Tests: path = os.path.join('foo', 'bar', 'baz', 'qux.py') expect = os.path.join('foo', 'bar', 'baz', '__pycache__', 'qux.{}.pyc'.format(self.tag)) - self.assertEqual(self.util.cache_from_source(path, True), expect) + self.assertEqual(self.util.cache_from_source(path, optimization=''), + expect) def test_cache_from_source_no_cache_tag(self): # No cache tag means NotImplementedError. @@ -575,43 +577,103 @@ class PEP3147Tests: path = os.path.join('foo.bar', 'file') expect = os.path.join('foo.bar', '__pycache__', 'file{}.pyc'.format(self.tag)) - self.assertEqual(self.util.cache_from_source(path, True), expect) + self.assertEqual(self.util.cache_from_source(path, optimization=''), + expect) - def test_cache_from_source_optimized(self): - # Given the path to a .py file, return the path to its PEP 3147 - # defined .pyo file (i.e. under __pycache__). + def test_cache_from_source_debug_override(self): + # Given the path to a .py file, return the path to its PEP 3147/PEP 488 + # defined .pyc file (i.e. under __pycache__). path = os.path.join('foo', 'bar', 'baz', 'qux.py') - expect = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyo'.format(self.tag)) - self.assertEqual(self.util.cache_from_source(path, False), expect) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + self.assertEqual(self.util.cache_from_source(path, False), + self.util.cache_from_source(path, optimization=1)) + self.assertEqual(self.util.cache_from_source(path, True), + self.util.cache_from_source(path, optimization='')) + with warnings.catch_warnings(): + warnings.simplefilter('error') + with self.assertRaises(DeprecationWarning): + self.util.cache_from_source(path, False) + with self.assertRaises(DeprecationWarning): + self.util.cache_from_source(path, True) def test_cache_from_source_cwd(self): path = 'foo.py' expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag)) - self.assertEqual(self.util.cache_from_source(path, True), expect) + self.assertEqual(self.util.cache_from_source(path, optimization=''), + expect) def test_cache_from_source_override(self): # When debug_override is not None, it can be any true-ish or false-ish # value. path = os.path.join('foo', 'bar', 'baz.py') - partial_expect = os.path.join('foo', 'bar', '__pycache__', - 'baz.{}.py'.format(self.tag)) - self.assertEqual(self.util.cache_from_source(path, []), partial_expect + 'o') - self.assertEqual(self.util.cache_from_source(path, [17]), - partial_expect + 'c') # However if the bool-ishness can't be determined, the exception # propagates. class Bearish: def __bool__(self): raise RuntimeError - with self.assertRaises(RuntimeError): - self.util.cache_from_source('/foo/bar/baz.py', Bearish()) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + self.assertEqual(self.util.cache_from_source(path, []), + self.util.cache_from_source(path, optimization=1)) + self.assertEqual(self.util.cache_from_source(path, [17]), + self.util.cache_from_source(path, optimization='')) + with self.assertRaises(RuntimeError): + self.util.cache_from_source('/foo/bar/baz.py', Bearish()) + + + def test_cache_from_source_optimization_empty_string(self): + # Setting 'optimization' to '' leads to no optimization tag (PEP 488). + path = 'foo.py' + expect = os.path.join('__pycache__', 'foo.{}.pyc'.format(self.tag)) + self.assertEqual(self.util.cache_from_source(path, optimization=''), + expect) + + def test_cache_from_source_optimization_None(self): + # Setting 'optimization' to None uses the interpreter's optimization. + # (PEP 488) + path = 'foo.py' + optimization_level = sys.flags.optimize + almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag)) + if optimization_level == 0: + expect = almost_expect + '.pyc' + elif optimization_level <= 2: + expect = almost_expect + '.opt-{}.pyc'.format(optimization_level) + else: + msg = '{!r} is a non-standard optimization level'.format(optimization_level) + self.skipTest(msg) + self.assertEqual(self.util.cache_from_source(path, optimization=None), + expect) + + def test_cache_from_source_optimization_set(self): + # The 'optimization' parameter accepts anything that has a string repr + # that passes str.alnum(). + path = 'foo.py' + valid_characters = string.ascii_letters + string.digits + almost_expect = os.path.join('__pycache__', 'foo.{}'.format(self.tag)) + got = self.util.cache_from_source(path, optimization=valid_characters) + # Test all valid characters are accepted. + self.assertEqual(got, + almost_expect + '.opt-{}.pyc'.format(valid_characters)) + # str() should be called on argument. + self.assertEqual(self.util.cache_from_source(path, optimization=42), + almost_expect + '.opt-42.pyc') + # Invalid characters raise ValueError. + with self.assertRaises(ValueError): + self.util.cache_from_source(path, optimization='path/is/bad') + + def test_cache_from_source_debug_override_optimization_both_set(self): + # Can only set one of the optimization-related parameters. + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + with self.assertRaises(TypeError): + self.util.cache_from_source('foo.py', False, optimization='') @unittest.skipUnless(os.sep == '\\' and os.altsep == '/', 'test meaningful only where os.altsep is defined') def test_sep_altsep_and_sep_cache_from_source(self): # Windows path and PEP 3147 where sep is right of altsep. self.assertEqual( - self.util.cache_from_source('\\foo\\bar\\baz/qux.py', True), + self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''), '\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag)) @unittest.skipUnless(sys.implementation.cache_tag is not None, @@ -649,7 +711,12 @@ class PEP3147Tests: ValueError, self.util.source_from_cache, '__pycache__/foo.pyc') def test_source_from_cache_too_many_dots(self): - # Too many dots in final path component -> ValueError + with self.assertRaises(ValueError): + self.util.source_from_cache( + '__pycache__/foo.cpython-32.opt-1.foo.pyc') + + def test_source_from_cache_not_opt(self): + # Non-`opt-` path component -> ValueError self.assertRaises( ValueError, self.util.source_from_cache, '__pycache__/foo.cpython-32.foo.pyc') @@ -660,6 +727,17 @@ class PEP3147Tests: ValueError, self.util.source_from_cache, '/foo/bar/foo.cpython-32.foo.pyc') + def test_source_from_cache_optimized_bytecode(self): + # Optimized bytecode is not an issue. + path = os.path.join('__pycache__', 'foo.{}.opt-1.pyc'.format(self.tag)) + self.assertEqual(self.util.source_from_cache(path), 'foo.py') + + def test_source_from_cache_missing_optimization(self): + # An empty optimization level is a no-no. + path = os.path.join('__pycache__', 'foo.{}.opt-.pyc'.format(self.tag)) + with self.assertRaises(ValueError): + self.util.source_from_cache(path) + (Frozen_PEP3147Tests, Source_PEP3147Tests diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 1abea27..bff35db 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -119,6 +119,10 @@ class PyCompileTests(unittest.TestCase): self.assertTrue(os.path.exists(cache_path)) self.assertFalse(os.path.exists(pyc_path)) + def test_optimization_path(self): + # Specifying optimized bytecode should lead to a path reflecting that. + self.assertIn('opt-2', py_compile.compile(self.source_path, optimize=2)) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 786b813..3884734 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -269,7 +269,7 @@ class RunModuleTestCase(unittest.TestCase, CodeExecutionMixin): if verbose > 1: print(ex) # Persist with cleaning up def _fix_ns_for_legacy_pyc(self, ns, alter_sys): - char_to_add = "c" if __debug__ else "o" + char_to_add = "c" ns["__file__"] += char_to_add ns["__cached__"] = ns["__file__"] spec = ns["__spec__"] diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 05bf274..2f2c584 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -13,8 +13,8 @@ from test.tracedmodules import testmod #------------------------------- Utilities -----------------------------------# def fix_ext_py(filename): - """Given a .pyc/.pyo filename converts it to the appropriate .py""" - if filename.endswith(('.pyc', '.pyo')): + """Given a .pyc filename converts it to the appropriate .py""" + if filename.endswith('.pyc'): filename = filename[:-1] return filename diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 19d3fd8..9382c48 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -660,11 +660,9 @@ class TestFilters(unittest.TestCase): self.assertFalse(fnmatch('abcdd', 'a*c*e')) self.assertFalse(fnmatch('abcbdefef', 'a*bd*eg')) - # replace .pyc and .pyo suffix with .py + # replace .pyc suffix with .py self.assertTrue(fnmatch('a.pyc', 'a.py')) - self.assertTrue(fnmatch('a.pyo', 'a.py')) self.assertTrue(fnmatch('a.py', 'a.pyc')) - self.assertTrue(fnmatch('a.py', 'a.pyo')) if os.name == 'nt': # case insensitive @@ -674,7 +672,6 @@ class TestFilters(unittest.TestCase): self.assertTrue(fnmatch('a.pyc', 'a.PY')) self.assertTrue(fnmatch('a.PYO', 'a.py')) self.assertTrue(fnmatch('a.py', 'a.PYC')) - self.assertTrue(fnmatch('a.PY', 'a.pyo')) else: # case sensitive self.assertFalse(fnmatch('aBC', 'ABc')) @@ -683,7 +680,6 @@ class TestFilters(unittest.TestCase): self.assertFalse(fnmatch('a.pyc', 'a.PY')) self.assertFalse(fnmatch('a.PYO', 'a.py')) self.assertFalse(fnmatch('a.py', 'a.PYC')) - self.assertFalse(fnmatch('a.PY', 'a.pyo')) if os.name == 'nt': # normalize alternate separator "/" to the standard separator "\" diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 1b2dc85..aa8c463 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -689,7 +689,7 @@ class PyZipFileTests(unittest.TestCase): self.requiresWriteAccess(os.path.dirname(__file__)) with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: fn = __file__ - if fn.endswith('.pyc') or fn.endswith('.pyo'): + if fn.endswith('.pyc'): path_split = fn.split(os.sep) if os.altsep is not None: path_split.extend(fn.split(os.altsep)) @@ -706,7 +706,7 @@ class PyZipFileTests(unittest.TestCase): with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: fn = __file__ - if fn.endswith(('.pyc', '.pyo')): + if fn.endswith('.pyc'): fn = fn[:-1] zipfp.writepy(fn, "testpackage") @@ -762,10 +762,8 @@ class PyZipFileTests(unittest.TestCase): import email packagedir = os.path.dirname(email.__file__) self.requiresWriteAccess(packagedir) - # use .pyc if running test in optimization mode, - # use .pyo if running test in debug mode optlevel = 1 if __debug__ else 0 - ext = '.pyo' if optlevel == 1 else '.pyc' + ext = '.pyc' with TemporaryFile() as t, \ zipfile.PyZipFile(t, "w", optimize=optlevel) as zipfp: @@ -839,11 +837,10 @@ class PyZipFileTests(unittest.TestCase): self.assertIn("SyntaxError", s.getvalue()) # as it will not have compiled the python file, it will - # include the .py file not .pyc or .pyo + # include the .py file not .pyc names = zipfp.namelist() self.assertIn('mod1.py', names) self.assertNotIn('mod1.pyc', names) - self.assertNotIn('mod1.pyo', names) finally: rmtree(TESTFN2) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 0a83841..a97a778 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -51,7 +51,7 @@ TESTPACK2 = "ziptestpackage2" TEMP_ZIP = os.path.abspath("junk95142.zip") pyc_file = importlib.util.cache_from_source(TESTMOD + '.py') -pyc_ext = ('.pyc' if __debug__ else '.pyo') +pyc_ext = '.pyc' class ImportHooksBaseTestCase(unittest.TestCase): |