Skip to content

Commit 4f43f87

Browse files
authored
bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1130) (#1151)
1 parent f40e72d commit 4f43f87

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

Lib/test/test_io.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3466,6 +3466,7 @@ def test_io_after_close(self):
34663466
self.assertRaises(ValueError, f.readinto1, bytearray(1024))
34673467
self.assertRaises(ValueError, f.readline)
34683468
self.assertRaises(ValueError, f.readlines)
3469+
self.assertRaises(ValueError, f.readlines, 1)
34693470
self.assertRaises(ValueError, f.seek, 0)
34703471
self.assertRaises(ValueError, f.tell)
34713472
self.assertRaises(ValueError, f.truncate)

Misc/NEWS

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ Extension Modules
4949
Library
5050
-------
5151

52+
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
53+
hint is present.
54+
5255
- bpo-29694: Fixed race condition in pathlib mkdir with flags
5356
parents=True. Patch by Armin Rigo.
5457

55-
- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
56-
contextlib.contextmanager.
57-
Patch by Siddharth Velankar.
58+
- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
59+
contextlib.contextmanager. Patch by Siddharth Velankar.
5860

5961
- bpo-29998: Pickling and copying ImportError now preserves name and path
6062
attributes.

Modules/_io/iobase.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
650650
/*[clinic end generated code: output=2f50421677fa3dea input=1961c4a95e96e661]*/
651651
{
652652
Py_ssize_t length = 0;
653-
PyObject *result;
653+
PyObject *result, *it = NULL;
654654

655655
result = PyList_New(0);
656656
if (result == NULL)
@@ -664,36 +664,45 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
664664
PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self);
665665

666666
if (ret == NULL) {
667-
Py_DECREF(result);
668-
return NULL;
667+
goto error;
669668
}
670669
Py_DECREF(ret);
671670
return result;
672671
}
673672

673+
it = PyObject_GetIter(self);
674+
if (it == NULL) {
675+
goto error;
676+
}
677+
674678
while (1) {
675-
PyObject *line = PyIter_Next(self);
679+
PyObject *line = PyIter_Next(it);
676680
if (line == NULL) {
677681
if (PyErr_Occurred()) {
678-
Py_DECREF(result);
679-
return NULL;
682+
goto error;
680683
}
681684
else
682685
break; /* StopIteration raised */
683686
}
684687

685688
if (PyList_Append(result, line) < 0) {
686689
Py_DECREF(line);
687-
Py_DECREF(result);
688-
return NULL;
690+
goto error;
689691
}
690692
length += PyObject_Size(line);
691693
Py_DECREF(line);
692694

693695
if (length > hint)
694696
break;
695697
}
698+
699+
Py_DECREF(it);
696700
return result;
701+
702+
error:
703+
Py_XDECREF(it);
704+
Py_DECREF(result);
705+
return NULL;
697706
}
698707

699708
/*[clinic input]

0 commit comments

Comments
 (0)