[Python-ideas] Yield-From: Finalization guarantees
greg.ewing at canterbury.ac.nz
Mon Mar 30 07:45:51 CEST 2009
The problem of how to handle GeneratorExit doesn't
seem to have any entirely satisfactory solution.
On the one hand, the inlining principle requires that
we never re-raise it if the subgenerator turns it into
a StopIteration (or GeneratorReturn).
On the other hand, not re-raising it means that a
broken generator can easily result from innocuously
combining two things that are individually legitimate.
I think we just have to accept this, and state that
refactoring only preserves semantics as long as the
code block being factored out does not catch
GeneratorExit without re-raising it. Then we're free
to always re-raise GeneratorExit and prevent broken
generators from occurring.
I'm inclined to think this situation is a symptom that
the idea of being able to catch GeneratorExit at all
is flawed. If generator finalization were implemented
by means of a forced return, or something equally
uncatchable, instead of an exception, we wouldn't have
so much of a problem.
Earlier I said that I thought GeneratorExit was best
regarded as an implementation detail of generators.
I'd like to strengthen that statement and say that it
should be considered a detail of the *present*
implementation of generators, subject to change in
future or alternate Pythons.
Related to that, I'm starting to come back to my
original instinct that GeneratorExit should not be
thrown into the subiterator at all. Rather, it should
be taken as an indication that the delegating generator
is being finalized, and the subiterator's close()
method called if it has one. Then there's never any
question about whether to re-raise it -- we should
always do so.
More information about the Python-ideas