Re: [Python-Dev] Combining the best of PEP 288 and PEP 325: generatorexceptions and cleanup
[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
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
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