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