On Sat, Oct 30, 2010 at 5:09 PM, Greg Ewing email@example.com wrote:
Guido van Rossum wrote:
A different approach to fixing this is for the throwing code to keep throwing EOFError until the generator stops yielding values:
That's precisely what I would recommend.
This solution doesn't quite work though, because the count returned will include the nodes that were yielded while the stack of generators was winding down.
My pragmatic solution for this is to change the protocol so that stopping the generator means that the node yielded last should not be included in the count.
This whole example seems contrived to me, so it's hard to say whether this is a good or bad solution.
I tried to come up with an example that made non-trivial use of yield-from. Iterating over a binary tree is about the most natural example I could think of. The desire to interrupt the iteration in the middle also seems natural. I agree that the addition of a return value for the whole generator is somewhat contrived. Maybe a better value to return would have been the maximum depth encountered?
I propose to modify g.close() to keep throwing GeneratorExit until the generator stops yielding values, and then capture the return value from StopIteration if that is what was raised. The beauty is then that the PEP 380 expansion can stop special-casing GeneratorExit: it just treats it as every other exception.
This was actually suggested during the initial round of discussion, and shot down -- if I remember correctly, on the grounds that it could result in infinite loops. But if you're no longer concerned about that, it's worth considering.
My concern is that this would be a fairly substantial change to the intended semantics of close() -- it would no longer be a way of aborting a generator and forcing it to clean up as quickly as possible.
But maybe you don't mind losing that functionality?
I've thought about this long and hard, and in the end I do mind losing the special semantics of GeneratorExit. I am withdrawing my proposal. I don't think the PEP should be weighed down with a separate method + exception to request a return value either -- rather, a framework that needs such functionality can create a local convention. I doubt that the intermingling of frameworks will be such that that is much of a burden for framework users -- if it is, we can always write a PEP to standardize such a convention later.
With this, I think PEP 380 can be accepted pretty much as is, although it would be nice if a part of my example made it into the PEP -- I don't think there is anything wrong with PEPs having examples.