[Python-ideas] Yield-From: Finalization guarantees

Nick Coghlan ncoghlan at gmail.com
Tue Mar 31 14:08:30 CEST 2009

Jacob Holm wrote:
> My guess is that your preference is more like 4, 3, 2, 1.  #3 is closest
> to what is in the current PEP, and is probably what it meant to say.
> (The PEP checks if the thrown exception was GeneratorExit, then does a
> bare raise instead of raising the thrown exception).

4, 3, 2, 1 is the position I've come around to. Since using send(),
throw() and close() on a shared subiterator doesn't make any sense, and
the whole advantage of the new expression over a for loop is to make it
easy to delegate send() throw() and close() correctly, I now believe
that shared subiterators are best handled by actually *iterating* over
them in a for loop rather than by delegating to them with "yield from".

So the fact that a definition of yield from that provides prompt
finalisation guarantees isn't friendly to using it with shared
subiterators is actually now a *bonus* in my book - it should hopefully
serve as a hint to developers that they're misusing the tool.

By adopting position 4, I believe the guarantees for the exception
handling in the new expression become as simple as possible:
 - if the subiterator does not provide a throw() method, or the
exception thrown in is GeneratorExit, then the subiterator's close()
method (if any) is called and the thrown in exception raised in the
current frame
 - otherwise, the exception (including traceback) is passed down to the
subiterator's throw() method

With these semantics, subiterators will be finalised promptly when the
outermost generator is finalised without any special effort on the
developer's part and it won't be trivially easy to accidentally suppress

To my mind, the practical benefits of such an approach are enough to
justify the deviation from the general 'inline behaviour' guideline.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list