[Python-ideas] Yield-From: Finalization guarantees

Greg Ewing greg.ewing at canterbury.ac.nz
Thu Mar 26 06:40:46 CET 2009


Jacob Holm wrote:

>  Can you explain in a little more detail how the 
> inlining argument makes you want to not catch a StopIteration escaping 
> from throw?

It's easier to see if we use an example that doesn't
involve a return value, since it's clearer what
"inlining" means in that case.

def inner():
    try:
        yield 1
    except ValueError:
        pass

def outer():
    print "About to yield from inner"
    yield from inner()
    print "Finished yielding from inner"

Now if we inline that, we get:

def outer_and_inner():
    print "About to yield from inner"
    try:
        yield 1
    except ValueError:
        pass
    print "Finished yielding from inner"

What would you expect that to do if you throw StopIteration
into it while it's suspended at the yield?

However, thinking about the return value case has made me
realize that it's not so obvious what "inlining" means then.
To get the return value in your example, one way would be to
perform the inlining like this:

def outer():
    try:
       try:
           yield 1
       except ValueError:
           pass
       raise StopIteration(2)
    except StopIteration, e:
       v = e.value
    yield v

which results in the behaviour you are expecting.

However, if you were inlining an ordinary function, that's
not how you would handle a return value -- rather, you'd
just replace the return by a statement that assigns the
return value to wherever it needs to go. Using that strategy,
we get

def outer():
    try:
        yield 1
    except ValueError:
        pass
    v = 2
    yield v

That's closer to what I have in mind when I talk about
"inlining" in the PEP.

I realize that this is probably not exactly what the current
expansion specifies. I'm working on a new one to fix issues
like this.

-- 
Greg



More information about the Python-ideas mailing list