[Python-Dev] patch: try/finally in generators

Tim Peters tim.one@comcast.net
Mon, 29 Jul 2002 17:42:50 -0400


[Neil Schemenauer]
> ...
> Basically, the GC has to be taught that generators can have finalizers
> and it may not be safe to collect them.  If we allow try/finally in
> generators

Note that we already allow try/finally in generators.  The only prohibition
is against having a yield stmt in the try clause of a try/finally construct
(YINTCOATFC).

> then they can cause uncollectible garbage.  It's not a show
> stopper but something else to take into consideration.

I'm concerned about semantic clarity.  A "finally" block is supposed to get
executed upon leaving its associated "try" block.  A yield stmt doesn't
leave the try block in that sense, so there's no justification for executing
the finally block unless the generator is resumed, and the try block is
exited "for real" via some other means (a return, an exception, or falling
off the end of the try block).  We could have allowed YINTCOATFC under those
rules with clarity, but it would have been a great surprise then that the
finally clause may never get executed at all.  Better to outlaw it than that
(or, as the PEP says, that would be "too much a violation of finally's
purpose to bear").

Making up new control flow out of thin air upon destructing a generator
("OK, let's pretend that the generator was actually resumed in that case,
and also pretend that a return statement immediately followed the yield") is
plainly a hack; and because it's still possible then that the finally clause
may never get executed at all (because it's possible to create an
uncollectible generator), it's too much a violation of finally's purpose to
bear even so.

When I've needed resource-cleanup in a generator, I've made the generator a
method of a class, and put the resources in instance variables.  Then
they're easy to clean up at will (even via a __del__ method, if need be; but
the uncertainty about when and whether __del__ methods get called is already
well-known, and I don't want to extend that fuzziness to 'finally' clauses
too -- we left those reliable against anything short of a system crash, and
IMO it's important to keep them that bulletproof).