diff --git a/Lib/gzip.py b/Lib/gzip.py index 247efc01527bb1..54145bffbe3c7e 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -467,12 +467,13 @@ def readline(self, size=-1): return self._buffer.readline(size) def __del__(self): - if self.mode == WRITE and not self.closed: - import warnings - warnings.warn("unclosed GzipFile", - ResourceWarning, source=self, stacklevel=2) - - super().__del__() + try: + if self.mode == WRITE and not self.closed: + import warnings + warnings.warn("unclosed GzipFile", + ResourceWarning, source=self, stacklevel=2) + finally: + super().__del__() def _read_exact(fp, n): '''Read exactly *n* bytes from `fp` diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 8bc8e507683cb5..fa107e07534e47 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -11,7 +11,7 @@ import unittest from subprocess import PIPE, Popen from unittest import mock -from test.support import catch_unraisable_exception +from test.support import catch_unraisable_exception, gc_collect from test.support import force_not_colorized_test_class, import_helper from test.support import os_helper from test.support import _4G, bigmemtest, requires_subprocess @@ -965,6 +965,19 @@ def test_refloop_unraisable(self): gc.collect() self.assertIsNone(cm.unraisable) + def test_del_closes_if_warning_fails(self): + # The file must still be closed if emitting the ResourceWarning + # raises, as can happen at interpreter shutdown. + b = io.BytesIO() + f = gzip.GzipFile(fileobj=b, mode="wb") + f.write(data1) + with (mock.patch("warnings.warn", side_effect=RuntimeError), + catch_unraisable_exception() as cm): + del f + gc_collect() + self.assertIs(cm.unraisable.exc_type, RuntimeError) + self.assertEqual(gzip.decompress(b.getvalue()), data1) + class TestOpen(BaseTest): def test_binary_modes(self): diff --git a/Misc/NEWS.d/next/Library/2026-10-14-15-50-59.gh-issue-159422.16mSqQ.rst b/Misc/NEWS.d/next/Library/2026-10-14-15-50-59.gh-issue-159422.16mSqQ.rst new file mode 100644 index 00000000000000..bcc37718ea76b2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-14-15-50-59.gh-issue-159422.16mSqQ.rst @@ -0,0 +1,3 @@ +Fix truncated output when a writable :class:`gzip.GzipFile` that was never +closed is finalized and emitting its :exc:`ResourceWarning` fails, for +example at interpreter shutdown. The file is now always closed.