[Python-ideas] Yield-From: Finalization guarantees

Jacob Holm jh at improva.dk
Wed Apr 1 03:45:25 CEST 2009


Greg Ewing wrote:
> Jacob Holm wrote:
>
>> will also remove some behavior that could have been useful, such as 
>> the ability to suppress the GeneratorExit if you know what you are 
>> doing.
>
> I'm not convinced there are any use cases for suppressing
> GeneratorExit in the first place. Can you provide an
> example that couldn't be easily done some other way?

I don't have any real use cases, just a few examples of things you can 
do in #2 that become a bit uglier in #3 or #4. This:

def inner():
    try:
        for i in xrange(10):
            yield i
    except GeneratorExit:
        return i
    return "all"

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


Does not behave like you would expect because the "return i" is 
swallowed by the call to inner.close() (or is it?) and the "print val" 
and "return val" statements are skipped due to the reraised 
GeneratorExit. To get the a value out of the generator being closed you 
need to raise and catch your own exception:

class Return(Exception): pass

def inner():
    try:
        for i in xrange(10):
            yield i
    except GeneratorExit:
        raise Return(i)
    return "all"

def outer():
    try:
        val = yield from inner()
    except Return as r:
        val = r.args[0]
    print val
    return val


This is certainly doable, but ugly compared to the version using return.

Here is an idea that would help this a little bit. We could change close 
to return the value (if any) returned by the generator, and then attach 
that value to the reraised GeneratorExit in the yield-from expansion. 
That would allow the example to be rewritten as:

def inner():
    try:
        for i in xrange(10):
            yield i
    except GeneratorExit:
        return i
    return "all"

def outer():
    try:
        val = yield from inner()
    except GeneratorExit as e:
        val = e.value
    print val
    return val


Which I think is much nicer.

- Jacob




More information about the Python-ideas mailing list