mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
[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 1858db7cbd
)
Co-authored-by: T. Wouters <thomas@python.org>
This commit is contained in:
parent
5e524ef346
commit
225cc4c043
3 changed files with 52 additions and 1 deletions
|
@ -370,8 +370,9 @@ class GzipFile(_compression.BaseStream):
|
||||||
def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
|
def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH):
|
||||||
self._check_not_closed()
|
self._check_not_closed()
|
||||||
if self.mode == WRITE:
|
if self.mode == WRITE:
|
||||||
# Ensure the compressor's buffer is flushed
|
|
||||||
self._buffer.flush()
|
self._buffer.flush()
|
||||||
|
# Ensure the compressor's buffer is flushed
|
||||||
|
self.fileobj.write(self.compress.flush(zlib_mode))
|
||||||
self.fileobj.flush()
|
self.fileobj.flush()
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
|
|
|
@ -9,6 +9,7 @@ import pathlib
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
import zlib
|
||||||
from subprocess import PIPE, Popen
|
from subprocess import PIPE, Popen
|
||||||
from test.support import import_helper
|
from test.support import import_helper
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
|
@ -616,6 +617,54 @@ class TestGzip(BaseTest):
|
||||||
self.assertEqual(f.write(q), LENGTH)
|
self.assertEqual(f.write(q), LENGTH)
|
||||||
self.assertEqual(f.tell(), 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):
|
class TestOpen(BaseTest):
|
||||||
def test_binary_modes(self):
|
def test_binary_modes(self):
|
||||||
|
|
|
@ -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).
|
Loading…
Add table
Add a link
Reference in a new issue