Skip to content
Prev Previous commit
Next Next commit
Better place for test. Remove excess newlines. Remove old TODO
  • Loading branch information
cmaloney committed Nov 13, 2025
commit 847c7edf860d1d37fdb91f1755f586ecef1a1dda
39 changes: 19 additions & 20 deletions Lib/test/test_io/test_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,25 @@ def readinto(self, b):
with self.assertRaises(ValueError):
Misbehaved(bad_size).read()

def test_RawIOBase_read_gh60107(self):
# gh-60107: Ensure a "Raw I/O" which keeps a reference to the
# mutable memory doesn't allow making a mutable bytes.
class RawIOKeepsReference(self.MockRawIOWithoutRead):
def __init__(self, *args, **kwargs):
self.buf = None
super().__init__(*args, **kwargs)

def readinto(self, buf):
# buf is the bytearray so keeping a reference to it doesn't keep
# the memory alive; a memoryview does.
self.buf = memoryview(buf)
buf[0:4] = self._read_stack.pop()
return 3

with self.assertRaises(BufferError):
rawio = RawIOKeepsReference([b"1234"])
rawio.read(4)

def test_types_have_dict(self):
test = (
self.IOBase(),
Expand Down Expand Up @@ -724,26 +743,6 @@ def test_RawIOBase_readall(self):
rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg"))
self.assertEqual(rawio.readall(), b"abcdefg")

# gh-60107: Ensure a "Raw I/O" which keeps a reference to the
# mutable memory doesn't allow making a mutable bytes.
class RawIOKeepsReference(self.MockRawIOWithoutRead):
def __init__(self, *args, **kwargs):
self.buf = None
super().__init__(*args, **kwargs)

def readinto(self, buf):
# buf is the bytearray so keeping a reference to it doesn't keep
# the memory alive; a memoryview does.
self.buf = memoryview(buf)
buf[0:4] = self._read_stack.pop()
return 3

with self.assertRaises(BufferError):
rawio = RawIOKeepsReference([b"1234"])
rawio.read(4)



def test_BufferedIOBase_readinto(self):
# Exercise the default BufferedIOBase.readinto() and readinto1()
# implementations (which call read() or read1() internally).
Expand Down
2 changes: 0 additions & 2 deletions Modules/_io/iobase.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,8 +927,6 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
return PyObject_CallMethodNoArgs(self, &_Py_ID(readall));
}

/* TODO: allocate a bytes object directly instead and manually construct
a writable memoryview pointing to it. */
b = PyByteArray_FromStringAndSize(NULL, n);
if (b == NULL)
return NULL;
Expand Down
Loading