Issue 36434: Zipfile breaks if signalled during write() (original) (raw)

Consider a simple write to a zip file:

import zipfile

with zipfile.ZipFile('/workdir/archive.zip', 'w', compression=zipfile.ZIP_DEFLATED) as zip_archive: zip_archive.write('/workdir/data.csv', arcname='data.csv') print('exiting from context manager...')

If a signal handler is fired and raises an exception during certain points of write() execution, such an error occurs (py 3.7.2):

Traceback (most recent call last): File "zipissue.py", line 4, in zip_archive.write('/workdir/data.csv', arcname='data.csv') File "/usr/local/lib/python3.7/zipfile.py", line 1744, in write shutil.copyfileobj(src, dest, 1024*8) File "/usr/local/lib/python3.7/zipfile.py", line 1107, in close buf = self._compressor.flush() KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "zipissue.py", line 5, in print('exiting from context manager...') File "/usr/local/lib/python3.7/zipfile.py", line 1265, in exit self.close() File "/usr/local/lib/python3.7/zipfile.py", line 1798, in close raise ValueError("Can't close the ZIP file while there is " ValueError: Can't close the ZIP file while there is an open writing handle on it. Close the writing handle before closing the zip. Exception ignored in: <function ZipFile.__del__ at 0x7fbeea4fcd08> Traceback (most recent call last): File "/usr/local/lib/python3.7/zipfile.py", line 1789, in del File "/usr/local/lib/python3.7/zipfile.py", line 1798, in close ValueError: Can't close the ZIP file while there is an open writing handle on it. Close the writing handle before closing the zip.

Before any write the ZipFile._writing flag is set, and that flag is cleared at _ZipWriteFile.close(). But if signalled inside _ZipWriteFile.close() we are moving to a broken state: we don't write anything anymore, but ZipFile._writing is still set. Therefore we cannot clearly close ZipFile. As ZipFile contextmanager swallows KeyboardInterrupt and produces an exception of Exception type, this leads to the impossibility of proper program shutdown.

I believe that by simply moving ZipFile._writing = False in _ZipWriteFile.close() to some finally block, this issue will be solved safely.