diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-25 22:19:38 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-25 22:19:38 (GMT) |
commit | b57f108b03df332d276a224c92e32cee13a042f2 (patch) | |
tree | 954924ef9693e020c58d90999bdb548af8f45f9f | |
parent | e9d44ccb2279a49a69277d38e956731675f1b556 (diff) | |
download | cpython-b57f108b03df332d276a224c92e32cee13a042f2.zip cpython-b57f108b03df332d276a224c92e32cee13a042f2.tar.gz cpython-b57f108b03df332d276a224c92e32cee13a042f2.tar.bz2 |
Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
-rw-r--r-- | Lib/_pyio.py | 6 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_io/_iomodule.c | 3 | ||||
-rw-r--r-- | Modules/_io/_iomodule.h | 1 | ||||
-rw-r--r-- | Modules/_io/bufferedio.c | 47 |
5 files changed, 48 insertions, 11 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 74047bf..265edab 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -944,6 +944,12 @@ class BufferedReader(_BufferedIOMixin): # Special case for when the number of bytes to read is unspecified. if n is None or n == -1: self._reset_read_buf() + if hasattr(self.raw, 'readall'): + chunk = self.raw.readall() + if chunk is None: + return buf[pos:] or None + else: + return buf[pos:] + chunk chunks = [buf[pos:]] # Strip the consumed bytes. current_size = 0 while True: @@ -161,6 +161,8 @@ Core and Builtins Library ------- +- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available. + - Issue #12175: FileIO.readall() now only reads the file position and size once. diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 44bdac6..6f5bd48 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -36,6 +36,7 @@ PyObject *_PyIO_str_nl; PyObject *_PyIO_str_read; PyObject *_PyIO_str_read1; PyObject *_PyIO_str_readable; +PyObject *_PyIO_str_readall; PyObject *_PyIO_str_readinto; PyObject *_PyIO_str_readline; PyObject *_PyIO_str_reset; @@ -767,6 +768,8 @@ PyInit__io(void) goto fail; if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable"))) goto fail; + if (!(_PyIO_str_readall = PyUnicode_InternFromString("readall"))) + goto fail; if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto"))) goto fail; if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline"))) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 925e4f2..9174bdd 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -155,6 +155,7 @@ extern PyObject *_PyIO_str_nl; extern PyObject *_PyIO_str_read; extern PyObject *_PyIO_str_read1; extern PyObject *_PyIO_str_readable; +extern PyObject *_PyIO_str_readall; extern PyObject *_PyIO_str_readinto; extern PyObject *_PyIO_str_readline; extern PyObject *_PyIO_str_reset; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 3b8b7e9..63ae1cb 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1407,32 +1407,57 @@ static PyObject * _bufferedreader_read_all(buffered *self) { Py_ssize_t current_size; - PyObject *res, *data = NULL; - PyObject *chunks = PyList_New(0); - - if (chunks == NULL) - return NULL; + PyObject *res, *data = NULL, *chunk, *chunks; /* First copy what we have in the current buffer. */ current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (current_size) { data = PyBytes_FromStringAndSize( self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); + if (data == NULL) return NULL; - } } _bufferedreader_reset_buf(self); /* We're going past the buffer's bounds, flush it */ if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); - if (res == NULL) { - Py_DECREF(chunks); + if (res == NULL) return NULL; - } Py_CLEAR(res); } + + if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) { + chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL); + if (chunk == NULL) + return NULL; + if (chunk != Py_None && !PyBytes_Check(chunk)) { + Py_XDECREF(data); + Py_DECREF(chunk); + PyErr_SetString(PyExc_TypeError, "readall() should return bytes"); + return NULL; + } + if (chunk == Py_None) { + if (current_size == 0) + return chunk; + else { + Py_DECREF(chunk); + return data; + } + } + else if (current_size) { + PyBytes_Concat(&data, chunk); + Py_DECREF(chunk); + if (data == NULL) + return NULL; + return data; + } else + return chunk; + } + + chunks = PyList_New(0); + if (chunks == NULL) + return NULL; + while (1) { if (data) { if (PyList_Append(chunks, data) < 0) { |