
[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. :-) -- --Guido van Rossum (home page: http://www.python.org/~guido/)