[Python-ideas] "Iteration stopping" syntax [Was: Is this PEP-able? for X in ListY while conditionZ:]

Steven D'Aprano steve at pearwood.info
Mon Jul 1 02:59:05 CEST 2013


On 01/07/13 08:08, Greg Ewing wrote:
> Ron Adam wrote:
>> It's the same as in-lineing the generator parts into the iterator that is driving it.
>>
>> We don't need to do that because we already have an optimised version of that.  It just needs to catch the StopIteration to be the same.
>>
>> I think that it's not uncommon for people to think this is how list comps work.  And I think it is surprising for them that the StopIteration isn't caught.
>
> I tend to feel that the fact that raising StopIteration in a
> generator has the same effect as returning from the generator
> is a quirk of the implementation that shouldn't be relied on.
> I'm not sure we should be giving it official status by going
> out of our way to make listcomps behave the same.


Raising StopIteration has been one of the two official ways to halt a generator, and has been since they were introduced. I nearly wrote "has been documented as..." except it seems to me that it has never been explicitly stated in the docs or the PEP. The closest I can find is this part of the PEP that *implies*, without actually coming right out and saying so, that raising StopIteration is the official way to halt a generator:


[quote]
Q. Why allow "return" at all?  Why not force termination to be spelled
    "raise StopIteration"?

A. The mechanics of StopIteration are low-level details, much like the
    mechanics of IndexError in Python 2.1:  the implementation needs to
    do *something* well-defined under the covers, and Python exposes
    these mechanisms for advanced users.  That's not an argument for
    forcing everyone to work at that level, though.  "return" means "I'm
    done" in any kind of function, and that's easy to explain and to use.
    Note that "return" isn't always equivalent to "raise StopIteration"
    in try/except construct, either (see the "Specification: Return"
    section).
[end quote]

http://www.python.org/dev/peps/pep-0255/

Generally the PEP talks about how generators which have already been stopped (due to some unhandled exception, or a return) will raise StopIteration, but otherwise emphasize using return rather than StopIteration.

The What's New for 2.2 does explicitly say you can raise StopIteration to halt a generator, but almost as an afterthought. In contrast, StopIteration is explicitly stated to be the way to signal that an iterator is halted.

http://docs.python.org/3.4/whatsnew/2.2.html#pep-234-iterators

So I think the missing piece is that generators are actually iterators. Since raising StopIteration is the official way to halt an iterator, it's also the (or at least, an) official way to halt a generator, and not a quirk of the implementation.



-- 
Steven


More information about the Python-ideas mailing list