Repository navigation
gh-81954: Always close ZipFile in __del__ even if the warning fails #159419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,7 +26,7 @@ | |||||||
| from test.support import ( | ||||||||
| findfile, requires_zlib, requires_bz2, requires_lzma, | ||||||||
| requires_zstd, captured_stdout, captured_stderr, requires_subprocess, | ||||||||
| cpython_only, gc_collect | ||||||||
| cpython_only, gc_collect, catch_unraisable_exception | ||||||||
| ) | ||||||||
| from test.support.os_helper import ( | ||||||||
| TESTFN, unlink, rmtree, temp_dir, temp_cwd, fd_count, FakePath, | ||||||||
|
|
@@ -4095,6 +4095,29 @@ def test_garbage_collection(self): | |||||||
| zf.close() | ||||||||
| del zf | ||||||||
|
|
||||||||
| def test_garbage_collection_closes_when_warning_fails(self): | ||||||||
| buf = io.BytesIO() | ||||||||
| zf = zipfile.ZipFile(buf, "w") | ||||||||
| zf.writestr("f.txt", b"data") | ||||||||
| with warnings.catch_warnings(), catch_unraisable_exception() as cm: | ||||||||
| warnings.simplefilter("error", ResourceWarning) | ||||||||
| del zf | ||||||||
| gc_collect() | ||||||||
| self.assertIsInstance(cm.unraisable.exc_value, ResourceWarning) | ||||||||
| with zipfile.ZipFile(buf) as zf: | ||||||||
| self.assertEqual(zf.namelist(), ["f.txt"]) | ||||||||
|
|
||||||||
| @requires_subprocess() | ||||||||
| def test_unclosed_at_shutdown(self): | ||||||||
| self.addCleanup(unlink, TESTFN) | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this particular test suite already cleans up TESTFN so I don't think this needs to be done here: cpython/Lib/test/test_zipfile/test_core.py Lines 487 to 489 in a6b4aa6
|
||||||||
| script_helper.assert_python_ok("-c", f"""if 1: | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This still ends up raising an ImportError for |
||||||||
| import zipfile | ||||||||
| zf = zipfile.ZipFile({TESTFN!r}, "w") | ||||||||
| zf.writestr("f.txt", b"data") | ||||||||
| """) | ||||||||
| with zipfile.ZipFile(TESTFN) as zf: | ||||||||
| self.assertEqual(zf.namelist(), ["f.txt"]) | ||||||||
|
|
||||||||
| def test_unsupported_version(self): | ||||||||
| # File has an extract_version of 120 | ||||||||
| data = (b'PK\x03\x04x\x00\x00\x00\x00\x00!p\xa1@\x00\x00\x00\x00\x00\x00' | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Fix data loss when a writable :class:`zipfile.ZipFile` that was never closed | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user didn't close the file either, this doesn't make a guarantee the zipfile is closed cleanly (GC order is not guaranteed). Definitely improves an edge case when
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thinking a bit more here: I think we should just make the |
||
| is finalized during interpreter shutdown: :meth:`~zipfile.ZipFile.close` is | ||
| now called even if emitting the :exc:`ResourceWarning` fails. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified a bit to:
Another option is making it so we just test with the
test_unclosed_at_shutdownstyle passing-Wto the interpreter which would reduce code a bit more while covering the same case.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be more cases in the existing
test_garbage_collectionrather than a new test section. It's adding a new case we want to check