
Greg Ewing wrote:
To do otherwise would require making a distinction that can't be expressed in the Python expansion. Also, it seems elegant to preserve the property that if g is a generator then g.close() and g.throw(GeneratorExit) are exactly equivalent.
What do people think about this?
That whole question is why I suggested rephrasing the question of which exceptions are passed to the subiterator in Exception vs BaseException terms. The only acknowledged direct subclasses of BaseException are KeyboardInterrupt, SystemExit and GeneratorExit. The purpose of those exceptions is to say "drop what you're doing and bail out any which way you can". Terminating the outermost generator in those cases and letting the subiterators clean up as best they can sounds like a perfectly reasonable option to me. The alternative is to catch BaseException and throw absolutely everything (including GeneratorExit) into the subiterator. The in-between options that you're describing would appear to just complicate the semantics to no great purpose. Note that you may also be pursuing a false consistency here, since g.close() has never been equivalent to g.throw(GeneratorExit), as the latter propagates the exception back into the current scope while the former suppresses it (example was run using 2.5.2):
def gen(): yield ... g = gen() g.next() g.close() g2 = gen() g2.next() g2.throw(GeneratorExit) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 1, in gen GeneratorExit
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------