[Python-ideas] Revised**12 PEP on Yield-From

Jim Pryor lists+python-ideas at jimpryor.net
Thu Apr 23 02:09:33 CEST 2009


On Wed, Apr 22, 2009 at 06:05:11PM +0200, Erik Groeneveld wrote:
> 2009/4/22 Jacob Holm <jh at improva.dk>:
> > In other words, the ValueError in the following example is swallowed
> > by close():
> >
> >
> >>>> def foo():
> > ...     yield 'bar'
> > ...     raise ValueError('baz')
> >>>> g = foo()
> >>>> g.next()
> > 'bar'
> >>>> g.close()
> >
>
> I have the same code here, it does not raise an exception indeed.
>
> > This looks like close() doesn't actually behave as it should
> > according to PEP342.  Interesting...
>
> From PEP342 (Thanks Jacob, for the reference):
>
> 4. Add a close() method for generator-iterators, which raises
>        GeneratorExit at the point where the generator was paused.  If
>        the generator then raises StopIteration (by exiting normally,
>        or
>        due to already being closed) or GeneratorExit (by not catching
>        the exception), close() returns to its caller.  If the
>        generator
>        yields a value, a RuntimeError is raised.  If the generator
>        raises any other exception, it is propagated to the caller.
>        close() does nothing if the generator has already exited due to
>        an exception or normal exit.
>
>
> > I would call that a bug.
>
> I agree with that.

I don't understand why you're both counting this as a bug. It looks like
exactly the behavior specified in PEP 342. When g.close() is evaluated,
a GeneratorExit is thrown to the suspended 'yield' expression in foo.
That exception is is not caught, so g terminates without executing the
rest of its code. The 'raise ValueError' line is never executed.

-- 
Jim Pryor
jim at jimpryor.net



More information about the Python-ideas mailing list