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

Jacob Holm jh at improva.dk
Wed Apr 22 17:18:18 CEST 2009


Hi Erik

Erik Groeneveld wrote:
> 
>>    * If a GeneratorExit exception is thrown into the delegating generator,
>>      or the ``close()`` method of the delegating generator is called, then
>>      the ``close()`` method of the iterator is called if it has one. If this
>>      call results in an exception, it is propagated to the delegating generator.
>>      Otherwise, GeneratorExit is raised in the delegating generator.
> 
> I tried to implement this, but I failed.  The reason is that a
> generator's close() checks for an exception being raised by its
> generator.  When no exception has been raised, it will raise the
> RuntimeError('generator ignored GeneratorExit').  And when an
> exception has been raised (regardless what type), it will exit just
> normally.


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()


This looks like close() doesn't actually behave as it should according 
to PEP342.  Interesting...

I would call that a bug.


>  So the phrase
> 
>> If this
>>      call results in an exception, it is propagated to the delegating generator.
> 
> applies only to the RuntimeError close() might throw.  And the ramaining phrase
> 
>>      Otherwise, GeneratorExit is raised in the delegating generator.
> 
> makes it behave no different than for all other types of exceptions.
> 
> Was this intended?  If Yes, I suggest to make the text clearer and
> more specific about it.  If No, then what is the correct expansion?


The assumption was that close() would behave as described in PEP342, 
which would make the description in the yield-from PEP380 correct.

I can't believe that none of us actually tested that...

Cheers
- Jacob




More information about the Python-ideas mailing list