[Python-ideas] Possible PEP 380 tweak

Nick Coghlan ncoghlan at gmail.com
Sun Oct 31 02:34:35 CEST 2010


On Sun, Oct 31, 2010 at 1:00 AM, Guido van Rossum <guido at python.org> wrote:
> What has this got to do with GeneratorExit and g.close()? I propose to
> modify g.close() to keep throwing GeneratorExit until the generator
> stops yielding values, and then capture the return value from
> StopIteration if that is what was raised. The beauty is then that the
> PEP 380 expansion can stop special-casing GeneratorExit: it just
> treats it as every other exception. And stddev() above works! (If you
> worry about infinite loops: you can get those anyway, by putting
> "while: True" in an "except GeneratorExit" block. I don't see much
> reason to worry more in this case.)

I'm back to liking your general idea, but wanting to use a new method
and exception for the task to keep the two sets of semantics
orthogonal :)

If we add a finish() method that corresponds to your stop() function,
and a GeneratorReturn exception as a peer to GeneratorExit:

class GeneratorReturn(BaseException): pass

def finish(self):
  if g.gi_frame is None:
    return self._result # (or raise RuntimeError)
  try:
    next(self)
    while True:
      self.throw(GeneratorReturn)
  except StopIteration as ex:
    return ex.value


Then your node counter iterator (nice example, btw) would simply look like:

def count_nodes(node):
 if not node:
   return 0
 count = 0
 count += yield from count_nodes(node.left)
 try:
   yield node
 except GeneratorReturn:
   return count
 count += 1 # Only count nodes when next is called in response
 count += yield from count_nodes(node.right)
 return count
Cheers,
Nick.

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



More information about the Python-ideas mailing list