[Python-Dev] GeneratorExit is unintuitive and uneccessary

Phillip J. Eby pje at telecommunity.com
Wed Aug 23 16:35:42 CEST 2006


I rather like it, actually.  I don't recall there being any real reasons to 
catch a GeneratorExit exception, but even if there were, you could do the 
equivalent like this:

     try:
         closed = True
         yield 1
         closed = False
     finally:
         if closed:
             # special closing code

Unfortunately, this is a pretty major change to be making to the 
specification (PEP 342) when we've just released 2.5c1; it seems like 
something that requires at least a beta release.

But aside from that, it seems like a fairly neat solution to the 
problem.  I'd like to hear from Jython and IronPython representatives 
regarding implementability for those platforms, though.  Our original 
assumption was that if they could implement throw() then they could clearly 
implement close(), since close() was defined in terms of throw().  An 
asynchronous return might be another matter.  But if that hurdle is 
crossable, then I agree that modelling close() as an early return is more 
intuitive, eliminates a built-in exception, etc.

At 03:17 PM 8/22/2006 +0200, Igor Bukanov wrote:
>Consider the following example:
>
>for i in range(3):
>   try:
>     print i
>     break
>   except:
>     print "Unexpected exception!"
>   finally:
>     print "Finally"
>
>When executed, it naturally prints
>   0
>   Finally
>since break does not use exceptions to transfer the control and as
>such can not be stopped using catch-all exception handler.
>
>Now consider a similar example using generators:
>
>def gen():
>   for i in range(3):
>     try:
>       yield i
>     except:
>       print "Unexpected exception!"
>     finally:
>       print "Finally"
>
>for i in gen():
>   print i
>   break
>
>This example prints:
>   0
>   Unexpected exception!
>   Finally
>   Exception exceptions.RuntimeError: 'generator ignored GeneratorExit'
>in <generator object at 0xb7daaa8c> ignored
>
>Suddenly with generators a program can mess with control transfer
>since it uses explicit GeneratorExit which can be caught and ignored.
>This is unintuitive IMO.
>
>This example also suggests how to fix generators. One just need to
>change the close method so it would cause return executed right after
>the yield instead of throw.
>
>I.e. replace the current text from
>http://www.python.org/dev/peps/pep-0342/
>
>4. Add a close() method for generator-iterators, which raises
>GeneratorExit at the point where the generator was paused.  If the
>generator then raises StopIteration (by exiting normally, or due to
>already being closed) or GeneratorExit (by not catching the
>exception), close() returns to its caller.  If the generator yields a
>value, a RuntimeError is raised.  If the generator raises any other
>exception, it is propagated to the caller. close() does nothing if the
>generator has already exited due to an exception or normal exit.
>
>by simpler one:
>
>4. Add a close() method for generator-iterators, which executes normal
>return at the point where the generator was paused.  If the generator
>then raises StopIteration (by exiting normally, or due to already
>being closed), close() returns to its caller.  If the generator yields
>a value, a RuntimeError is raised.  If the generator raises any other
>exception, it is propagated to the caller. close() does nothing if the
>generator has already exited due to an exception or normal exit.
>
>This not only fixes the above discrepancy between normal flow control
>and generators, removes GeneratorExit and simplifies the generator
>protocol, but also bring a new feature allowing to have easy to grasp
>feature table of the iterator methods:
>
>next: continue after yield
>throw: raise after yield
>close: return after yield
>
>Regards, Igor
>_______________________________________________
>Python-Dev mailing list
>Python-Dev at python.org
>http://mail.python.org/mailman/listinfo/python-dev
>Unsubscribe: 
>http://mail.python.org/mailman/options/python-dev/pje%40telecommunity.com



More information about the Python-Dev mailing list