Skip to content

Commit 974cc01

Browse files
committed
allocate a bytes object directly instead and manually construct a writable memoryview pointing to it.
1 parent d7b9ea5 commit 974cc01

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

Modules/_io/iobase.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -927,13 +927,19 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
927927
return PyObject_CallMethodNoArgs(self, &_Py_ID(readall));
928928
}
929929

930-
/* TODO: allocate a bytes object directly instead and manually construct
931-
a writable memoryview pointing to it. */
932-
b = PyByteArray_FromStringAndSize(NULL, n);
930+
b = PyBytes_FromStringAndSize(NULL, n);
933931
if (b == NULL)
934932
return NULL;
935933

936-
res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL);
934+
PyObject *mv = PyMemoryView_FromMemory(PyBytes_AS_STRING(b), n, PyBUF_WRITE);
935+
if (mv == NULL) {
936+
Py_DECREF(b);
937+
return NULL;
938+
}
939+
940+
res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), mv, NULL);
941+
Py_DECREF(mv);
942+
937943
if (res == NULL || res == Py_None) {
938944
Py_DECREF(b);
939945
return res;
@@ -946,9 +952,14 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
946952
return NULL;
947953
}
948954

949-
res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
950-
Py_DECREF(b);
951-
return res;
955+
if (n != PyBytes_GET_SIZE(b)) {
956+
if (_PyBytes_Resize(&b, n) < 0) {
957+
Py_DECREF(b);
958+
return NULL;
959+
}
960+
}
961+
962+
return b;
952963
}
953964

954965

0 commit comments

Comments
 (0)