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 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?