summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/py_compile.rst7
-rw-r--r--Lib/py_compile.py2
-rw-r--r--Lib/test/test_py_compile.py12
-rw-r--r--Misc/NEWS.d/next/Build/2018-01-16-08-32-49.bpo-29708.YCaHEx.rst2
4 files changed, 22 insertions, 1 deletions
diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst
index a4f06de..d720e01 100644
--- a/Doc/library/py_compile.rst
+++ b/Doc/library/py_compile.rst
@@ -55,7 +55,9 @@ byte-code cache files in the directory containing the source code.
*invalidation_mode* should be a member of the :class:`PycInvalidationMode`
enum and controls how the generated ``.pyc`` files are invalidated at
- runtime.
+ runtime. If the :envvar:`SOURCE_DATE_EPOCH` environment variable is set,
+ *invalidation_mode* will be forced to
+ :attr:`PycInvalidationMode.CHECKED_HASH`.
.. versionchanged:: 3.2
Changed default value of *cfile* to be :PEP:`3147`-compliant. Previous
@@ -71,6 +73,9 @@ byte-code cache files in the directory containing the source code.
.. versionchanged:: 3.7
The *invalidation_mode* parameter was added as specified in :pep:`552`.
+ If the :envvar:`SOURCE_DATE_EPOCH` environment variable is set,
+ *invalidation_mode* will be forced to
+ :attr:`PycInvalidationMode.CHECKED_HASH`.
.. class:: PycInvalidationMode
diff --git a/Lib/py_compile.py b/Lib/py_compile.py
index a0f4def..16dc0a0 100644
--- a/Lib/py_compile.py
+++ b/Lib/py_compile.py
@@ -112,6 +112,8 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
the resulting file would be regular and thus not the same type of file as
it was previously.
"""
+ if os.environ.get('SOURCE_DATE_EPOCH'):
+ invalidation_mode = PycInvalidationMode.CHECKED_HASH
if cfile is None:
if optimize >= 0:
optimization = optimize if optimize >= 1 else ''
diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py
index bcb686c..8fc0b33 100644
--- a/Lib/test/test_py_compile.py
+++ b/Lib/test/test_py_compile.py
@@ -98,6 +98,18 @@ class PyCompileTests(unittest.TestCase):
self.assertFalse(os.path.exists(
importlib.util.cache_from_source(bad_coding)))
+ def test_source_date_epoch(self):
+ testtime = 123456789
+ with support.EnvironmentVarGuard() as env:
+ env["SOURCE_DATE_EPOCH"] = str(testtime)
+ py_compile.compile(self.source_path, self.pyc_path)
+ self.assertTrue(os.path.exists(self.pyc_path))
+ self.assertFalse(os.path.exists(self.cache_path))
+ with open(self.pyc_path, 'rb') as fp:
+ flags = importlib._bootstrap_external._classify_pyc(
+ fp.read(), 'test', {})
+ self.assertEqual(flags, 0b11)
+
@unittest.skipIf(sys.flags.optimize > 0, 'test does not work with -O')
def test_double_dot_no_clobber(self):
# http://bugs.python.org/issue22966
diff --git a/Misc/NEWS.d/next/Build/2018-01-16-08-32-49.bpo-29708.YCaHEx.rst b/Misc/NEWS.d/next/Build/2018-01-16-08-32-49.bpo-29708.YCaHEx.rst
new file mode 100644
index 0000000..e52c001
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2018-01-16-08-32-49.bpo-29708.YCaHEx.rst
@@ -0,0 +1,2 @@
+If the :envvar:`SOURCE_DATE_EPOCH` environment variable is set,
+:mod:`py_compile` will always create hash-based ``.pyc`` files.