Skip to content

gh-81954: Warn when ZipFile is closed with unwritten data - #152354

Open
cmaloney wants to merge 8 commits into
python:mainfrom
cmaloney:zipfile_resourcewarning
Open

gh-81954: Warn when ZipFile is closed with unwritten data#152354
cmaloney wants to merge 8 commits into
python:mainfrom
cmaloney:zipfile_resourcewarning

Conversation

@cmaloney

@cmaloney cmaloney commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Bring zipfile.ZipFile into alignment with other buffered file writers like GzipFile and TextIOWrapper by emitting a ResourceWarning if there is unwritten data and it is closed implicitly.

ZipFile should be closed either by using it as a context manager or explicitly calling .close().

cc: @jaraco the _path/test_path fixtures have quite a few ZipFiles they don't close. For now I just blanket silenced, not sure your preferred upstream fix.

Bring `zipfile.ZipFile` into alignment with other buffered file writers
like `GzipFile` and `TextIOWrapper` by emitting a `ResourceWarning` if
there is unwritten data and it is closed implicitly.

ZipFile should be closed either by using it as a context manager or
explicitly calling `.close()`.
@read-the-docs-community

read-the-docs-community Bot commented Jun 27, 2026

Copy link
Copy Markdown

Comment thread Lib/test/test_zipfile/_path/test_path.py Outdated
Comment thread Lib/zipfile/__init__.py Outdated
# records. GC cleanup order is non-deterministic and can result in data
# loss.
if (self.fp is not None and self.mode in ('w', 'x', 'a')
and self._didModify):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this complex logic? open() logs a ResourceWarning even for files open in read-mode. A ZipFile contains a file, so it should emit a ResourceWarning if it's not closed, even if it's open in read-mode, or even if all data is flushed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reducing noisy cases that need to be updated for minimal value in an upgrade to 3.16. This parallels the GzipFile logic from gh-130806:

cpython/Lib/gzip.py

Lines 469 to 475 in 48cc257

def __del__(self):
if self.mode == WRITE and not self.closed:
import warnings
warnings.warn("unclosed GzipFile",
ResourceWarning, source=self, stacklevel=2)
super().__del__()

Dropped the self._didModify part (anything opened in writable mode should be reliably closed). The self.fp is not None is how ZipFile checks "has this been closed".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants