bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present ...
authorXiang Zhang <angwerzx@126.com>
Sat, 15 Apr 2017 04:47:28 +0000 (12:47 +0800)
committerGitHub <noreply@github.com>
Sat, 15 Apr 2017 04:47:28 +0000 (12:47 +0800)
Lib/test/test_io.py
Misc/NEWS
Modules/_io/iobase.c

index 929865d9565998afc08f92645b86b1ac7593ae99..32f76a6c627186f218f976d5dc08a9868a779bf7 100644 (file)
@@ -3510,6 +3510,7 @@ class MiscIOTest(unittest.TestCase):
                 self.assertRaises(ValueError, f.readinto1, bytearray(1024))
             self.assertRaises(ValueError, f.readline)
             self.assertRaises(ValueError, f.readlines)
+            self.assertRaises(ValueError, f.readlines, 1)
             self.assertRaises(ValueError, f.seek, 0)
             self.assertRaises(ValueError, f.tell)
             self.assertRaises(ValueError, f.truncate)
index c780241383ee38677957c4c5e5a7a15649220958..da40d8f5a007c05a04a9f30a2a9588f80ac47167 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -310,12 +310,14 @@ Extension Modules
 Library
 -------
 
+- bpo-30068: _io._IOBase.readlines will check if it's closed first when
+  hint is present.
+
 - bpo-29694: Fixed race condition in pathlib mkdir with flags
   parents=True.  Patch by Armin Rigo.
 
 - bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in
-  contextlib.contextmanager.
-  Patch by Siddharth Velankar.
+  contextlib.contextmanager.  Patch by Siddharth Velankar.
 
 - bpo-26187: Test that sqlite3 trace callback is not called multiple
   times when schema is changing.  Indirectly fixed by switching to
index 75cfe59624bfb95d76f9e38a8bf48b7ca947e206..1a687c517bb36b9226d0b086b3a7042e3e198fde 100644 (file)
@@ -643,7 +643,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
 /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
 {
     Py_ssize_t length = 0;
-    PyObject *result;
+    PyObject *result, *it = NULL;
 
     result = PyList_New(0);
     if (result == NULL)
@@ -658,19 +658,22 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
                                                       self, NULL);
 
         if (ret == NULL) {
-            Py_DECREF(result);
-            return NULL;
+            goto error;
         }
         Py_DECREF(ret);
         return result;
     }
 
+    it = PyObject_GetIter(self);
+    if (it == NULL) {
+        goto error;
+    }
+
     while (1) {
-        PyObject *line = PyIter_Next(self);
+        PyObject *line = PyIter_Next(it);
         if (line == NULL) {
             if (PyErr_Occurred()) {
-                Py_DECREF(result);
-                return NULL;
+                goto error;
             }
             else
                 break; /* StopIteration raised */
@@ -678,8 +681,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
 
         if (PyList_Append(result, line) < 0) {
             Py_DECREF(line);
-            Py_DECREF(result);
-            return NULL;
+            goto error;
         }
         length += PyObject_Size(line);
         Py_DECREF(line);
@@ -687,7 +689,14 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
         if (length > hint)
             break;
     }
+
+    Py_DECREF(it);
     return result;
+
+ error:
+    Py_XDECREF(it);
+    Py_DECREF(result);
+    return NULL;
 }
 
 /*[clinic input]