Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3452)

Unified Diff: Lib/packaging/tests/support.py

Issue 13473: Add tests for files byte-compiled by distutils[2]
Patch Set: Created 1 year, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Doc/library/packaging.util.rst ('k') | Lib/packaging/tests/test_command_build_py.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Lib/packaging/tests/support.py
+++ b/Lib/packaging/tests/support.py
@@ -38,7 +38,9 @@ import shutil
import logging
import weakref
import tempfile
+import textwrap
import sysconfig
+from subprocess import Popen, PIPE
from packaging.dist import Distribution
from packaging.util import resolve_name
@@ -56,6 +58,8 @@ __all__ = [
# misc. functions and decorators
'fake_dec', 'create_distribution', 'use_command',
'copy_xxmodule_c', 'fixup_build_ext',
+ # functions used in byte-compilation tests
+ 'create_py_module', 'check_pyc_file', 'check_pyo_file',
# imported from this module for backport purposes
'unittest', 'requires_zlib', 'skip_2to3_optimize', 'skip_unless_symlink',
]
@@ -381,6 +385,88 @@ def fixup_build_ext(cmd):
cmd.library_dirs = value.split(os.pathsep)
+def create_py_module(filename):
+ """Create a Python module suitable for some tests.
+
+ *filename* is a string containing the filename to write to.
+ This function should be used with check_pyc_file and check_pyo_file,
+ see test_command_build_py.py for an example.
+ """
+ # The documentation of -O mode is quite brief; experimentation + source
+ # code reading (Py_OptimizeFlag then c_optimize in Python/compile.c)
+ # find these optimizations: -O sets __debug__ to False and disables
+ # asserts, -OO also sets __doc__ attributes to None. The following code
+ # exercises all of these things.
+ with open(filename, 'w') as fp:
+ fp.write(textwrap.dedent('''\
+ """Module docstring."""
+
+ print('debug:', __debug__)
+
+ try:
+ assert False
+ except AssertionError:
+ print('assertion: failed as expected')
+ else:
+ print('assertion: disabled')
+
+ print('docstring:', __doc__)
+ '''))
+
+
+def check_pyc_file(testcase, modname, basedir):
+ """Make sure that a pyc file is compiled with optimization off.
+
+ *testcase* should be a unittest.TestCase instance. *modname* is the
+ name of a module for which there exists a .pyc file created by
+ byte-compiling a module written by create_py_module. *basedir* is
+ the parent directory of the .py file.
+ """
+ # using a subprocess to avoid module caching issues and to be independent
+ # of the calling Python's -O option -> we can call check_pyc_file and
+ # check_pyo_file in a row, from a Python started with or without -O
+ with Popen([sys.executable, '-E', '-m', modname], cwd=basedir,
+ stdout=PIPE, stderr=PIPE) as process:
+ output = process.stdout.read()
+
+ output = output.decode('ascii').splitlines()
+ testcase.assertEqual(process.returncode, 0)
+ testcase.assertEqual(output, ['debug: True',
+ 'assertion: failed as expected',
+ 'docstring: Module docstring.'])
+
+
+def check_pyo_file(testcase, modname, basedir, level):
+ """Make sure that a pyo file is compiled with the right optimizations.
+
+ *level* should be 1 or 2 (matching python -O or -OO). See
+ check_pyc_file for the other arguments.
+ """
+ if level == 1:
+ flag = '-O'
+ docstring = 'docstring: Module docstring.'
+ elif level == 2:
+ flag = '-OO'
+ docstring = 'docstring: None'
+ else:
+ raise ValueError('level must be 1 or 2, not %r' % level)
+
+ # an existing .pyc file is not considered for import, but if there is a
+ # .pyo file created with -O, a call with -OO will not recreate it, so
+ # pay attention to byte-compilation when writing tests (i.e. use different
+ # methods or module names to test code with different optimization levels)
+
+ with Popen([sys.executable, '-E', flag, '-m', modname], cwd=basedir,
+ stdout=PIPE, stderr=PIPE) as process:
+ output = process.stdout.read()
+
+ output = output.decode('ascii').splitlines()
+ testcase.assertEqual(process.returncode, 0)
+ testcase.assertEqual(output, ['debug: False',
+ 'assertion: disabled',
+ docstring])
+
+
try:
from test.support import skip_unless_symlink
except ImportError:
« no previous file with comments | « Doc/library/packaging.util.rst ('k') | Lib/packaging/tests/test_command_build_py.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7