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