[Python-ideas] Change how Generator Expressions handle StopIteration

Guido van Rossum guido at python.org
Fri Nov 7 18:10:42 CET 2014

Trying to keep the thread on focus...

On Fri, Nov 7, 2014 at 3:20 AM, Steven D'Aprano <steve at pearwood.info> wrote:

> On Thu, Nov 06, 2014 at 10:54:51AM -0800, Guido van Rossum wrote:
> > If I had had the right foresight, I would have made it an error to
> > terminate a generator with a StopIteration, probably by raising another
> > exception chained to the StopIteration (so the traceback shows the place
> > where the StopIteration escaped).
> >
> > The question at hand is if we can fix this post-hoc, using clever tricks
> > and (of course) a deprecation period.
> Do we need "clever tricks"? In my earlier email, I suggested that if
> this needs to be fixed, the best way to introduce a change in
> behaviour is with the __future__ mechanism. 3.5 could introduce
>     from __future__ stopiteration_is_an_error
> (in my earlier post, I managed to get the suggested behaviour completely
> backwards) and then 3.6 could raise a warning and 3.7 could make it
> the default behaviour.

Sure. (Though IMO __future__ itself is a clever hack.)

> We're still breaking backwards compatibility, but at least we're doing
> it cleanly, without clever and/or ugly hacks. There will be a transition
> period during which people can choose to keep the old behaviour or the
> new, and then we transition to the new behaviour.

We'd still need to specify the eventual behavior. I propose the following
as a strawman (after the deprecation period is finished and the __future__
import is no longer needed):

- If a StopIteration is about to bubble out of a generator frame, it is
replaced with some other exception (maybe RuntimeError, maybe a new custom
Exception subclass, but *not* deriving from StopIteration) which causes the
next() call (which invoked the generator) to fail, passing that exception
out. From then on it's just like any old exception.

During the transition, we check if the generator was defined in the scope
of the __future__, and if so, we do the the same thing; otherwise, we issue
a warning and let the StopIteration bubble out, eventually terminating some
loop or generator expression.

It would be nice if, when the warning is made fatal (e.g. through the -W
flag), the exception raised was the same one mentioned above (i.e.
RuntimeError or a custom subclass -- I don't care much about this detail).

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20141107/5756644c/attachment-0001.html>

More information about the Python-ideas mailing list