Nick Coghlan
Then, in Py3K, finalisation could simply become the default for loop behaviour. However, the '__finalise__' flag would result in some impressive code bloat, as any for loop would need to expand to:
itr = iter(EXPR1) if getattr(itr, "__finalise__", False): # Finalised semantics # I'm trying to channel Guido here. # This would really look like whatever the PEP 340 block statement # semantics end up being val = arg = None ret = broke = False while True: try: VAR1 = next(itr, arg) except StopIteration: BLOCK2 break try: val = arg = None ret = False BLOCK1 except Exception, val: itr.__error__(val) if ret: try: itr.__error__(StopIteration()) except StopIteration: pass return val
The problem is that BLOCK2 is executed within the while loop (the same problem I had with a fix I offered), which may contain a break for breaking out of a higher-level loop construct. Here's one that works as you intended (though perhaps I'm being a bit to paranoid about the __error__ attribute)... val = arg = None ret = ex_block_2 = False while True: try: VAR1 = next(itr, arg) except StopIteration: ex_block_2 = True break try: val = arg = None ret = False BLOCK1 except Exception, val: if hasattr(itr, '__error__): itr.__error__(val) if ret: try: if hasattr(itr, '__error__'): itr.__error__(StopIteration()) except StopIteration: pass return val if ex_block_2: BLOCK2
P.S. I think PEP 340's proposed for loop semantics are currently incorrect, as BLOCK2 is unreachable. It should look more like the non-finalised semantics above (with BLOCK2 before the break in the except clause)
Indeed, I also mentioned this on Wednesday. - Josiah