]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91372: Add mtime to gzip.open() (GH-32310)
authorMarin Misur <50244077+ellaellela@users.noreply.github.com>
Fri, 22 May 2026 12:14:25 +0000 (14:14 +0200)
committerGitHub <noreply@github.com>
Fri, 22 May 2026 12:14:25 +0000 (15:14 +0300)
Doc/library/gzip.rst
Doc/whatsnew/3.16.rst
Lib/gzip.py
Lib/test/test_gzip.py
Misc/NEWS.d/next/Library/2022-04-04-17-58-05.bpo-47216.gPyPte.rst [new file with mode: 0644]

index 2c667ddc522399c5c3310cdbcd4e48fa69c977fd..9211e5f18c6b6e69a5dafc0753d04bec97292206 100644 (file)
@@ -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`.
index 2e5342e4f02053431c0744b6e040cb9d44d8e890..f1ff4fcf9bafde0919648c2059502b40c135a5b7 100644 (file)
@@ -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
 --
 
index 0713b922522ee18439932b7e731fcc24b34a872e..14c47fc86f217a26379cdcecfb912c5a5bea7f7f 100644 (file)
@@ -31,7 +31,7 @@ _WRITE_BUFFER_SIZE = 4 * io.DEFAULT_BUFFER_SIZE
 
 
 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")
 
index cafac9d3c8be6e775cbbad0ba831f9deade06c6f..8bc8e507683cb5037fbdf50ebe4231c7ef5c6dcd 100644 (file)
@@ -351,6 +351,17 @@ class TestGzip(BaseTest):
             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 (file)
index 0000000..066e17c
--- /dev/null
@@ -0,0 +1,2 @@
+Added *mtime* option to :func:`gzip.open`, which will be passed
+to the constructor of :class:`~gzip.GzipFile`.