[Python-3000] PEP: rename it.next() to it.__next__(), add a next() built-in

Guido van Rossum guido at python.org
Tue Mar 6 22:50:09 CET 2007


On 3/6/07, Brett Cannon <brett at python.org> wrote:
> On 3/6/07, Georg Brandl <g.brandl at gmx.net> wrote:
> > Guido van Rossum schrieb:
> > > Having now read this entire thread I am going to accept Ping's PEP.
> > > Adding the sentinel argument to the next() builtin was what did it for
> > > me: it neatly solves the problem if having to catch that StopIteration
> > > in 99% of the cases.
> >
> > Attached is a possible implementation for the next() function, regardless
> > of how the next method is going to be called in the future.
> >
> > Georg
> >
> >
> > Index: Python/bltinmodule.c
> > ===================================================================
> > --- Python/bltinmodule.c        (Revision 54016)
> > +++ Python/bltinmodule.c        (Arbeitskopie)
> > @@ -1029,6 +1029,45 @@
> >
> >
> >  static PyObject *
> > +builtin_next(PyObject *self, PyObject *args)
> > +{
> > +       PyObject *it, *res;
> > +       PyObject *def = NULL;
> > +
> > +       if (!PyArg_UnpackTuple(args, "next", 1, 2, &it, &def))
> > +               return NULL;
> > +       if (!PyIter_Check(it)) {
> > +               PyErr_Format(PyExc_TypeError,
> > +                       "%.200s object is not an iterator", it->ob_type->tp_name);
> > +               return NULL;
> > +       }
> > +
> > +       res = (*it->ob_type->tp_iternext)(it);
> > +       if (res == NULL) {
> > +               if (def) {
> > +                       if (PyErr_Occurred() &&
> > +                           !PyErr_ExceptionMatches(PyExc_StopIteration))
> > +                               return NULL;
> > +                       Py_INCREF(def);
> > +                       return def;
> > +               } else if (PyErr_Occurred()) {
> > +                       return NULL;
> > +               } else {
> > +                       PyErr_SetNone(PyExc_StopIteration);
> > +                       return NULL;
> > +               }
> > +       }
> > +       return res;
> > +}
>
> http://docs.python.org/dev/api/type-structs.html#l2h-1017 doesn't say
> that a NULL return can be used as a signal that iterator is exhausted
> without raising StopIteration.  That would mean the above could be
> simplified somewhat in terms of return value checking.

But in practice a NULL without an error is often used (and was
intended to be valid).

The code should clear the exception though if it *is* set and def is returned.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list