[Python-ideas] Yield-From: Finalization guarantees

Jacob Holm jh at improva.dk
Sun Mar 29 14:33:51 CEST 2009


Greg Ewing wrote:
> Nick Coghlan wrote:
>
>> Generators that catch and do anything with GeneratorExit other than turn
>> it into StopIteration are almost always going to be broken - the new
>> expression needs to avoid making it easy to do that accidentally.
>
> However, as this example shows, the suggested solution
> of reraising GeneratorExit is not viable because it
> violates the inlining principle.
>
> The basic problem is that there's no way of telling the
> difference between a StopIteration that means "it's okay,
> I've finalized myself" and "I really mean to return
> normally here".
>

Would it be possible to attach the current exception (if any) to the 
StopIteration/GeneratorReturn raised by a return statement in a finally 
clause? (Using the __traceback__ and __cause__ attributes from PEP-3134) 
Then the PEP expansion could check for and reraise the attached 
exception. Now that I think about it, this is almost required by the 
inlining/refactoring principle. Consider this example:

def inner():
    try:
        yield 1
        yield 2
        yield 3
    finally:
        return 'VALUE'

def outer():
    val = yield from inner()
    print val


Which I think should be equivalent to:

def outer():
    try:
        yield 1
        yield 2
        yield 3
    finally:
        val = 'VALUE'
    print val


The problem is that any exception thrown into inner is converted to a 
GeneratorReturn, which is then swallowed by the yield-from instead of 
being reraised.

- Jacob



More information about the Python-ideas mailing list