Skip to content

Commit 8e5b52a

Browse files
bpo-30017: Allowed calling the close() method of the zip entry writer object (#1041) (#1092)
multiple times. Writing to closed zip entry writer object now always produce a ValueError. (cherry picked from commit 4c0d9ea)
1 parent d5fa5f3 commit 8e5b52a

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

Lib/test/test_zipfile.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,48 @@ class LzmaTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
734734
compression = zipfile.ZIP_LZMA
735735

736736

737+
class AbstractWriterTests:
738+
739+
def tearDown(self):
740+
unlink(TESTFN2)
741+
742+
def test_close_after_close(self):
743+
data = b'content'
744+
with zipfile.ZipFile(TESTFN2, "w", self.compression) as zipf:
745+
w = zipf.open('test', 'w')
746+
w.write(data)
747+
w.close()
748+
self.assertTrue(w.closed)
749+
w.close()
750+
self.assertTrue(w.closed)
751+
self.assertEqual(zipf.read('test'), data)
752+
753+
def test_write_after_close(self):
754+
data = b'content'
755+
with zipfile.ZipFile(TESTFN2, "w", self.compression) as zipf:
756+
w = zipf.open('test', 'w')
757+
w.write(data)
758+
w.close()
759+
self.assertTrue(w.closed)
760+
self.assertRaises(ValueError, w.write, b'')
761+
self.assertEqual(zipf.read('test'), data)
762+
763+
class StoredWriterTests(AbstractWriterTests, unittest.TestCase):
764+
compression = zipfile.ZIP_STORED
765+
766+
@requires_zlib
767+
class DeflateWriterTests(AbstractWriterTests, unittest.TestCase):
768+
compression = zipfile.ZIP_DEFLATED
769+
770+
@requires_bz2
771+
class Bzip2WriterTests(AbstractWriterTests, unittest.TestCase):
772+
compression = zipfile.ZIP_BZIP2
773+
774+
@requires_lzma
775+
class LzmaWriterTests(AbstractWriterTests, unittest.TestCase):
776+
compression = zipfile.ZIP_LZMA
777+
778+
737779
class PyZipFileTests(unittest.TestCase):
738780
def assertCompiledIn(self, name, namelist):
739781
if name + 'o' not in namelist:

Lib/zipfile.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,8 @@ def writable(self):
981981
return True
982982

983983
def write(self, data):
984+
if self.closed:
985+
raise ValueError('I/O operation on closed file.')
984986
nbytes = len(data)
985987
self._file_size += nbytes
986988
self._crc = crc32(data, self._crc)
@@ -991,6 +993,8 @@ def write(self, data):
991993
return nbytes
992994

993995
def close(self):
996+
if self.closed:
997+
return
994998
super().close()
995999
# Flush any data from the compressor, and update header info
9961000
if self._compressor:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Core and Builtins
3232
Library
3333
-------
3434

35+
- bpo-30017: Allowed calling the close() method of the zip entry writer object
36+
multiple times. Writing to a closed writer now always produces a ValueError.
37+
3538
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
3639
hint is present.
3740

0 commit comments

Comments
 (0)