Greg Ewing wrote:
I'm thinking about replacing the expansion with the following, which hopefully fixes a couple of concerns that were raised recently without breaking anything else.
Can anyone see any remaining ways in which it doesn't match the textual description in the Proposal section?
(It still isn't *quite* right, because it doesn't distinguish between a GeneratorExit explicitly thrown in and one resulting from calling close() on the delegating generator. I may need to revise the text and/or my implementation on that point, because I want the inline-expansion interpretation to hold.)
_i = iter(EXPR) try: _u = _i.next() except StopIteration, _e: _r = _e.value else: while 1: try: _v = yield _u except GeneratorExit: _m = getattr(_i, 'close', None) if _m is not None: _m() raise 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 RESULT = _r
I'd adjust the inner exception handlers to exploit the fact that SystemExit and GeneratorExit don't inherit from BaseException: _i = iter(EXPR) try: _u = _i.next() except StopIteration, _e: _r = _e.value else: while 1: try: _v = yield _u except Exception, _e: _m = getattr(_i, 'throw', None) if _m is not None: _u = _m(_e) else: raise except: # Covers SystemExit, GeneratorExit and # anything else that doesn't inherit # from Exception _m = getattr(_i, 'close', None) if _m is not None: _m() raise else: try: if _v is None: _u = _i.next() else: _u = _i.send(_v) except StopIteration, _e: _r = _e.value break RESULT = _r I think Antoine and PJE are right that the PEP needs some more actual use cases though. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------