Skip to content

Commit 9106913

Browse files
authored
[3.14] gh-160427: Return None from TextIOWrapper.buffer when detached (GH-160802) (#161450)
gh-154523 turned the buffer member descriptor into a getter that raises ValueError when the buffer is NULL, and the backport shipped in 3.14.9 and 3.15.1. That made hasattr(stream, "buffer") raise after detach(). Restore the old member descriptor result (None) while keeping the critical section. (cherry picked from commit 3422197)
1 parent 7ed3bb8 commit 9106913

3 files changed

Lines changed: 10 additions & 4 deletions

File tree

‎Lib/test/test_io.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2910,6 +2910,7 @@ def test_detach(self):
29102910
r = self.BytesIO()
29112911
b = self.BufferedWriter(r)
29122912
t = self.TextIOWrapper(b, encoding="ascii")
2913+
self.assertIs(t.buffer, b)
29132914
self.assertIs(t.detach(), b)
29142915

29152916
t = self.TextIOWrapper(b, encoding="ascii")
@@ -2925,6 +2926,7 @@ def test_detach(self):
29252926
self.assertEqual(t.errors, "strict")
29262927
self.assertFalse(t.line_buffering)
29272928
self.assertFalse(t.write_through)
2929+
self.assertIsNone(t.buffer)
29282930

29292931
def test_repr(self):
29302932
raw = self.BytesIO("hello".encode("utf-8"))
@@ -4403,9 +4405,7 @@ def readinto(self, b):
44034405
self.BufferedReader(raw), encoding="utf-8")
44044406
method = getattr(wrapper, method_name)
44054407
self.assertEqual(method(), "ab\n")
4406-
with self.assertRaisesRegex(ValueError,
4407-
"underlying buffer has been detached"):
4408-
getattr(wrapper, 'buffer')
4408+
self.assertIsNone(wrapper.buffer)
44094409

44104410

44114411
class PyTextIOWrapperTest(TextIOWrapperTest):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :attr:`~io.TextIOBase.buffer` of a detached :class:`io.TextIOWrapper`
2+
raising :exc:`ValueError` instead of returning ``None``.

‎Modules/_io/textio.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3467,7 +3467,11 @@ static PyObject *
34673467
_io_TextIOWrapper_buffer_get_impl(textio *self)
34683468
/*[clinic end generated code: output=d265a34555aa5d4b input=5951cfa148f7350a]*/
34693469
{
3470-
return buffer_access_safe(self);
3470+
/* gh-160427: None once detached, matching the former member descriptor. */
3471+
if (self->buffer == NULL) {
3472+
Py_RETURN_NONE;
3473+
}
3474+
return Py_NewRef(self->buffer);
34713475
}
34723476

34733477
static PyMethodDef incrementalnewlinedecoder_methods[] = {

0 commit comments

Comments
 (0)