[Python-Dev] The iterator story

Oren Tirosh oren-py-d@hishome.net
Sat, 20 Jul 2002 09:28:57 -0400


On Fri, Jul 19, 2002 at 04:22:26PM -0700, Neil Schemenauer wrote:
> Neal Norwitz wrote:
> > In what context?  Were you iterating over a file or something else?
> > I'm wondering if this is a problem, perhaps pychecker could generate
> > a warning?
> 
> I was switching between implementing something as a generator and
> returning a list.  I was curious why I was getting different behavior
> until I realized I was iterating over the result twice.  I don't
> think pychecker could warn about such a bug.

That's the scenario that bit me too.  For me it was a little more difficult
to find because it was wrapped in a few layers of chained transformations.
I can't tell by the last element in the chain whether the first one is 
re-iterable or not. 

One approach to solve this is Ka-Ping Yee's proposal to specify in advance
whether you are expecting an iterator or a re-iterable container using
either 'for x in y' or 'for x from y'.  I don't think this will work.
There's already too much code that uses for x in y where y is an iterator.
Another problem is that a transformation shouldn't care whether its upstream 
source is an iterator or an iterable - it's a generic reusable building 
block.

My suggestion (which was rejected by Guido) was to raise an error when an
iterator's .next() method is called afer it raises StopIteration.  This
way, if I try to iterate over the result again at least I'll get and error
like "IteratorExhaustedError" instead something that is indistinguishable
from an iterator of an empty container. I hate silent errors.

This shouldn't be required from all iterator implementers but if all
built-in iterators supported this (especially generators) it would help a
lot to find such errors.

	Oren

P.S. My definition of a transformation is a function taking one iterable
argument and returning an iterator.  It is usually implemented as a
generator function.