[Python-Dev] Termination of two-arg iter()

Guido van Rossum guido@python.org
Tue, 16 Jul 2002 08:49:36 -0400


> > It means that the implementation of various iterators can be a little
> > simpler, because no next() implementation needs to be given.
> 
> I'm not sure that's a feature we always want to use.  Going thru a wrapper
> function (a) adds another layer of function call, and (b) adds a
> 
> 	if (!PyArg_ParseTuple(args, ""))
> 		return NULL;
> 
> call via wrap_next().  Both expenses could be avoided if an existing
> next method were left alone.  I suppose only the seoond expense is
> actually "real", though, as most explicit xyz_next methods naturally
> call the tp_iternext slot function anyway.  Still, when the body of
> a "next" method is as simple as it is for lists, a call to
> PyArg_ParseTuple is a significant overhead.

I'm not worried.  There's considerable expense in the attribute lookup
for the next method too, if you call it from Python, which probably
drowns the PyArg_ParseTuple overhead.  The whole idea is that usually
the tp_iternext slot will be used directly, and as long as that's
fast, I'm happy.  (If you're not, we can always write faster code to
check for no arguments here.)

The code in typeobject.c maintains a correspondence between
tp_iternext and the next() method, just like it does for tp_iter and
__iter__(), and for tp_hash and __hash__().  It goes both ways: if you
assign to C.next, the tp_iternext slot will be set to a wrapper that
calls C.next().

This also prevents inconsistency between next() and tp_iternext.
(Both the list iterator and hotshot had broken next() implementations,
BTW.)

It needs to be documented, though!

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