Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b57f108

Browse files
author
Victor Stinner
committed
Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
1 parent e9d44cc commit b57f108

5 files changed

Lines changed: 48 additions & 11 deletions

File tree

Lib/_pyio.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,12 @@ def _read_unlocked(self, n=None):
944944
# Special case for when the number of bytes to read is unspecified.
945945
if n is None or n == -1:
946946
self._reset_read_buf()
947+
if hasattr(self.raw, 'readall'):
948+
chunk = self.raw.readall()
949+
if chunk is None:
950+
return buf[pos:] or None
951+
else:
952+
return buf[pos:] + chunk
947953
chunks = [buf[pos:]] # Strip the consumed bytes.
948954
current_size = 0
949955
while True:

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ Core and Builtins
161161
Library
162162
-------
163163

164+
- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
165+
164166
- Issue #12175: FileIO.readall() now only reads the file position and size
165167
once.
166168

Modules/_io/_iomodule.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ PyObject *_PyIO_str_nl;
3636
PyObject *_PyIO_str_read;
3737
PyObject *_PyIO_str_read1;
3838
PyObject *_PyIO_str_readable;
39+
PyObject *_PyIO_str_readall;
3940
PyObject *_PyIO_str_readinto;
4041
PyObject *_PyIO_str_readline;
4142
PyObject *_PyIO_str_reset;
@@ -767,6 +768,8 @@ PyInit__io(void)
767768
goto fail;
768769
if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
769770
goto fail;
771+
if (!(_PyIO_str_readall = PyUnicode_InternFromString("readall")))
772+
goto fail;
770773
if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto")))
771774
goto fail;
772775
if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline")))

Modules/_io/_iomodule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ extern PyObject *_PyIO_str_nl;
155155
extern PyObject *_PyIO_str_read;
156156
extern PyObject *_PyIO_str_read1;
157157
extern PyObject *_PyIO_str_readable;
158+
extern PyObject *_PyIO_str_readall;
158159
extern PyObject *_PyIO_str_readinto;
159160
extern PyObject *_PyIO_str_readline;
160161
extern PyObject *_PyIO_str_reset;

Modules/_io/bufferedio.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,32 +1407,57 @@ static PyObject *
14071407
_bufferedreader_read_all(buffered *self)
14081408
{
14091409
Py_ssize_t current_size;
1410-
PyObject *res, *data = NULL;
1411-
PyObject *chunks = PyList_New(0);
1412-
1413-
if (chunks == NULL)
1414-
return NULL;
1410+
PyObject *res, *data = NULL, *chunk, *chunks;
14151411

14161412
/* First copy what we have in the current buffer. */
14171413
current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
14181414
if (current_size) {
14191415
data = PyBytes_FromStringAndSize(
14201416
self->buffer + self->pos, current_size);
1421-
if (data == NULL) {
1422-
Py_DECREF(chunks);
1417+
if (data == NULL)
14231418
return NULL;
1424-
}
14251419
}
14261420
_bufferedreader_reset_buf(self);
14271421
/* We're going past the buffer's bounds, flush it */
14281422
if (self->writable) {
14291423
res = _bufferedwriter_flush_unlocked(self, 1);
1430-
if (res == NULL) {
1431-
Py_DECREF(chunks);
1424+
if (res == NULL)
14321425
return NULL;
1433-
}
14341426
Py_CLEAR(res);
14351427
}
1428+
1429+
if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1430+
chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1431+
if (chunk == NULL)
1432+
return NULL;
1433+
if (chunk != Py_None && !PyBytes_Check(chunk)) {
1434+
Py_XDECREF(data);
1435+
Py_DECREF(chunk);
1436+
PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1437+
return NULL;
1438+
}
1439+
if (chunk == Py_None) {
1440+
if (current_size == 0)
1441+
return chunk;
1442+
else {
1443+
Py_DECREF(chunk);
1444+
return data;
1445+
}
1446+
}
1447+
else if (current_size) {
1448+
PyBytes_Concat(&data, chunk);
1449+
Py_DECREF(chunk);
1450+
if (data == NULL)
1451+
return NULL;
1452+
return data;
1453+
} else
1454+
return chunk;
1455+
}
1456+
1457+
chunks = PyList_New(0);
1458+
if (chunks == NULL)
1459+
return NULL;
1460+
14361461
while (1) {
14371462
if (data) {
14381463
if (PyList_Append(chunks, data) < 0) {

0 commit comments

Comments
 (0)