[Python-ideas] Possible PEP 380 tweak

Nick Coghlan ncoghlan at gmail.com
Tue Oct 26 12:36:08 CEST 2010


On Tue, Oct 26, 2010 at 1:14 PM, Guido van Rossum <guido at python.org> wrote:
> On Mon, Oct 25, 2010 at 6:35 PM, Jacob Holm <jh at improva.dk> wrote:
>> Throwing and catching GeneratorExit is not common, and according to some
>> shouldn't be used for this purpose at all.
>
> Well, *throwing* it is close()'s job. And *catching* it ought to be
> pretty rare. Maybe this idiom would be better:
>
> def sum():
>  total = 0
>  try:
>    while True:
>      value = yield
>      total += value
>  finally:
>    return total

Rereading my previous post that Jacob linked, I'm still a little
uncomfortable with the idea of people deliberately catching
GeneratorExit to turn it into a normal value return to be reported by
close(). That said, I'm even less comfortable with the idea of
encouraging the moral equivalent of a bare except clause :)

I see two realistic options here:

1. Use GeneratorExit for this, have g.close() return a value and I
(and others that agree with me) just get the heck over it.

2. Add a new GeneratorReturn exception and a new g.finish() method
that follows the same basic algorithm Guido suggested, only with a
different exception type:

class GeneratorReturn(Exception): # Note: ordinary exception, unlike
GeneratorExit
  pass

def finish(gen):
 try:
   gen.throw(GeneratorReturn)
   raise RuntimeError("Generator ignored GeneratorReturn")
 except StopIteration as err:
   if err.args:
     return err.args[0]
 except GeneratorReturn:
   pass
 return None

(Why "finish" as the suggested name for the method? I'd prefer
"return", but that's a keyword and "return_" is somewhat ugly. Pairing
GeneratorReturn with finish() is my second choice, for the "OK, time
to wrap things up and complete your assigned task" connotations, as
compared to the "drop everything and clean up the mess" connotations
of GeneratorExit and close())

I'd personally be +1 on option 2 (since it addresses the immediate use
case while maintaining appropriate separation of concerns between
guaranteed resource cleanup and graceful completion of coroutines) and
-0 on option 1 (unsurprising, given my previously stated objections to
failing to maintain appropriate separation of concerns).

(I should note that this differs from the previous suggestion of a
GeneratorReturn exception in the context of PEP 380. Those suggestions
were to use it as a replacement for StopIteration when a generator
contained a return statement. The suggestion here is to instead use it
as a replacement for GeneratorExit in order to request
prompt-but-graceful completion of a generator rather than just bailing
out immediately).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list