mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
This commit is contained in:
parent
e9d44ccb22
commit
b57f108b03
5 changed files with 48 additions and 11 deletions
|
@ -944,6 +944,12 @@ class BufferedReader(_BufferedIOMixin):
|
||||||
# Special case for when the number of bytes to read is unspecified.
|
# Special case for when the number of bytes to read is unspecified.
|
||||||
if n is None or n == -1:
|
if n is None or n == -1:
|
||||||
self._reset_read_buf()
|
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.
|
chunks = [buf[pos:]] # Strip the consumed bytes.
|
||||||
current_size = 0
|
current_size = 0
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -161,6 +161,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
|
||||||
|
|
||||||
- Issue #12175: FileIO.readall() now only reads the file position and size
|
- Issue #12175: FileIO.readall() now only reads the file position and size
|
||||||
once.
|
once.
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ PyObject *_PyIO_str_nl;
|
||||||
PyObject *_PyIO_str_read;
|
PyObject *_PyIO_str_read;
|
||||||
PyObject *_PyIO_str_read1;
|
PyObject *_PyIO_str_read1;
|
||||||
PyObject *_PyIO_str_readable;
|
PyObject *_PyIO_str_readable;
|
||||||
|
PyObject *_PyIO_str_readall;
|
||||||
PyObject *_PyIO_str_readinto;
|
PyObject *_PyIO_str_readinto;
|
||||||
PyObject *_PyIO_str_readline;
|
PyObject *_PyIO_str_readline;
|
||||||
PyObject *_PyIO_str_reset;
|
PyObject *_PyIO_str_reset;
|
||||||
|
@ -767,6 +768,8 @@ PyInit__io(void)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
|
if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
if (!(_PyIO_str_readall = PyUnicode_InternFromString("readall")))
|
||||||
|
goto fail;
|
||||||
if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto")))
|
if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto")))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline")))
|
if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline")))
|
||||||
|
|
|
@ -155,6 +155,7 @@ extern PyObject *_PyIO_str_nl;
|
||||||
extern PyObject *_PyIO_str_read;
|
extern PyObject *_PyIO_str_read;
|
||||||
extern PyObject *_PyIO_str_read1;
|
extern PyObject *_PyIO_str_read1;
|
||||||
extern PyObject *_PyIO_str_readable;
|
extern PyObject *_PyIO_str_readable;
|
||||||
|
extern PyObject *_PyIO_str_readall;
|
||||||
extern PyObject *_PyIO_str_readinto;
|
extern PyObject *_PyIO_str_readinto;
|
||||||
extern PyObject *_PyIO_str_readline;
|
extern PyObject *_PyIO_str_readline;
|
||||||
extern PyObject *_PyIO_str_reset;
|
extern PyObject *_PyIO_str_reset;
|
||||||
|
|
|
@ -1407,32 +1407,57 @@ static PyObject *
|
||||||
_bufferedreader_read_all(buffered *self)
|
_bufferedreader_read_all(buffered *self)
|
||||||
{
|
{
|
||||||
Py_ssize_t current_size;
|
Py_ssize_t current_size;
|
||||||
PyObject *res, *data = NULL;
|
PyObject *res, *data = NULL, *chunk, *chunks;
|
||||||
PyObject *chunks = PyList_New(0);
|
|
||||||
|
|
||||||
if (chunks == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* First copy what we have in the current buffer. */
|
/* First copy what we have in the current buffer. */
|
||||||
current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
|
current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
|
||||||
if (current_size) {
|
if (current_size) {
|
||||||
data = PyBytes_FromStringAndSize(
|
data = PyBytes_FromStringAndSize(
|
||||||
self->buffer + self->pos, current_size);
|
self->buffer + self->pos, current_size);
|
||||||
if (data == NULL) {
|
if (data == NULL)
|
||||||
Py_DECREF(chunks);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_bufferedreader_reset_buf(self);
|
_bufferedreader_reset_buf(self);
|
||||||
/* We're going past the buffer's bounds, flush it */
|
/* We're going past the buffer's bounds, flush it */
|
||||||
if (self->writable) {
|
if (self->writable) {
|
||||||
res = _bufferedwriter_flush_unlocked(self, 1);
|
res = _bufferedwriter_flush_unlocked(self, 1);
|
||||||
if (res == NULL) {
|
if (res == NULL)
|
||||||
Py_DECREF(chunks);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
Py_CLEAR(res);
|
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) {
|
while (1) {
|
||||||
if (data) {
|
if (data) {
|
||||||
if (PyList_Append(chunks, data) < 0) {
|
if (PyList_Append(chunks, data) < 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue