[Python-checkins] [3.12] GH-105808: Fix a regression introduced in GH-101251 (GH-105910) (#105920)

Yhg1s webhook-mailer at python.org
Mon Jun 19 13:42:27 EDT 2023


https://github.com/python/cpython/commit/225cc4c043aca472f0c7c78bed1a7524fae5c278
commit: 225cc4c043aca472f0c7c78bed1a7524fae5c278
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Yhg1s <thomas at python.org>
date: 2023-06-19T17:42:23Z
summary:

[3.12] GH-105808: Fix a regression introduced in GH-101251 (GH-105910) (#105920)

GH-105808: Fix a regression introduced in GH-101251 (GH-105910)

Fix a regression introduced in pythonGH-101251, causing GzipFile.flush() to
not flush the compressor (nor pass along the zip_mode argument).
(cherry picked from commit 1858db7cbdbf41aa600c954c15224307bf81a258)

Co-authored-by: T. Wouters <thomas at python.org>

files:
A Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst
M Lib/gzip.py
M Lib/test/test_gzip.py

diff --git a/Lib/gzip.py b/Lib/gzip.py
index 8796c8d9fd9a2..cf8b675064ce8 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -370,8 +370,9 @@ def close(self):
     def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
         self._check_not_closed()
         if self.mode == WRITE:
-            # Ensure the compressor's buffer is flushed
             self._buffer.flush()
+            # Ensure the compressor's buffer is flushed
+            self.fileobj.write(self.compress.flush(zlib_mode))
             self.fileobj.flush()
 
     def fileno(self):
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 6de413e5056ef..c7ac7c687c8b2 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -9,6 +9,7 @@
 import struct
 import sys
 import unittest
+import zlib
 from subprocess import PIPE, Popen
 from test.support import import_helper
 from test.support import os_helper
@@ -616,6 +617,54 @@ def test_issue44439(self):
             self.assertEqual(f.write(q), LENGTH)
             self.assertEqual(f.tell(), LENGTH)
 
+    def test_flush_flushes_compressor(self):
+        # See issue GH-105808.
+        b = io.BytesIO()
+        message = b"important message here."
+        with gzip.GzipFile(fileobj=b, mode='w') as f:
+            f.write(message)
+            f.flush()
+            partial_data = b.getvalue()
+        full_data = b.getvalue()
+        self.assertEqual(gzip.decompress(full_data), message)
+        # The partial data should contain the gzip header and the complete
+        # message, but not the end-of-stream markers (so we can't just
+        # decompress it directly).
+        with self.assertRaises(EOFError):
+            gzip.decompress(partial_data)
+        d = zlib.decompressobj(wbits=-zlib.MAX_WBITS)
+        f = io.BytesIO(partial_data)
+        gzip._read_gzip_header(f)
+        read_message = d.decompress(f.read())
+        self.assertEqual(read_message, message)
+
+    def test_flush_modes(self):
+        # Make sure the argument to flush is properly passed to the
+        # zlib.compressobj; see issue GH-105808.
+        class FakeCompressor:
+            def __init__(self):
+                self.modes = []
+            def compress(self, data):
+                return b''
+            def flush(self, mode=-1):
+                self.modes.append(mode)
+                return b''
+        b = io.BytesIO()
+        fc = FakeCompressor()
+        with gzip.GzipFile(fileobj=b, mode='w') as f:
+            f.compress = fc
+            f.flush()
+            f.flush(50)
+            f.flush(zlib_mode=100)
+        # The implicit close will also flush the compressor.
+        expected_modes = [
+            zlib.Z_SYNC_FLUSH,
+            50,
+            100,
+            -1,
+        ]
+        self.assertEqual(fc.modes, expected_modes)
+
 
 class TestOpen(BaseTest):
     def test_binary_modes(self):
diff --git a/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst b/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst
new file mode 100644
index 0000000000000..8e69fd627c28e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-19-11-31-55.gh-issue-105808.NL-quu.rst
@@ -0,0 +1 @@
+Fix a regression introduced in GH-101251 for 3.12, causing :meth:`gzip.GzipFile.flush` to not flush the compressor (nor pass along the ``zip_mode`` argument).



More information about the Python-checkins mailing list