[Python-ideas] Yield-From: Finalization guarantees
ncoghlan at gmail.com
Tue Mar 24 22:13:26 CET 2009
Greg Ewing wrote:
> We have a decision to make. It appears we can have
> *one* of the following, but not both:
> (1) In non-refcounting implementations, subiterators
> are finalized promptly when the delegating generator
> is explicitly closed.
> (2) Subiterators are not prematurely finalized when
> other references to them exist.
> Since in the majority of intended use cases the
> subiterator won't be shared, (1) seems like the more
> important guarantee to uphold. Does anyone disagree
> with that?
If you choose (2), then (1) is trivial to implement in code that uses
the new expression in combination with existing support for
deterministic finalisation. For example:
with contextlib.closing(make_subiter()) as subiter:
yield from subiter
On the other hand, if you choose (1), then it is impossible to use that
construct in combination with any other existing constructs to avoid
finalisation - you have to write out the equivalent code from the PEP by
hand, leaving out the finalisation parts.
So I think dropping the implicit finalisation is the better option - it
simplifies the new construct, and plays well with explicit finalisation
when that is what people want.
However, I would also recommend *not* special casing GeneratorExit in
that case: just pass it down using throw.
Note that non-generator iterators that want "throw" to mean the same
thing as "close" can do that easily enough:
def throw(self, *args):
(reraise itself would just do the dance to check how many arguments
there were and use the appropriate form of "raise" to reraise the exception)
Hmm, that does suggest another issue with the PEP however: it only calls
the subiterator's throw with the value of the thrown in exception. It
should be using the 3 argument form to avoid losing any passed in
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas