Trying to keep the thread on focus...

On Fri, Nov 7, 2014 at 3:20 AM, Steven D'Aprano <steve@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)