From 925a9bf6e6e01cc80a87a584a0b7cc7c6a07b17a Mon Sep 17 00:00:00 2001 From: Marin Date: Mon, 4 Apr 2022 19:20:26 +0200 Subject: [PATCH 01/11] add mtime to gzip.open --- Lib/gzip.py | 6 +++--- Lib/test/test_gzip.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Lib/gzip.py b/Lib/gzip.py index 6773ea3eef0971..984a8a09e25dda 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -23,7 +23,7 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, - encoding=None, errors=None, newline=None): + encoding=None, errors=None, newline=None, mtime=None): """Open a gzip-compressed file in binary or text mode. The filename argument can be an actual filename (a str or bytes object), or @@ -55,9 +55,9 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, gz_mode = mode.replace("t", "") if isinstance(filename, (str, bytes, os.PathLike)): - binary_file = GzipFile(filename, gz_mode, compresslevel) + binary_file = GzipFile(filename, gz_mode, compresslevel, mtime=mtime) elif hasattr(filename, "read") or hasattr(filename, "write"): - binary_file = GzipFile(None, gz_mode, compresslevel, filename) + binary_file = GzipFile(None, gz_mode, compresslevel, filename, mtime=mtime) else: raise TypeError("filename must be a str or bytes object, or a file") diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 497e66cd553b7f..f0e3e9c9d2cdaa 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -314,6 +314,17 @@ def test_mtime(self): self.assertEqual(dataRead, data1) self.assertEqual(fRead.mtime, mtime) + def test_mtime_with_open(self): + mtime = 123456789 + with gzip.open(self.filename, "w", mtime = mtime) as fWrite: + fWrite.write(data1) + with gzip.open(self.filename, "rb") as fRead: + self.assertTrue(hasattr(fRead, 'mtime')) + self.assertIsNone(fRead.mtime) + dataRead = fRead.read() + self.assertEqual(dataRead, data1) + self.assertEqual(fRead.mtime, mtime) + def test_metadata(self): mtime = 123456789 From 7372cb50de5aeec8b2ba900f9cc8d96f8185da85 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 4 Apr 2022 17:58:06 +0000 Subject: [PATCH 02/11] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst diff --git a/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst new file mode 100644 index 00000000000000..2bd2b9ae56405a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst @@ -0,0 +1,2 @@ +Added a mtime option to gzip open(). +open() didn't have it, while init of class GzipFile has mtime as an optional argument. From 4eb867891f18a3f0b9597523191412750284386b Mon Sep 17 00:00:00 2001 From: Marin Date: Sat, 30 Mar 2024 12:01:07 +0100 Subject: [PATCH 03/11] update docs for adding mtime to gzip open and add reviews --- Doc/library/gzip.rst | 2 +- Doc/whatsnew/3.13.rst | 7 +++++++ Lib/gzip.py | 2 +- Lib/test/test_gzip.py | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 044be8c1c1bf41..9dec3b8a944ff3 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -26,7 +26,7 @@ Note that additional file formats which can be decompressed by the The module defines the following items: -.. function:: open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None) +.. function:: open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None, *, mtime=None) Open a gzip-compressed file in binary or text mode, returning a :term:`file object`. diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index f50364a7ddcc2a..2a9fd23e3035dd 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -393,6 +393,13 @@ glob shell-style wildcards to a regular expression. (Contributed by Barney Gale in :gh:`72904`.) +gzip +--- + +* :func:`gzip.open` now accepts an optional argument ``mtime`` + which is passed on to the init constructor of the GzipFile class. + (Contributed by Marin Misur in :gh:`91372`.) + io -- diff --git a/Lib/gzip.py b/Lib/gzip.py index 02bd570e1add45..aa9e0f481bd55c 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -26,7 +26,7 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, - encoding=None, errors=None, newline=None, mtime=None): + encoding=None, errors=None, newline=None, *, mtime=None): """Open a gzip-compressed file in binary or text mode. The filename argument can be an actual filename (a str or bytes object), or diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index b41c89d0215b88..12bf612c751f57 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -318,7 +318,7 @@ def test_mtime(self): def test_mtime_with_open(self): mtime = 123456789 - with gzip.open(self.filename, "w", mtime = mtime) as fWrite: + with gzip.open(self.filename, "wb", mtime=mtime) as fWrite: fWrite.write(data1) with gzip.open(self.filename, "rb") as fRead: self.assertTrue(hasattr(fRead, 'mtime')) From 389ccdef5eaee8b6f6e4bbaa3ef7e95215b60a6c Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 09:20:51 +0200 Subject: [PATCH 04/11] Update 3.16.rst --- Doc/whatsnew/3.16.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 2e5342e4f02053..b10c25a845a4ba 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -85,6 +85,12 @@ New modules Improved modules ================ +gzip +--- + +* :func:`gzip.open` now accepts an optional argument ``mtime`` + which is passed on to the init constructor of the GzipFile class. + (Contributed by Marin Misur in :gh:`91372`.) os -- From bb1b4b51aa37543c03a24d35d0932338c3c65a38 Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 09:22:16 +0200 Subject: [PATCH 05/11] Update 3.16.rst formating --- Doc/whatsnew/3.16.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index b10c25a845a4ba..f8d9c9ddb8618b 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -85,6 +85,8 @@ New modules Improved modules ================ + + gzip --- From a92c1c7c14226d693de7b6b213983ac694001830 Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 09:23:25 +0200 Subject: [PATCH 06/11] Update 3.16.rst formating --- Doc/whatsnew/3.16.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index f8d9c9ddb8618b..a72a6f0df8bf85 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -88,7 +88,7 @@ Improved modules gzip ---- +---- * :func:`gzip.open` now accepts an optional argument ``mtime`` which is passed on to the init constructor of the GzipFile class. From e121a633cc28a903b26e47a7f00bd64893ce8d98 Mon Sep 17 00:00:00 2001 From: Marin Date: Fri, 22 May 2026 09:42:22 +0200 Subject: [PATCH 07/11] update Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst --- .../next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst index 2bd2b9ae56405a..276ace8bf6120c 100644 --- a/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst +++ b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst @@ -1,2 +1,2 @@ -Added a mtime option to gzip open(). +Added a mtime option to gzip open(). open() didn't have it, while init of class GzipFile has mtime as an optional argument. From b9bffb59bb5ade58ecc0201389675ea5119195b4 Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 11:57:01 +0200 Subject: [PATCH 08/11] Update according to review requests. --- Doc/library/gzip.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 19e0c4cfe79c6a..4453d7549547d9 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -43,8 +43,10 @@ The module defines the following items: The *compresslevel* argument is an integer from 0 to 9, as for the :class:`GzipFile` constructor. + The keyword-only argument *mtime* represents a Unix timestamp. + For binary mode, this function is equivalent to the :class:`GzipFile` - constructor: ``GzipFile(filename, mode, compresslevel)``. In this case, the + constructor: ``GzipFile(filename, mode, compresslevel, mtime)``. In this case, the *encoding*, *errors* and *newline* arguments must not be provided. For text mode, a :class:`GzipFile` object is created, and wrapped in an @@ -66,6 +68,10 @@ The module defines the following items: It is the default level used by most compression tools and a better tradeoff between speed and performance. + .. versionchanged:: 3.16 + Added keyword-only argument *mtime* which is passed to the class + constructor of :class:`~gzip.GzipFile`. + .. exception:: BadGzipFile An exception raised for invalid gzip files. It inherits from :exc:`OSError`. From 18af009b775fbc03716359974fdbf4fba32ae7f8 Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 11:57:42 +0200 Subject: [PATCH 09/11] Apply suggestions from code review Co-authored-by: Serhiy Storchaka --- Doc/whatsnew/3.16.rst | 2 +- Lib/gzip.py | 3 ++- .../next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index a72a6f0df8bf85..f1ff4fcf9bafde 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -91,7 +91,7 @@ gzip ---- * :func:`gzip.open` now accepts an optional argument ``mtime`` - which is passed on to the init constructor of the GzipFile class. + which is passed on to the constructor of the :class:`~gzip.GzipFile` class. (Contributed by Marin Misur in :gh:`91372`.) os diff --git a/Lib/gzip.py b/Lib/gzip.py index 7ce1b1c08ac9b3..b3bae3e8636e65 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -65,7 +65,8 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_TRADEOFF, if isinstance(filename, (str, bytes, os.PathLike)): binary_file = GzipFile(filename, gz_mode, compresslevel, mtime=mtime) elif hasattr(filename, "read") or hasattr(filename, "write"): - binary_file = GzipFile(None, gz_mode, compresslevel, filename, mtime=mtime) + binary_file = GzipFile(None, gz_mode, compresslevel, filename, + mtime=mtime) else: raise TypeError("filename must be a str or bytes object, or a file") diff --git a/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst index 276ace8bf6120c..066e17c1c6e06a 100644 --- a/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst +++ b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst @@ -1,2 +1,2 @@ -Added a mtime option to gzip open(). -open() didn't have it, while init of class GzipFile has mtime as an optional argument. +Added *mtime* option to :func:`gzip.open`, which will be passed +to the constructor of :class:`~gzip.GzipFile`. From ab6ba39c93fa8d7121822c5f0074a9c0c3b8e29e Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 12:42:19 +0200 Subject: [PATCH 10/11] Reviewer's doc improvements. Co-authored-by: Serhiy Storchaka --- Doc/library/gzip.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 4453d7549547d9..4675cde280e75d 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -68,7 +68,7 @@ The module defines the following items: It is the default level used by most compression tools and a better tradeoff between speed and performance. - .. versionchanged:: 3.16 + .. versionchanged:: next Added keyword-only argument *mtime* which is passed to the class constructor of :class:`~gzip.GzipFile`. From 33d07f4a20aee6c0e9c66e6c6c992f1c902973f9 Mon Sep 17 00:00:00 2001 From: Marin Misur <50244077+ellaellela@users.noreply.github.com> Date: Fri, 22 May 2026 12:44:56 +0200 Subject: [PATCH 11/11] Reviewer's improvements. --- Doc/library/gzip.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 4675cde280e75d..9211e5f18c6b6e 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -46,8 +46,9 @@ The module defines the following items: The keyword-only argument *mtime* represents a Unix timestamp. For binary mode, this function is equivalent to the :class:`GzipFile` - constructor: ``GzipFile(filename, mode, compresslevel, mtime)``. In this case, the - *encoding*, *errors* and *newline* arguments must not be provided. + constructor: ``GzipFile(filename, mode, compresslevel, mtime=mtime)``. + In this case, the *encoding*, *errors* and *newline* arguments must not + be provided. For text mode, a :class:`GzipFile` object is created, and wrapped in an :class:`io.TextIOWrapper` instance with the specified encoding, error