Nick Coghlan wrote:
I'd adjust the inner exception handlers to exploit the fact that SystemExit and GeneratorExit don't inherit from BaseException:
But then anything thrown in that didn't inherit from Exception would bypass giving the subiterator a chance to handle it, which doesn't seem right. The more I think about this, the more I'm wondering whether I shouldn't ever try to call close() on the subiterator at all, and just rely on it to finalize itself when it's deallocated. That would solve all problems concerning when and if close() calls should be made (the answer would be "never"). It would also avoid the problem of a partially exhausted iterator that's still in use by something else getting prematurely finalized, which is another thing that's been bothering me. Here's another expansion based on that idea. When we've finished with the subiterator for whatever reason -- it raised StopIteration, something got thrown in, we got closed ourselves, etc. -- we simply drop our reference to it. If that causes it to be deallocated, it's responsible for cleaning itself up however it sees fit. _i = iter(EXPR) try: try: _u = _i.next() except StopIteration, _e: _r = _e.value else: while 1: try: _v = yield _u except BaseException, _e: _m = getattr(_i, 'throw', None) if _m is not None: _u = _m(_e) else: raise else: try: if _v is None: _u = _i.next() else: _u = _i.send(_v) except StopIteration, _e: _r = _e.value break finally: del _i RESULT = _r
I think Antoine and PJE are right that the PEP needs some more actual use cases though.
The examples I have are a bit big to put in the PEP itself, but I can include some links. -- Greg