From: Serhiy Storchaka Date: Sun, 16 Apr 2017 09:04:45 +0000 (+0300) Subject: bpo-30017: Allowed calling the close() method of the zip entry writer object (#1041... X-Git-Tag: v3.6.2rc1~221 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e5b52a8da07e781bda50ba0a7065b1058495a37;p=python 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 4c0d9ea995da595e90e08813b89510de59907802) --- diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index d39f05fdb7..d09ad96fc8 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -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: diff --git a/Lib/zipfile.py b/Lib/zipfile.py index d7f5beba99..06eedec340 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -981,6 +981,8 @@ class _ZipWriteFile(io.BufferedIOBase): 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) @@ -991,6 +993,8 @@ class _ZipWriteFile(io.BufferedIOBase): return nbytes def close(self): + if self.closed: + return super().close() # Flush any data from the compressor, and update header info if self._compressor: diff --git a/Misc/NEWS b/Misc/NEWS index 7628ed5cab..673211d72d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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.