Skip to content

Commit d5fa5f3

Browse files
authored
bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1130) (#1150)
1 parent 05bfbcd commit d5fa5f3

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
@@ -3498,6 +3498,7 @@ def test_io_after_close(self):
34983498
self.assertRaises(ValueError, f.readinto1, bytearray(1024))
34993499
self.assertRaises(ValueError, f.readline)
35003500
self.assertRaises(ValueError, f.readlines)
3501+
self.assertRaises(ValueError, f.readlines, 1)
35013502
self.assertRaises(ValueError, f.seek, 0)
35023503
self.assertRaises(ValueError, f.tell)
35033504
self.assertRaises(ValueError, f.truncate)

Misc/NEWS

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ Core and Builtins
3232
Library
3333
-------
3434

35+
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
36+
hint is present.
37+
3538
- bpo-29694: Fixed race condition in pathlib mkdir with flags
3639
parents=True. Patch by Armin Rigo.
3740

38-
- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
39-
contextlib.contextmanager.
40-
Patch by Siddharth Velankar.
41+
- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
42+
contextlib.contextmanager. Patch by Siddharth Velankar.
4143

4244
- bpo-29998: Pickling and copying ImportError now preserves name and path
4345
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)