[Python-Dev] Combining the best of PEP 288 and PEP 325: generator exceptions and cleanup

Phillip J. Eby pje at telecommunity.com
Wed May 18 18:55:49 CEST 2005

At 09:39 AM 5/18/2005 -0700, Guido van Rossum wrote:
>- g.throw(type, value, traceback) causes the specified exception to be
>thrown at the place where the generator g is currently suspended. If
>the generator catches the exception and yields another value, that is
>the return value of g.throw(). If it doesn't catch the exception, the
>throw() appears to raise the same exception passed it (it "falls
>through"). If the generator raises another exception (this includes
>the StopIteration produced when it returns) that exception is raised
>by the throw. In summary, throw() behaves like next() except it raises
>an exception at the place of the yield. If the generator is already in
>the closed state, throw() just raises the exception it was passed
>without going through the generator.
>- There's a new exception, GeneratorExit, which can be thrown to cause
>a generator to clean up. A generator should not yield a value in
>response to this exception.
>- g.close() throws a GeneratorExit exception in the generator, and
>catches it (so g.close() itself does not raise an exception).
>g.close() is idempotent -- if the generator is already closed, it is a
>no-op. If the generator, against the rules, yields another value, it
>is nevertheless marked closed.
>- When a generator is GC'ed, its close() method is called (which is a
>no-op if it is already closed).
>That's it! With this, we can write the decorator from Nick's PEP 3XX
>and the generator examples in PEP 343 can be rewritten to have a
>try/finally clause around the yield statement.
>Oh, somewhere it should be stated that yield without an expression is
>equivalent to yield None. PEP 342 ("continue EXPR") already implies
>that, so we don't have to write a separate PEP for it. I also propose
>to go with the alternative in PEP 342 of using next() rather than
>__next__() -- generators will have methods next(), throw(), and

And there was much rejoicing in the land of the co-routiney people.  :)  +1000.

Should this maybe just be added to PEP 342?  To me, PEP 342 has always 
seemed incomplete without ways to throw() and close(), but that could 
easily be just me.  In any case I'd expect the implementation of 
'next(arg)' to have some overlap with the implementation of 'throw()'.

Also, if the generator yields a value upon close(), shouldn't that throw a 
runtime error?  Otherwise, you have no way to know the generator's 
exception handling is broken.

More information about the Python-Dev mailing list