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 GeneratorExit. To my mind, the practical benefits of such an approach are enough to justify the deviation from the general 'inline behaviour' guideline. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------