Skip to content

Commit 026435c

Browse files
authored
bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1130)
1 parent eaeda64 commit 026435c

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

Lib/test/test_io.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,6 +3510,7 @@ def test_io_after_close(self):
35103510
self.assertRaises(ValueError, f.readinto1, bytearray(1024))
35113511
self.assertRaises(ValueError, f.readline)
35123512
self.assertRaises(ValueError, f.readlines)
3513+
self.assertRaises(ValueError, f.readlines, 1)
35133514
self.assertRaises(ValueError, f.seek, 0)
35143515
self.assertRaises(ValueError, f.tell)
35153516
self.assertRaises(ValueError, f.truncate)

Misc/NEWS

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,14 @@ Extension Modules
310310
Library
311311
-------
312312

313+
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
314+
hint is present.
315+
313316
- bpo-29694: Fixed race condition in pathlib mkdir with flags
314317
parents=True. Patch by Armin Rigo.
315318

316319
- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
317-
contextlib.contextmanager.
318-
Patch by Siddharth Velankar.
320+
contextlib.contextmanager. Patch by Siddharth Velankar.
319321

320322
- bpo-26187: Test that sqlite3 trace callback is not called multiple
321323
times when schema is changing. Indirectly fixed by switching to

Modules/_io/iobase.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
643643
/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
644644
{
645645
Py_ssize_t length = 0;
646-
PyObject *result;
646+
PyObject *result, *it = NULL;
647647

648648
result = PyList_New(0);
649649
if (result == NULL)
@@ -658,36 +658,45 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
658658
self, NULL);
659659

660660
if (ret == NULL) {
661-
Py_DECREF(result);
662-
return NULL;
661+
goto error;
663662
}
664663
Py_DECREF(ret);
665664
return result;
666665
}
667666

667+
it = PyObject_GetIter(self);
668+
if (it == NULL) {
669+
goto error;
670+
}
671+
668672
while (1) {
669-
PyObject *line = PyIter_Next(self);
673+
PyObject *line = PyIter_Next(it);
670674
if (line == NULL) {
671675
if (PyErr_Occurred()) {
672-
Py_DECREF(result);
673-
return NULL;
676+
goto error;
674677
}
675678
else
676679
break; /* StopIteration raised */
677680
}
678681

679682
if (PyList_Append(result, line) < 0) {
680683
Py_DECREF(line);
681-
Py_DECREF(result);
682-
return NULL;
684+
goto error;
683685
}
684686
length += PyObject_Size(line);
685687
Py_DECREF(line);
686688

687689
if (length > hint)
688690
break;
689691
}
692+
693+
Py_DECREF(it);
690694
return result;
695+
696+
error:
697+
Py_XDECREF(it);
698+
Py_DECREF(result);
699+
return NULL;
691700
}
692701

693702
/*[clinic input]

0 commit comments

Comments
 (0)