Re: [Python-Dev] Combining the best of PEP 288 and PEP 325: generatorexceptions and cleanup

2005-05-18 Thread Raymond Hettinger
 [Raymond Hettinger]
  Are the value and traceback arguments optional as they are with the
  current raise statement?  If they are optional, what would the
default
  be?  I think the preferred choice is to have the call to the throw
  method be the anchor point.  That makes sense in a traceback so you
can
  see who threw the exception.
 
 AFAI throw() is concerned, the defaults are None. The raise statement
 does something sane when the second and/or third arg are None (the
 first can't be though).
 
  The alternative is to have the generator resumption point be the
anchor.
  That is closer to the notion that throw(ex) is equivalent to a
raise
  ex following the last yield.   This probably isn't the way to go
but
  the PEP should address it explicitly.
 
 It's actually kind of tricky since the exception will come *back* to
 the throw point anyway. I think the traceback ought to start at the
 resumption point by default.
 
   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.
 
  The parallel to next() makes this easy to understand, learn, and
  implement.  However, there are some disadvantages to passing through
a
  StopIteration.  It means that throw() calls usually need to be
wrapped
  in a try/except or that a generator's exception handler would
terminate
  with a yield None where a return would be more natural.  As a
  example, it is a bit painful to simulate the effects of g.close()
using
  g.throw(GeneratorExit).
 
 Doesn't bother me; the main use case is in the do_template (or
 with_template) decorator. Since it must support both raising an
 exception and returning a value, we're pretty much forced to catch the
 exception (unless we just want to pass it through, which is actually a
 reasonable use case).
 
   I also propose
   to go with the alternative in PEP 342 of using next() rather than
   __next__() -- generators will have methods next(), throw(), and
   close().
 
  +0  The switch from __next__() to next() is attractive but not
essential
  to the proposal.  Besides a small cost to backwards compatability,
it
  introduces yet another new/old style distinction where we have to
keep
  both forms in perpetuity.
 
 Right. PBP. :-)


FWIW, I'm in agreement with everything.
I hope this one gets accepted.
Please do put it in a separate PEP.


Raymond
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Combining the best of PEP 288 and PEP 325: generatorexceptions and cleanup

2005-05-18 Thread Phillip J. Eby
At 01:24 PM 5/18/2005 -0400, Raymond Hettinger wrote:
  - g.throw(type, value, traceback) causes the specified exception to be
  thrown at the place where the generator g is currently suspended.

Are the value and traceback arguments optional as they are with the
current raise statement?  If they are optional, what would the default
be?  I think the preferred choice is to have the call to the throw
method be the anchor point.  That makes sense in a traceback so you can
see who threw the exception.

The alternative is to have the generator resumption point be the anchor.
That is closer to the notion that throw(ex) is equivalent to a raise
ex following the last yield.   This probably isn't the way to go but
the PEP should address it explicitly.

My use case for throw() calls for the latter option; i.e., the exception is 
raised by the yield expression at the resumption point.  Keep in mind that 
if the exception passes out of the generator, the throw() call will show in 
the traceback anyway.  It's unlikely the generator itself will inspect the 
traceback and need to see the throw() call as if it were nested.


  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.

The parallel to next() makes this easy to understand, learn, and
implement.  However, there are some disadvantages to passing through a
StopIteration.  It means that throw() calls usually need to be wrapped
in a try/except or that a generator's exception handler would terminate
with a yield None where a return would be more natural.  As a
example, it is a bit painful to simulate the effects of g.close() using
g.throw(GeneratorExit).

I don't see this as a big problem, personally, but that's because all of my 
use cases for throw() will be using only one piece of code that calls 
throw(), and that code will be overall simplified by the availability of 
throw().

It's also easy to write a wrapper for control-flow signals of the kind 
you used in PEP 288:

 def send(gen, *exc):
 try:
 return gen.throw(*exc)
 except StopIteration:
 pass

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Combining the best of PEP 288 and PEP 325: generatorexceptions and cleanup

2005-05-18 Thread Greg Ewing
Phillip J. Eby wrote:
 My use case for throw() calls for the latter option; i.e., the exception is 
 raised by the yield expression at the resumption point.  Keep in mind that 
 if the exception passes out of the generator, the throw() call will show in 
 the traceback anyway.  It's unlikely the generator itself will inspect the 
 traceback and need to see the throw() call as if it were nested.

There mightn't be much choice anyway. If the frame making
the call to throw() were to be made the starting point for
the traceback, and the exception propagated back to the
throw, something would try to put the same frame in the
traceback twice, which can't work since it's a linked
list.

-- 
Greg Ewing, Computer Science Dept, +--+
University of Canterbury,  | A citizen of NewZealandCorp, a   |
Christchurch, New Zealand  | wholly-owned subsidiary of USA Inc.  |
[EMAIL PROTECTED]  +--+
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com