Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions Lib/test/test_zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,48 @@ class LzmaTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
compression = zipfile.ZIP_LZMA


class AbstractWriterTests:

def tearDown(self):
unlink(TESTFN2)

def test_close_after_close(self):
data = b'content'
with zipfile.ZipFile(TESTFN2, "w", self.compression) as zipf:
w = zipf.open('test', 'w')
w.write(data)
w.close()
self.assertTrue(w.closed)
w.close()
self.assertTrue(w.closed)
self.assertEqual(zipf.read('test'), data)

def test_write_after_close(self):
data = b'content'
with zipfile.ZipFile(TESTFN2, "w", self.compression) as zipf:
w = zipf.open('test', 'w')
w.write(data)
w.close()
self.assertTrue(w.closed)
self.assertRaises(ValueError, w.write, b'')
self.assertEqual(zipf.read('test'), data)

class StoredWriterTests(AbstractWriterTests, unittest.TestCase):
compression = zipfile.ZIP_STORED

@requires_zlib
class DeflateWriterTests(AbstractWriterTests, unittest.TestCase):
compression = zipfile.ZIP_DEFLATED

@requires_bz2
class Bzip2WriterTests(AbstractWriterTests, unittest.TestCase):
compression = zipfile.ZIP_BZIP2

@requires_lzma
class LzmaWriterTests(AbstractWriterTests, unittest.TestCase):
compression = zipfile.ZIP_LZMA


class PyZipFileTests(unittest.TestCase):
def assertCompiledIn(self, name, namelist):
if name + 'o' not in namelist:
Expand Down
4 changes: 4 additions & 0 deletions Lib/zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,8 @@ def writable(self):
return True

def write(self, data):
if self.closed:
raise ValueError('I/O operation on closed file.')
nbytes = len(data)
self._file_size += nbytes
self._crc = crc32(data, self._crc)
Expand All @@ -991,6 +993,8 @@ def write(self, data):
return nbytes

def close(self):
if self.closed:
return
super().close()
# Flush any data from the compressor, and update header info
if self._compressor:
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Core and Builtins
Library
-------

- bpo-30017: Allowed calling the close() method of the zip entry writer object
multiple times. Writing to a closed writer now always produces a ValueError.

- bpo-30068: _io._IOBase.readlines will check if it's closed first when
hint is present.

Expand Down