From 2c096b513273a758b446405d9e5efe4860af1036 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Thu, 27 Sep 2018 13:05:14 -0400 Subject: [PATCH] bpo-34022: Stop forcing of hash-based invalidation with SOURCE_DATE_EPOCH Unconditional forcing of ``CHECKED_HASH`` invalidation was introduced in 3.7.0 in bpo-29708. The change is bad, as it unconditionally overrides *invalidation_mode*, even if it was passed as an explicit argument to ``py_compile.compile()`` or ``compileall``. An environment variable should *never* override an explicit argument to a library function. That change leads to multiple test failures if the ``SOURCE_DATE_EPOCH`` environment variable is set. This changes ``py_compile.compile()`` to only look at ``SOURCE_DATE_EPOCH`` if no explicit *invalidation_mode* was specified. I also made various relevant tests run with explicit control over the value of ``SOURCE_DATE_EPOCH``. While looking at this, I noticed that ``zipimport`` does not work with hash-based .pycs _at all_, though I left the fixes for subsequent commits. --- Doc/library/compileall.rst | 11 ++-- Doc/library/py_compile.rst | 13 ++-- Lib/compileall.py | 20 ++++-- Lib/py_compile.py | 13 +++- Lib/test/test_compileall.py | 50 ++++++++++++-- .../test_importlib/source/test_file_loader.py | 15 +++++ Lib/test/test_py_compile.py | 66 +++++++++++++++++-- .../2018-09-27-13-14-15.bpo-34022.E2cl0r.rst | 3 + 8 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-09-27-13-14-15.bpo-34022.E2cl0r.rst --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -92,6 +92,11 @@ byte-code cache files in the directory c .. versionchanged:: 3.8 The *quiet* parameter was added. + .. versionchanged:: 3.7.2 + The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer + overrides the value of the *invalidation_mode* argument, and determines + its default value instead. + .. class:: PycInvalidationMode --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -209,6 +209,21 @@ class CompileallTestsWithoutSourceEpoch( pass + +class CompileallTestsWithSourceEpoch(CompileallTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=True): + pass + + +class CompileallTestsWithoutSourceEpoch(CompileallTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=False): + pass + + class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors to stdout.""" @@ -620,6 +635,21 @@ class CommandLineTestsBase: class CommmandLineTestsWithSourceEpoch(CommandLineTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=True): + pass + + +class CommmandLineTestsNoSourceEpoch(CommandLineTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=False): + pass + + + +class CommmandLineTestsWithSourceEpoch(CommandLineTestsBase, unittest.TestCase, metaclass=SourceDateEpochTestMeta, source_date_epoch=True): --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -22,6 +22,9 @@ from test.support import make_legacy_pyc from test.test_py_compile import without_source_date_epoch from test.test_py_compile import SourceDateEpochTestMeta +from test.test_py_compile import without_source_date_epoch +from test.test_py_compile import SourceDateEpochTestMeta + class SimpleTest(abc.LoaderTests): @@ -363,6 +366,17 @@ class SimpleTest(abc.LoaderTests): class SourceDateEpochTestMeta(SourceDateEpochTestMeta, + type(Source_SimpleTest)): + pass + + +class SourceDateEpoch_SimpleTest(Source_SimpleTest, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=True): + pass + + +class SourceDateEpochTestMeta(SourceDateEpochTestMeta, type(Source_SimpleTest)): pass --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -272,5 +272,19 @@ class PyCompileCLITestCase(unittest.Test self.assertIn(b'No such file or directory', stderr) +class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=True): + pass + + +class PyCompileTestsWithoutSourceEpoch(PyCompileTestsBase, + unittest.TestCase, + metaclass=SourceDateEpochTestMeta, + source_date_epoch=False): + pass + + if __name__ == "__main__": unittest.main() --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-09-27-13-14-15.bpo-34022.E2cl0r.rst @@ -0,0 +1,3 @@ +The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer overrides the +value of the *invalidation_mode* argument to :func:`py_compile.compile`, and +determines its default value instead.