mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00
Issue #14099: Restored support of writing ZIP files to tellable but
non-seekable streams.
This commit is contained in:
parent
f15e524026
commit
a14f7d239f
3 changed files with 44 additions and 3 deletions
|
@ -1668,6 +1668,34 @@ class LzmaTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles,
|
||||||
compression = zipfile.ZIP_LZMA
|
compression = zipfile.ZIP_LZMA
|
||||||
|
|
||||||
|
|
||||||
|
# Privide the tell() method but not seek()
|
||||||
|
class Tellable:
|
||||||
|
def __init__(self, fp):
|
||||||
|
self.fp = fp
|
||||||
|
self.offset = 0
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
self.offset += self.fp.write(data)
|
||||||
|
|
||||||
|
def tell(self):
|
||||||
|
return self.offset
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class UnseekableTests(unittest.TestCase):
|
||||||
|
def test_writestr_tellable(self):
|
||||||
|
f = io.BytesIO()
|
||||||
|
with zipfile.ZipFile(Tellable(f), 'w', zipfile.ZIP_STORED) as zipfp:
|
||||||
|
zipfp.writestr('ones', b'111')
|
||||||
|
zipfp.writestr('twos', b'222')
|
||||||
|
with zipfile.ZipFile(f, mode='r') as zipf:
|
||||||
|
with zipf.open('ones') as zopen:
|
||||||
|
self.assertEqual(zopen.read(), b'111')
|
||||||
|
with zipf.open('twos') as zopen:
|
||||||
|
self.assertEqual(zopen.read(), b'222')
|
||||||
|
|
||||||
|
|
||||||
@requires_zlib
|
@requires_zlib
|
||||||
class TestsWithMultipleOpens(unittest.TestCase):
|
class TestsWithMultipleOpens(unittest.TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -1504,7 +1504,14 @@ class ZipFile:
|
||||||
|
|
||||||
zinfo.file_size = len(data) # Uncompressed size
|
zinfo.file_size = len(data) # Uncompressed size
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self.fp.seek(self.start_dir, 0)
|
try:
|
||||||
|
self.fp.seek(self.start_dir)
|
||||||
|
except (AttributeError, io.UnsupportedOperation):
|
||||||
|
# Some file-like objects can provide tell() but not seek()
|
||||||
|
pass
|
||||||
|
zinfo.header_offset = self.fp.tell() # Start of header data
|
||||||
|
if compress_type is not None:
|
||||||
|
zinfo.compress_type = compress_type
|
||||||
zinfo.header_offset = self.fp.tell() # Start of header data
|
zinfo.header_offset = self.fp.tell() # Start of header data
|
||||||
if compress_type is not None:
|
if compress_type is not None:
|
||||||
zinfo.compress_type = compress_type
|
zinfo.compress_type = compress_type
|
||||||
|
@ -1550,7 +1557,11 @@ class ZipFile:
|
||||||
try:
|
try:
|
||||||
if self.mode in ("w", "a") and self._didModify: # write ending records
|
if self.mode in ("w", "a") and self._didModify: # write ending records
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self.fp.seek(self.start_dir, 0)
|
try:
|
||||||
|
self.fp.seek(self.start_dir)
|
||||||
|
except (AttributeError, io.UnsupportedOperation):
|
||||||
|
# Some file-like objects can provide tell() but not seek()
|
||||||
|
pass
|
||||||
self._write_end_record()
|
self._write_end_record()
|
||||||
finally:
|
finally:
|
||||||
fp = self.fp
|
fp = self.fp
|
||||||
|
@ -1558,7 +1569,6 @@ class ZipFile:
|
||||||
self._fpclose(fp)
|
self._fpclose(fp)
|
||||||
|
|
||||||
def _write_end_record(self):
|
def _write_end_record(self):
|
||||||
self.fp.seek(self.start_dir, 0)
|
|
||||||
for zinfo in self.filelist: # write central directory
|
for zinfo in self.filelist: # write central directory
|
||||||
dt = zinfo.date_time
|
dt = zinfo.date_time
|
||||||
dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
|
dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
|
||||||
|
|
|
@ -218,6 +218,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #14099: Restored support of writing ZIP files to tellable but
|
||||||
|
non-seekable streams.
|
||||||
|
|
||||||
- Issue #14099: Writing to ZipFile and reading multiple ZipExtFiles is
|
- Issue #14099: Writing to ZipFile and reading multiple ZipExtFiles is
|
||||||
threadsafe now.
|
threadsafe now.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue