From 37500719d70038919efcd8bccb9febbe72cddf58 Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Thu, 10 Oct 2024 15:11:51 +0200 Subject: [PATCH] gh-125260: gzip: let compress mtime default to 0 this follows GNU gzip, which defaults to store 0 as mtime for compressing stdin, where no file mtime is involved This makes gzip.compress(str) output deterministic by default and greatly helps reproducible builds. --- Doc/library/gzip.rst | 4 +++- Lib/gzip.py | 3 +-- Lib/test/test_gzip.py | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 6b6e158f6eba2c..c2c8f668ea245c 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -184,7 +184,7 @@ The module defines the following items: attribute instead. -.. function:: compress(data, compresslevel=9, *, mtime=None) +.. function:: compress(data, compresslevel=9, *, mtime=0) Compress the *data*, returning a :class:`bytes` object containing the compressed data. *compresslevel* and *mtime* have the same meaning as in @@ -203,6 +203,8 @@ The module defines the following items: .. versionchanged:: 3.13 The gzip header OS byte is guaranteed to be set to 255 when this function is used as was the case in 3.10 and earlier. + .. versionchanged:: 3.14 + The *mtime* parameter now defaults to 0 for reproducible output. .. function:: decompress(data) diff --git a/Lib/gzip.py b/Lib/gzip.py index ba753ce3050dd8..c2c37f4cafa106 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -579,8 +579,7 @@ def _rewind(self): super()._rewind() self._new_member = True - -def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None): +def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=0): """Compress data in one shot and return the compressed string. compresslevel sets the compression level in range of 0-9. diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index ae384c3849d49e..ddb3f7bb4c1635 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -717,6 +717,10 @@ def test_compress_correct_level(self): for mtime in (0, 42): with self.subTest(mtime=mtime): nocompress = gzip.compress(data1, compresslevel=0, mtime=mtime) + if mtime == 0: + # test for gh-125260 + nocompressnomtime = gzip.compress(data1, compresslevel=0) + self.assertEqual(nocompress, nocompressnomtime) yescompress = gzip.compress(data1, compresslevel=1, mtime=mtime) self.assertIn(data1, nocompress) self.assertNotIn(data1, yescompress)