From: yihong Date: Mon, 15 Dec 2025 14:13:58 +0000 (+0800) Subject: gh-142594: fix by property calls io.TextIOWrapper.detach (GH-142706) X-Git-Tag: v3.15.0a3~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d3854a19a376c1fc7f71e96c620f6bc2de8cd74;p=thirdparty%2FPython%2Fcpython.git gh-142594: fix by property calls io.TextIOWrapper.detach (GH-142706) Signed-off-by: yihong0618 --- diff --git a/Lib/test/test_io/test_textio.py b/Lib/test/test_io/test_textio.py index 6331ed2b9585..d725f9212cea 100644 --- a/Lib/test/test_io/test_textio.py +++ b/Lib/test/test_io/test_textio.py @@ -1544,6 +1544,22 @@ class CTextIOWrapperTest(TextIOWrapperTest, CTestCase): self.assertEqual([b"abcdef", b"middle", b"g"*chunk_size], buf._write_stack) + def test_issue142594(self): + wrapper = None + detached = False + class ReentrantRawIO(self.RawIOBase): + @property + def closed(self): + nonlocal detached + if wrapper is not None and not detached: + detached = True + wrapper.detach() + return False + + raw = ReentrantRawIO() + wrapper = self.TextIOWrapper(raw) + wrapper.close() # should not crash + class PyTextIOWrapperTest(TextIOWrapperTest, PyTestCase): shutdown_error = "LookupError: unknown encoding: ascii" diff --git a/Misc/NEWS.d/next/Library/2025-12-14-18-30-48.gh-issue-142594.belDmD.rst b/Misc/NEWS.d/next/Library/2025-12-14-18-30-48.gh-issue-142594.belDmD.rst new file mode 100644 index 000000000000..ee6a958933f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-14-18-30-48.gh-issue-142594.belDmD.rst @@ -0,0 +1,2 @@ +Fix crash in ``TextIOWrapper.close()`` when the underlying buffer's +``closed`` property calls :meth:`~io.TextIOBase.detach`. diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 65da300abcf3..f98819525612 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -3150,6 +3150,9 @@ _io_TextIOWrapper_close_impl(textio *self) if (r > 0) { Py_RETURN_NONE; /* stream already closed */ } + if (self->detached) { + Py_RETURN_NONE; /* gh-142594 null pointer issue */ + } else { PyObject *exc = NULL; if (self->finalizing) {