https://github.com/python/cpython/commit/cf5c8c56986873b11e4a17223a5d49080e75eeaa
commit: cf5c8c56986873b11e4a17223a5d49080e75eeaa
branch: main
author: Marin Misur <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-05-22T15:14:25+03:00
summary:

gh-91372: Add mtime to gzip.open() (GH-32310)

files:
A Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst
M Doc/library/gzip.rst
M Doc/whatsnew/3.16.rst
M Lib/gzip.py
M Lib/test/test_gzip.py

diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index 2c667ddc522399c..9211e5f18c6b6e6 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -28,7 +28,7 @@ Note that additional file formats which can be decompressed 
by the
 The module defines the following items:
 
 
-.. function:: open(filename, mode='rb', compresslevel=6, encoding=None, 
errors=None, newline=None)
+.. function:: open(filename, mode='rb', compresslevel=6, encoding=None, 
errors=None, newline=None, *, mtime=None)
 
    Open a gzip-compressed file in binary or text mode, returning a :term:`file
    object`.
@@ -43,9 +43,12 @@ 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
-   *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
@@ -66,6 +69,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:: next
+      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`.
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index 2e5342e4f020534..f1ff4fcf9bafde0 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -86,6 +86,14 @@ New modules
 Improved modules
 ================
 
+
+gzip
+----
+
+* :func:`gzip.open` now accepts an optional argument ``mtime``
+  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 0713b922522ee18..14c47fc86f217a2 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -31,7 +31,7 @@
 
 
 def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_TRADEOFF,
-         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
@@ -63,9 +63,10 @@ def open(filename, mode="rb", 
compresslevel=_COMPRESS_LEVEL_TRADEOFF,
 
     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 cafac9d3c8be6e7..8bc8e507683cb50 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -351,6 +351,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, "wb", 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_mtime_out_of_range(self):
         for mtime in (-1, 2**32):
             with gzip.GzipFile(self.filename, 'w', mtime=mtime) as fWrite:
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 000000000000000..066e17c1c6e06aa
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst
@@ -0,0 +1,2 @@
+Added *mtime* option to :func:`gzip.open`, which will be passed
+to the constructor of :class:`~gzip.GzipFile`.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to