summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/compileall.py7
-rw-r--r--Lib/distutils/command/build_py.py4
-rw-r--r--Lib/distutils/command/install_lib.py16
-rw-r--r--Lib/distutils/tests/test_build_py.py4
-rw-r--r--Lib/distutils/tests/test_install_lib.py13
-rw-r--r--Lib/distutils/util.py9
-rw-r--r--Lib/doctest.py4
-rw-r--r--Lib/imp.py19
-rw-r--r--Lib/importlib/_bootstrap.py78
-rw-r--r--Lib/modulefinder.py2
-rw-r--r--Lib/msilib/__init__.py7
-rw-r--r--Lib/py_compile.py11
-rwxr-xr-xLib/pydoc.py2
-rw-r--r--Lib/test/support/__init__.py20
-rw-r--r--Lib/test/test_compile.py2
-rw-r--r--Lib/test/test_compileall.py21
-rw-r--r--Lib/test/test_imp.py115
-rw-r--r--Lib/test/test_import/__init__.py37
-rw-r--r--Lib/test/test_importlib/test_util.py114
-rw-r--r--Lib/test/test_py_compile.py4
-rw-r--r--Lib/test/test_runpy.py2
-rw-r--r--Lib/test/test_trace.py4
-rw-r--r--Lib/test/test_tracemalloc.py6
-rw-r--r--Lib/test/test_zipfile.py11
-rw-r--r--Lib/test/test_zipimport.py2
-rw-r--r--Lib/tkinter/__init__.py2
-rw-r--r--Lib/tkinter/test/runtktests.py2
-rwxr-xr-xLib/trace.py2
-rw-r--r--Lib/tracemalloc.py2
-rw-r--r--Lib/unittest/loader.py4
-rw-r--r--Lib/warnings.py2
-rw-r--r--Lib/zipfile.py57
32 files changed, 288 insertions, 297 deletions
diff --git a/Lib/compileall.py b/Lib/compileall.py
index 4f46920..aeaaf8e 100644
--- a/Lib/compileall.py
+++ b/Lib/compileall.py
@@ -1,4 +1,4 @@
-"""Module/script to byte-compile all .py files to .pyc (or .pyo) files.
+"""Module/script to byte-compile all .py files to .pyc files.
When called as a script with arguments, this compiles the directories
given as arguments recursively; the -l option prevents it from
@@ -118,11 +118,12 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
return success
if os.path.isfile(fullname):
if legacy:
- cfile = fullname + ('c' if __debug__ else 'o')
+ cfile = fullname + 'c'
else:
if optimize >= 0:
+ opt = optimize if optimize >= 1 else ''
cfile = importlib.util.cache_from_source(
- fullname, debug_override=not optimize)
+ fullname, optimization=opt)
else:
cfile = importlib.util.cache_from_source(fullname)
cache_dir = os.path.dirname(cfile)
diff --git a/Lib/distutils/command/build_py.py b/Lib/distutils/command/build_py.py
index 9100b96..cf0ca57 100644
--- a/Lib/distutils/command/build_py.py
+++ b/Lib/distutils/command/build_py.py
@@ -314,10 +314,10 @@ class build_py (Command):
if include_bytecode:
if self.compile:
outputs.append(importlib.util.cache_from_source(
- filename, debug_override=True))
+ filename, optimization=''))
if self.optimize > 0:
outputs.append(importlib.util.cache_from_source(
- filename, debug_override=False))
+ filename, optimization=self.optimize))
outputs += [
os.path.join(build_dir, filename)
diff --git a/Lib/distutils/command/install_lib.py b/Lib/distutils/command/install_lib.py
index 215813b..6154cf0 100644
--- a/Lib/distutils/command/install_lib.py
+++ b/Lib/distutils/command/install_lib.py
@@ -22,15 +22,15 @@ class install_lib(Command):
# possible scenarios:
# 1) no compilation at all (--no-compile --no-optimize)
# 2) compile .pyc only (--compile --no-optimize; default)
- # 3) compile .pyc and "level 1" .pyo (--compile --optimize)
- # 4) compile "level 1" .pyo only (--no-compile --optimize)
- # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more)
- # 6) compile "level 2" .pyo only (--no-compile --optimize-more)
+ # 3) compile .pyc and "opt-1" .pyc (--compile --optimize)
+ # 4) compile "opt-1" .pyc only (--no-compile --optimize)
+ # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more)
+ # 6) compile "opt-2" .pyc only (--no-compile --optimize-more)
#
- # The UI for this is two option, 'compile' and 'optimize'.
+ # The UI for this is two options, 'compile' and 'optimize'.
# 'compile' is strictly boolean, and only decides whether to
# generate .pyc files. 'optimize' is three-way (0, 1, or 2), and
- # decides both whether to generate .pyo files and what level of
+ # decides both whether to generate .pyc files and what level of
# optimization to use.
user_options = [
@@ -166,10 +166,10 @@ class install_lib(Command):
continue
if self.compile:
bytecode_files.append(importlib.util.cache_from_source(
- py_file, debug_override=True))
+ py_file, optimization=''))
if self.optimize > 0:
bytecode_files.append(importlib.util.cache_from_source(
- py_file, debug_override=False))
+ py_file, optimization=self.optimize))
return bytecode_files
diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py
index c8f6b89..18283dc 100644
--- a/Lib/distutils/tests/test_build_py.py
+++ b/Lib/distutils/tests/test_build_py.py
@@ -120,8 +120,8 @@ class BuildPyTestCase(support.TempdirManager,
found = os.listdir(cmd.build_lib)
self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py'])
found = os.listdir(os.path.join(cmd.build_lib, '__pycache__'))
- self.assertEqual(sorted(found),
- ['boiledeggs.%s.pyo' % sys.implementation.cache_tag])
+ expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag)
+ self.assertEqual(sorted(found), [expect])
def test_dir_in_package_data(self):
"""
diff --git a/Lib/distutils/tests/test_install_lib.py b/Lib/distutils/tests/test_install_lib.py
index 40dd1a9..5378aa8 100644
--- a/Lib/distutils/tests/test_install_lib.py
+++ b/Lib/distutils/tests/test_install_lib.py
@@ -44,12 +44,11 @@ class InstallLibTestCase(support.TempdirManager,
f = os.path.join(project_dir, 'foo.py')
self.write_file(f, '# python file')
cmd.byte_compile([f])
- pyc_file = importlib.util.cache_from_source('foo.py',
- debug_override=True)
- pyo_file = importlib.util.cache_from_source('foo.py',
- debug_override=False)
+ pyc_file = importlib.util.cache_from_source('foo.py', optimization='')
+ pyc_opt_file = importlib.util.cache_from_source('foo.py',
+ optimization=cmd.optimize)
self.assertTrue(os.path.exists(pyc_file))
- self.assertTrue(os.path.exists(pyo_file))
+ self.assertTrue(os.path.exists(pyc_opt_file))
def test_get_outputs(self):
project_dir, dist = self.create_dist()
@@ -66,8 +65,8 @@ class InstallLibTestCase(support.TempdirManager,
cmd.distribution.packages = ['spam']
cmd.distribution.script_name = 'setup.py'
- # get_outputs should return 4 elements: spam/__init__.py, .pyc and
- # .pyo, foo.import-tag-abiflags.so / foo.pyd
+ # get_outputs should return 4 elements: spam/__init__.py and .pyc,
+ # foo.import-tag-abiflags.so / foo.pyd
outputs = cmd.get_outputs()
self.assertEqual(len(outputs), 4, outputs)
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 5adcac5..e423325 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -322,11 +322,11 @@ def byte_compile (py_files,
prefix=None, base_dir=None,
verbose=1, dry_run=0,
direct=None):
- """Byte-compile a collection of Python source files to either .pyc
- or .pyo files in a __pycache__ subdirectory. 'py_files' is a list
+ """Byte-compile a collection of Python source files to .pyc
+ files in a __pycache__ subdirectory. 'py_files' is a list
of files to compile; any files that don't end in ".py" are silently
skipped. 'optimize' must be one of the following:
- 0 - don't optimize (generate .pyc)
+ 0 - don't optimize
1 - normal optimization (like "python -O")
2 - extra optimization (like "python -OO")
If 'force' is true, all files are recompiled regardless of
@@ -438,8 +438,9 @@ byte_compile(files, optimize=%r, force=%r,
# cfile - byte-compiled file
# dfile - purported source filename (same as 'file' by default)
if optimize >= 0:
+ opt = '' if optimize == 0 else optimize
cfile = importlib.util.cache_from_source(
- file, debug_override=not optimize)
+ file, optimization=opt)
else:
cfile = importlib.util.cache_from_source(file)
dfile = file
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 7d5bcf4..96ab0c4 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -1051,7 +1051,7 @@ class DocTestFinder:
filename = None
else:
filename = getattr(module, '__file__', module.__name__)
- if filename[-4:] in (".pyc", ".pyo"):
+ if filename[-4:] == ".pyc":
filename = filename[:-1]
return self._parser.get_doctest(docstring, globs, name,
filename, lineno)
@@ -2378,7 +2378,7 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
continue
if not test.filename:
filename = module.__file__
- if filename[-4:] in (".pyc", ".pyo"):
+ if filename[-4:] == ".pyc":
filename = filename[:-1]
test.filename = filename
suite.addTest(DocTestCase(test, **options))
diff --git a/Lib/imp.py b/Lib/imp.py
index 3e6752a..35c4a69 100644
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -58,24 +58,23 @@ def new_module(name):
def get_magic():
"""**DEPRECATED**
- Return the magic number for .pyc or .pyo files.
+ Return the magic number for .pyc files.
"""
return util.MAGIC_NUMBER
def get_tag():
- """Return the magic tag for .pyc or .pyo files."""
+ """Return the magic tag for .pyc files."""
return sys.implementation.cache_tag
def cache_from_source(path, debug_override=None):
"""**DEPRECATED**
- Given the path to a .py file, return the path to its .pyc/.pyo file.
+ Given the path to a .py file, return the path to its .pyc file.
The .py file does not need to exist; this simply returns the path to the
- .pyc/.pyo file calculated as if the .py file were imported. The extension
- will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo.
+ .pyc file calculated as if the .py file were imported.
If debug_override is not None, then it must be a boolean and is used in
place of sys.flags.optimize.
@@ -83,16 +82,18 @@ def cache_from_source(path, debug_override=None):
If sys.implementation.cache_tag is None then NotImplementedError is raised.
"""
- return util.cache_from_source(path, debug_override)
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore')
+ return util.cache_from_source(path, debug_override)
def source_from_cache(path):
"""**DEPRECATED**
- Given the path to a .pyc./.pyo file, return the path to its .py file.
+ Given the path to a .pyc. file, return the path to its .py file.
- The .pyc/.pyo file does not need to exist; this simply returns the path to
- the .py file calculated to correspond to the .pyc/.pyo file. If path does
+ The .pyc file does not need to exist; this simply returns the path to
+ the .py file calculated to correspond to the .pyc file. If path does
not conform to PEP 3147 format, ValueError will be raised. If
sys.implementation.cache_tag is None then NotImplementedError is raised.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 0ed7cc6..c6019ad 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -429,45 +429,64 @@ MAGIC_NUMBER = (3320).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
+_OPT = 'opt-'
SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed.
-DEBUG_BYTECODE_SUFFIXES = ['.pyc']
-OPTIMIZED_BYTECODE_SUFFIXES = ['.pyo']
+BYTECODE_SUFFIXES = ['.pyc']
+# Deprecated.
+DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES
-def cache_from_source(path, debug_override=None):
- """Given the path to a .py file, return the path to its .pyc/.pyo file.
+def cache_from_source(path, debug_override=None, *, optimization=None):
+ """Given the path to a .py file, return the path to its .pyc file.
The .py file does not need to exist; this simply returns the path to the
- .pyc/.pyo file calculated as if the .py file were imported. The extension
- will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo.
+ .pyc file calculated as if the .py file were imported.
- If debug_override is not None, then it must be a boolean and is used in
- place of sys.flags.optimize.
+ The 'optimization' parameter controls the presumed optimization level of
+ the bytecode file. If 'optimization' is not None, the string representation
+ of the argument is taken and verified to be alphanumeric (else ValueError
+ is raised).
+
+ The debug_override parameter is deprecated. If debug_override is not None,
+ a True value is the same as setting 'optimization' to the empty string
+ while a False value is equivalent to setting 'optimization' to '1'.
If sys.implementation.cache_tag is None then NotImplementedError is raised.
"""
- debug = not sys.flags.optimize if debug_override is None else debug_override
- if debug:
- suffixes = DEBUG_BYTECODE_SUFFIXES
- else:
- suffixes = OPTIMIZED_BYTECODE_SUFFIXES
+ if debug_override is not None:
+ _warnings.warn('the debug_override parameter is deprecated; use '
+ "'optimization' instead", DeprecationWarning)
+ if optimization is not None:
+ message = 'debug_override or optimization must be set to None'
+ raise TypeError(message)
+ optimization = '' if debug_override else 1
head, tail = _path_split(path)
base, sep, rest = tail.rpartition('.')
tag = sys.implementation.cache_tag
if tag is None:
raise NotImplementedError('sys.implementation.cache_tag is None')
- filename = ''.join([(base if base else rest), sep, tag, suffixes[0]])
- return _path_join(head, _PYCACHE, filename)
+ almost_filename = ''.join([(base if base else rest), sep, tag])
+ if optimization is None:
+ if sys.flags.optimize == 0:
+ optimization = ''
+ else:
+ optimization = sys.flags.optimize
+ optimization = str(optimization)
+ if optimization != '':
+ if not optimization.isalnum():
+ raise ValueError('{!r} is not alphanumeric'.format(optimization))
+ almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization)
+ return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0])
def source_from_cache(path):
- """Given the path to a .pyc./.pyo file, return the path to its .py file.
+ """Given the path to a .pyc. file, return the path to its .py file.
- The .pyc/.pyo file does not need to exist; this simply returns the path to
- the .py file calculated to correspond to the .pyc/.pyo file. If path does
- not conform to PEP 3147 format, ValueError will be raised. If
+ The .pyc file does not need to exist; this simply returns the path to
+ the .py file calculated to correspond to the .pyc file. If path does
+ not conform to PEP 3147/488 format, ValueError will be raised. If
sys.implementation.cache_tag is None then NotImplementedError is raised.
"""
@@ -478,9 +497,19 @@ def source_from_cache(path):
if pycache != _PYCACHE:
raise ValueError('{} not bottom-level directory in '
'{!r}'.format(_PYCACHE, path))
- if pycache_filename.count('.') != 2:
- raise ValueError('expected only 2 dots in '
+ dot_count = pycache_filename.count('.')
+ if dot_count not in {2, 3}:
+ raise ValueError('expected only 2 or 3 dots in '
'{!r}'.format(pycache_filename))
+ elif dot_count == 3:
+ optimization = pycache_filename.rsplit('.', 2)[-2]
+ if not optimization.startswith(_OPT):
+ raise ValueError("optimization portion of filename does not start "
+ "with {!r}".format(_OPT))
+ opt_level = optimization[len(_OPT):]
+ if not opt_level.isalnum():
+ raise ValueError("optimization level {!r} is not an alphanumeric "
+ "value".format(optimization))
base_filename = pycache_filename.partition('.')[0]
return _path_join(head, base_filename + SOURCE_SUFFIXES[0])
@@ -2337,15 +2366,10 @@ def _setup(sys_module, _imp_module):
modules, those two modules must be explicitly passed in.
"""
- global _imp, sys, BYTECODE_SUFFIXES
+ global _imp, sys
_imp = _imp_module
sys = sys_module
- if sys.flags.optimize:
- BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES
- else:
- BYTECODE_SUFFIXES = DEBUG_BYTECODE_SUFFIXES
-
# Set up the spec for existing builtin/frozen modules.
module_type = type(sys)
for name, module in sys.modules.items():
diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py
index b778e60..5d2c06d 100644
--- a/Lib/modulefinder.py
+++ b/Lib/modulefinder.py
@@ -223,7 +223,7 @@ class ModuleFinder:
if not m.__path__:
return
modules = {}
- # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"].
+ # 'suffixes' used to be a list hardcoded to [".py", ".pyc"].
# But we must also collect Python extension modules - although
# we cannot separate normal dlls from Python extensions.
suffixes = []
diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py
index d29a593..873560d 100644
--- a/Lib/msilib/__init__.py
+++ b/Lib/msilib/__init__.py
@@ -361,7 +361,7 @@ class Directory:
# [(logical, 0, filehash.IntegerData(1),
# filehash.IntegerData(2), filehash.IntegerData(3),
# filehash.IntegerData(4))])
- # Automatically remove .pyc/.pyo files on uninstall (2)
+ # Automatically remove .pyc files on uninstall (2)
# XXX: adding so many RemoveFile entries makes installer unbelievably
# slow. So instead, we have to use wildcard remove entries
if file.endswith(".py"):
@@ -382,10 +382,9 @@ class Directory:
return files
def remove_pyc(self):
- "Remove .pyc/.pyo files on uninstall"
+ "Remove .pyc files on uninstall"
add_data(self.db, "RemoveFile",
- [(self.component+"c", self.component, "*.pyc", self.logical, 2),
- (self.component+"o", self.component, "*.pyo", self.logical, 2)])
+ [(self.component+"c", self.component, "*.pyc", self.logical, 2)])
class Binary:
def __init__(self, fname):
diff --git a/Lib/py_compile.py b/Lib/py_compile.py
index 1277b93..166c488 100644
--- a/Lib/py_compile.py
+++ b/Lib/py_compile.py
@@ -1,4 +1,4 @@
-"""Routine to "compile" a .py file to a .pyc (or .pyo) file.
+"""Routine to "compile" a .py file to a .pyc file.
This module has intimate knowledge of the format of .pyc files.
"""
@@ -67,7 +67,7 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
:param file: The source file name.
:param cfile: The target byte compiled file name. When not given, this
- defaults to the PEP 3147 location.
+ defaults to the PEP 3147/PEP 488 location.
:param dfile: Purported file name, i.e. the file name that shows up in
error messages. Defaults to the source file name.
:param doraise: Flag indicating whether or not an exception should be
@@ -85,12 +85,12 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
Note that it isn't necessary to byte-compile Python modules for
execution efficiency -- Python itself byte-compiles a module when
it is loaded, and if it can, writes out the bytecode to the
- corresponding .pyc (or .pyo) file.
+ corresponding .pyc file.
However, if a Python installation is shared between users, it is a
good idea to byte-compile all modules upon installation, since
other users may not be able to write in the source directories,
- and thus they won't be able to write the .pyc/.pyo file, and then
+ and thus they won't be able to write the .pyc file, and then
they would be byte-compiling every module each time it is loaded.
This can slow down program start-up considerably.
@@ -105,8 +105,9 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1):
"""
if cfile is None:
if optimize >= 0:
+ optimization = optimize if optimize >= 1 else ''
cfile = importlib.util.cache_from_source(file,
- debug_override=not optimize)
+ optimization=optimization)
else:
cfile = importlib.util.cache_from_source(file)
if os.path.islink(cfile):
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index d77ed00..264e407 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -213,7 +213,7 @@ def classify_class_attrs(object):
def ispackage(path):
"""Guess whether a path refers to a package directory."""
if os.path.isdir(path):
- for ext in ('.py', '.pyc', '.pyo'):
+ for ext in ('.py', '.pyc'):
if os.path.isfile(os.path.join(path, '__init__' + ext)):
return True
return False
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):
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index c8d8061..109e399 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -1852,7 +1852,7 @@ class Tk(Misc, Wm):
import os
baseName = os.path.basename(sys.argv[0])
baseName, ext = os.path.splitext(baseName)
- if ext not in ('.py', '.pyc', '.pyo'):
+ if ext not in ('.py', '.pyc'):
baseName = baseName + ext
interactive = 0
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
diff --git a/Lib/tkinter/test/runtktests.py b/Lib/tkinter/test/runtktests.py
index ccb3755..dbe5e88 100644
--- a/Lib/tkinter/test/runtktests.py
+++ b/Lib/tkinter/test/runtktests.py
@@ -16,7 +16,7 @@ this_dir_path = os.path.abspath(os.path.dirname(__file__))
def is_package(path):
for name in os.listdir(path):
- if name in ('__init__.py', '__init__.pyc', '__init.pyo'):
+ if name in ('__init__.py', '__init__.pyc'):
return True
return False
diff --git a/Lib/trace.py b/Lib/trace.py
index 41eff26..f108266 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -305,7 +305,7 @@ class CoverageResults:
if self.is_ignored_filename(filename):
continue
- if filename.endswith((".pyc", ".pyo")):
+ if filename.endswith(".pyc"):
filename = filename[:-1]
if coverdir is None:
diff --git a/Lib/tracemalloc.py b/Lib/tracemalloc.py
index adedfc5..6288da8 100644
--- a/Lib/tracemalloc.py
+++ b/Lib/tracemalloc.py
@@ -297,7 +297,7 @@ class _Traces(Sequence):
def _normalize_filename(filename):
filename = os.path.normcase(filename)
- if filename.endswith(('.pyc', '.pyo')):
+ if filename.endswith('.pyc'):
filename = filename[:-1]
return filename
diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
index 8a1a2a7..c776f16 100644
--- a/Lib/unittest/loader.py
+++ b/Lib/unittest/loader.py
@@ -14,9 +14,9 @@ from . import case, suite, util
__unittest = True
-# what about .pyc or .pyo (etc)
+# what about .pyc (etc)
# we would need to avoid loading the same tests multiple times
-# from '.py', '.pyc' *and* '.pyo'
+# from '.py', *and* '.pyc'
VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 5ca4b9c..16246b4 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -188,7 +188,7 @@ def warn(message, category=None, stacklevel=1):
filename = globals.get('__file__')
if filename:
fnl = filename.lower()
- if fnl.endswith((".pyc", ".pyo")):
+ if fnl.endswith(".pyc"):
filename = filename[:-1]
else:
if module == "__main__":
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index d545c55..85bdaa9 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -1731,7 +1731,7 @@ class PyZipFile(ZipFile):
the modules into the archive. If pathname is a plain
directory, listdir *.py and enter all modules. Else, pathname
must be a Python *.py file and the module will be put into the
- archive. Added modules are always module.pyo or module.pyc.
+ archive. Added modules are always module.pyc.
This method will compile the module.py into module.pyc if
necessary.
If filterfunc(pathname) is given, it is called with every argument.
@@ -1824,46 +1824,59 @@ class PyZipFile(ZipFile):
file_py = pathname + ".py"
file_pyc = pathname + ".pyc"
- file_pyo = pathname + ".pyo"
- pycache_pyc = importlib.util.cache_from_source(file_py, True)
- pycache_pyo = importlib.util.cache_from_source(file_py, False)
+ pycache_opt0 = importlib.util.cache_from_source(file_py, optimization='')
+ pycache_opt1 = importlib.util.cache_from_source(file_py, optimization=1)
+ pycache_opt2 = importlib.util.cache_from_source(file_py, optimization=2)
if self._optimize == -1:
# legacy mode: use whatever file is present
- if (os.path.isfile(file_pyo) and
- os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime):
- # Use .pyo file.
- arcname = fname = file_pyo
- elif (os.path.isfile(file_pyc) and
+ if (os.path.isfile(file_pyc) and
os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime):
# Use .pyc file.
arcname = fname = file_pyc
- elif (os.path.isfile(pycache_pyc) and
- os.stat(pycache_pyc).st_mtime >= os.stat(file_py).st_mtime):
+ elif (os.path.isfile(pycache_opt0) and
+ os.stat(pycache_opt0).st_mtime >= os.stat(file_py).st_mtime):
# Use the __pycache__/*.pyc file, but write it to the legacy pyc
# file name in the archive.
- fname = pycache_pyc
+ fname = pycache_opt0
arcname = file_pyc
- elif (os.path.isfile(pycache_pyo) and
- os.stat(pycache_pyo).st_mtime >= os.stat(file_py).st_mtime):
- # Use the __pycache__/*.pyo file, but write it to the legacy pyo
+ elif (os.path.isfile(pycache_opt1) and
+ os.stat(pycache_opt1).st_mtime >= os.stat(file_py).st_mtime):
+ # Use the __pycache__/*.pyc file, but write it to the legacy pyc
+ # file name in the archive.
+ fname = pycache_opt1
+ arcname = file_pyc
+ elif (os.path.isfile(pycache_opt2) and
+ os.stat(pycache_opt2).st_mtime >= os.stat(file_py).st_mtime):
+ # Use the __pycache__/*.pyc file, but write it to the legacy pyc
# file name in the archive.
- fname = pycache_pyo
- arcname = file_pyo
+ fname = pycache_opt2
+ arcname = file_pyc
else:
# Compile py into PEP 3147 pyc file.
if _compile(file_py):
- fname = (pycache_pyc if __debug__ else pycache_pyo)
- arcname = (file_pyc if __debug__ else file_pyo)
+ if sys.flags.optimize == 0:
+ fname = pycache_opt0
+ elif sys.flags.optimize == 1:
+ fname = pycache_opt1
+ else:
+ fname = pycache_opt2
+ arcname = file_pyc
else:
fname = arcname = file_py
else:
# new mode: use given optimization level
if self._optimize == 0:
- fname = pycache_pyc
+ fname = pycache_opt0
arcname = file_pyc
else:
- fname = pycache_pyo
- arcname = file_pyo
+ arcname = file_pyc
+ if self._optimize == 1:
+ fname = pycache_opt1
+ elif self._optimize == 2:
+ fname = pycache_opt2
+ else:
+ msg = "invalid value for 'optimize': {!r}".format(self._optimize)
+ raise ValueError(msg)
if not (os.path.isfile(fname) and
os.stat(fname).st_mtime >= os.stat(file_py).st_mtime):
if not _compile(file_py, optimize=self._optimize):