[Python-Dev] Re: [Python-iterators] Python generators and try/finally..

Neil Schemenauer nas@python.ca
Mon, 14 Jan 2002 15:42:13 -0800


[Cross-posted to python-dev, I'm not sure how many people are still on
the python-iterators list]

David Jeske wrote:
> Hello,
> 
> I just read PEP255 about Python Generators. It's a very interesting
> and elegant solution to a tricky problem. 
> 
> I have a thought about allowing try/finally with some reasonable
> semantics. 

This is definitely a wart.  This problem is one of the major reasons why
Ken Pitman did not want continuations in Common Lisp (Scheme predates CL
and in CL try/finally is called unwind-protect).  It's a hard problem.

However, I think try/finally is less of a problem with generators then
it is for continuations.  Generators only allow you to temporarily jump
up one level in the stack frame while continuations allow you to jump to
essentially arbirary stack frames.  We disallow try/finally inside a
generator since there is no guarantee that the finally clause will ever
be executed.  The problem is localized.  With continuations the problem
spreads.  Any try/finally block could affected.

In practice, I think the current restriction is not a big problem.
try/finally is allowed in code that calls generators as well as code
called by generators.  It is only disallowed in the body of generator
itself.

> The PEP says that there is no guarantee that next() will be called
> again. However, there is a guaratee that either next() will be called,
> or the Generator will be cleaned up. It seems reasonable to me to
> build a mechanism by which, on __del__ cleanup of the Generator, an
> exception is raised from the Yeild point "UnfinishedGenerator" (and
> also caught by the cleanup function). This exception would trigger any
> finally exception clauses which exist above the yeild. This also has
> the added advantage that code can detect when a Generator does not run
> to completion.
> 
> It might even be useful to be able to flag the generator such that it
> does not catch the UnfinishedGenerator exception. Although this
> probably wouldn't be used often.

I'm pretty sure something like this could be done but I'm not sure it's
a good idea.  The handling of exceptions in __del__ methods is ugly,
IMHO.  We should not propagate that behavior without some careful
thought.  I would like to see some compelling arguments as to why
try/finally should be supported inside generators.

  Neil