]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Make PyIter_Next() a little smarter (wrt its knowledge of iterator
authorTim Peters <tim.peters@gmail.com>
Sat, 5 May 2001 00:14:56 +0000 (00:14 +0000)
committerTim Peters <tim.peters@gmail.com>
Sat, 5 May 2001 00:14:56 +0000 (00:14 +0000)
internals) so clients can be a lot dumber (wrt their knowledge).

Include/abstract.h
Objects/abstract.c
Python/bltinmodule.c
Python/ceval.c

index 1dae5f144264489fd37cb7246e76e723507f09ea..ac9e568ef0ef5e6f8e4449528f75bbdb84503d67 100644 (file)
@@ -484,9 +484,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
      DL_IMPORT(PyObject *) PyIter_Next(PyObject *);
      /* Takes an iterator object and calls its tp_iternext slot,
        returning the next value.  If the iterator is exhausted,
-       this can return NULL without setting an exception, *or*
-       NULL with a StopIteration exception.
-       NULL with any other exception  means an error occurred. */
+       this returns NULL without setting an exception.
+       NULL with an exception means an error occurred. */
 
 /*  Number Protocol:*/
 
index 8ee1e5a19025c37364fa689c8401fdddb5f94923..7133867684b9e76633811959701cca010929dba4 100644 (file)
@@ -1276,17 +1276,9 @@ PySequence_List(PyObject *v)
        for (i = 0; ; i++) {
                PyObject *item = PyIter_Next(it);
                if (item == NULL) {
-                       /* We're out of here in any case, but if this is a
-                        * StopIteration exception it's expected, but if
-                        * any other kind of exception it's an error.
-                        */
                        if (PyErr_Occurred()) {
-                               if (PyErr_ExceptionMatches(PyExc_StopIteration))
-                                       PyErr_Clear();
-                               else {
-                                       Py_DECREF(result);
-                                       result = NULL;
-                               }
+                               Py_DECREF(result);
+                               result = NULL;
                        }
                        break;
                }
@@ -1796,14 +1788,27 @@ PyObject_GetIter(PyObject *o)
        }
 }
 
+/* Return next item.
+ * If an error occurs, return NULL.  PyErr_Occurred() will be true.
+ * If the iteration terminates normally, return NULL and clear the
+ * PyExc_StopIteration exception (if it was set).  PyErr_Occurred()
+ * will be false.
+ * Else return the next object.  PyErr_Occurred() will be false.
+ */
 PyObject *
 PyIter_Next(PyObject *iter)
 {
+       PyObject *result;
        if (!PyIter_Check(iter)) {
                PyErr_Format(PyExc_TypeError,
                             "'%.100s' object is not an iterator",
                             iter->ob_type->tp_name);
                return NULL;
        }
-       return (*iter->ob_type->tp_iternext)(iter);
+       result = (*iter->ob_type->tp_iternext)(iter);
+       if (result == NULL &&
+           PyErr_Occurred() &&
+           PyErr_ExceptionMatches(PyExc_StopIteration))
+               PyErr_Clear();
+       return result;
 }
index 5209607df154d1db00cf90c356ddf5b0442affd7..4a51ccd98a1279287fe3f4511ae3090370033eeb 100644 (file)
@@ -164,7 +164,7 @@ builtin_filter(PyObject *self, PyObject *args)
 {
        PyObject *func, *seq, *result, *it;
        int len;   /* guess for result list size */
-       register int i, j;
+       register int j;
 
        if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq))
                return NULL;
@@ -204,22 +204,15 @@ builtin_filter(PyObject *self, PyObject *args)
        }
 
        /* Build the result list. */
-       for (i = j = 0; ; ++i) {
+       j = 0;
+       for (;;) {
                PyObject *item, *good;
                int ok;
 
                item = PyIter_Next(it);
                if (item == NULL) {
-                       /* We're out of here in any case, but if this is a
-                        * StopIteration exception it's expected, but if
-                        * any other kind of exception it's an error.
-                        */
-                       if (PyErr_Occurred()) {
-                               if (PyErr_ExceptionMatches(PyExc_StopIteration))
-                                       PyErr_Clear();
-                               else
-                                       goto Fail_result_it;
-                       }
+                       if (PyErr_Occurred())
+                               goto Fail_result_it;
                        break;
                }
 
@@ -1030,24 +1023,14 @@ builtin_map(PyObject *self, PyObject *args)
                                if (item)
                                        ++numactive;
                                else {
-                                       /* StopIteration is *implied* by a
-                                        * NULL return from PyIter_Next() if
-                                        * PyErr_Occurred() is false.
-                                        */
                                        if (PyErr_Occurred()) {
-                                               if (PyErr_ExceptionMatches(
-                                                   PyExc_StopIteration))
-                                                       PyErr_Clear();
-                                               else {
-                                                       Py_XDECREF(alist);
-                                                       goto Fail_1;
-                                               }
+                                               Py_XDECREF(alist);
+                                               goto Fail_1;
                                        }
                                        Py_INCREF(Py_None);
                                        item = Py_None;
                                        sqp->saw_StopIteration = 1;
                                }
-
                        }
                        if (alist)
                                PyTuple_SET_ITEM(alist, j, item);
@@ -1445,7 +1428,6 @@ Return the dictionary containing the current scope's local variables.";
 static PyObject *
 min_max(PyObject *args, int op)
 {
-       int i;
        PyObject *v, *w, *x, *it;
 
        if (PyTuple_Size(args) > 1)
@@ -1458,21 +1440,13 @@ min_max(PyObject *args, int op)
                return NULL;
 
        w = NULL;  /* the result */
-       for (i = 0; ; i++) {
+       for (;;) {
                x = PyIter_Next(it);
                if (x == NULL) {
-                       /* We're out of here in any case, but if this is a
-                        * StopIteration exception it's expected, but if
-                        * any other kind of exception it's an error.
-                        */
                        if (PyErr_Occurred()) {
-                               if (PyErr_ExceptionMatches(PyExc_StopIteration))
-                                       PyErr_Clear();
-                               else {
-                                       Py_XDECREF(w);
-                                       Py_DECREF(it);
-                                       return NULL;
-                               }
+                               Py_XDECREF(w);
+                               Py_DECREF(it);
+                               return NULL;
                        }
                        break;
                }
@@ -1880,16 +1854,9 @@ builtin_reduce(PyObject *self, PyObject *args)
 
                op2 = PyIter_Next(it);
                if (op2 == NULL) {
-                       /* StopIteration is *implied* by a NULL return from
-                        * PyIter_Next() if PyErr_Occurred() is false.
-                        */
-                       if (PyErr_Occurred()) {
-                               if (PyErr_ExceptionMatches(PyExc_StopIteration))
-                                       PyErr_Clear();
-                               else
-                                       goto Fail;
-                       }
-                       break;
+                       if (PyErr_Occurred())
+                               goto Fail;
+                       break;
                }
 
                if (result == NULL)
index df160f2cc35da86b1e90cfc6a9e60a4bdcf19d02..0cdd0199b965e10df1b5b1e3e371079a3010be00 100644 (file)
@@ -1894,11 +1894,9 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
                                PUSH(x);
                                continue;
                        }
-                       if (!PyErr_Occurred() ||
-                           PyErr_ExceptionMatches(
-                                   PyExc_StopIteration))
-                       {
-                               x = v = POP();
+                       if (!PyErr_Occurred()) {
+                               /* iterator ended normally */
+                               x = v = POP();
                                Py_DECREF(v);
                                JUMPBY(oparg);
                                continue;