[Neil Schemenauer]
Is "raise StopIteration" an abuse of exceptions?
I only care whether it works <wink>. It certainly came as a surprise to me, though, that I'm going to need to fiddle PEP 255 to explain that return in a generator isn't really equivalent to raise StopIteration (because a return in the try-part of a try/except should not trigger the except-part if the generator is pumped again). While a minor wart, it's a wart. If this stands, I'm going to look into changing gen_iternext() to determine whether eval_frame() finished by raising StopIteration, and mark the iterator as done if so. That is, force "return" and "raise StopIteration" to act the same inside generators, and to force "raise StopIteration" inside a generator to truly *mean* "I'm done" in all cases. This would also allow to avoid the proposed special-casing of generators at the tail end of eval_frame() (yes, I'm anal <0.9 wink>: since it's a problem unique to generators, this simply should not be eval_frame's problem to solve -- if generators create the problem, generators should pay to solve it).
Why can we not use "return StopIteration" to signal the end of an iterator?
Just explained why not yesterday, and you did two sentences later <wink>.
.... This could be fixed in most causes by changing the tp_iternext protocol. Something like:
int tp_iternext(PyObject *it, PyObject **item)
were the return value is 1, 0, or -1.
Meaning 13, 42, and 666 respectively <wink>? That is, one for "error", one for "OK, and item is the next value", and one for "no error but no next value either -- this iterator terminated normally"? That could work. At one point during the development of the iterator PEP, Guido had some code like that in the internals, on *top* of the exception business. It was clumsy then because redundant. At the level of Python code, how would a user spell "end of iteration"? Would iterators need to return a 2-two tuple in all non-exception cases then, e.g. a (next_value, i_am_done_flag) pair? Or would Python-level iterators simply be unable to return StopIteration as a normal value?
IOW, StopIteration would not have to come into the protocol if the object implemented tp_iternext.
All iterable objects in 2.2 implement tp_iternext, although sometimes it's a Miranda tp_iternext (i.e., one created for an object that doesn't supply its own), so that shouldn't be a worry. All in all, I'm -0 on changing the exception approach -- it's worked very well so far.