# HG changeset patch # Parent 800507fb0a7e198f45f82e9d1a8dc595c741e257 Make rawiobase_read() read directly to bytes object instead of copying. diff -r 800507fb0a7e Modules/_io/iobase.c --- a/Modules/_io/iobase.c Sun Sep 09 11:19:17 2012 +0200 +++ b/Modules/_io/iobase.c Mon Sep 10 12:52:30 2012 +0100 @@ -782,7 +782,7 @@ rawiobase_read(PyObject *self, PyObject *args) { Py_ssize_t n = -1; - PyObject *b, *res; + PyObject *b, *m, *res; if (!PyArg_ParseTuple(args, "|n:read", &n)) { return NULL; @@ -794,13 +794,21 @@ return _PyObject_CallMethodId(self, &PyId_readall, NULL); } - /* TODO: allocate a bytes object directly instead and manually construct - a writable memoryview pointing to it. */ - b = PyByteArray_FromStringAndSize(NULL, n); + b = PyBytes_FromStringAndSize(NULL, n); if (b == NULL) return NULL; - res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); + if (n == 0) + return b; + + m = PyMemoryView_FromMemory(PyBytes_AS_STRING(b), n, PyBUF_WRITE); + if (m == 0) { + Py_DECREF(b); + return NULL; + } + + res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, m, NULL); + Py_DECREF(m); if (res == NULL || res == Py_None) { Py_DECREF(b); return res; @@ -813,9 +821,10 @@ return NULL; } - res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); - Py_DECREF(b); - return res; + if (n < PyBytes_GET_SIZE(b) && _PyBytes_Resize(&b, n) < 0) + return NULL; + + return b; }