Mike Meyer wrote:
A single new keyword/clause, "retry". It has the same syntax as an "except" clause, can be used anywhere "except" can be used, and can be intermingled with them in the same try statement. There's probably a better syntax, but this is easy to describe.
The behavior change from except is that instead of exiting the "try" statement when the "retry" clause ends, it restarts the try
This sounds like retry should be a flow-control statement, like continue or break, not a block. E.g.: try: something() except ValueError: if condition: retry else: raise "retry" will jump back to the start of the try block -- a limited form of GOTO, with all the pros and cons of this.
clause. In python, this code:
try: # try block except: # except block retry: # retry block else: # else block finally: # finally block
Would provide the same behavior as this code:
while True: try: # try block except: # except block retry: # retry block else: # else block finally: # finally block break
Um, you're trying to explain the behaviour of retry here, but your Python code includes a retry. This is one case where recursion is NOT your friend.
Where except & retry can be repeated, include exceptions to check against, and intermixed with each other. The break would propagate up to the else block and any except blocks if there was no finally. If there's no else, the break from it winds up at the end of the try.
None of your explanation is clear to me. Under what circumstances will the retry block be executed? E.g. given: try: len(None) except TypeError: print("spam spam spam") retry: print("a") what will happen? How about these? #1 try: len(None) retry: print("a") except TypeError: print("spam spam spam") #2 try: len(None) except TypeError: print("spam spam spam") retry: print("a") except ValueError: print("this never gets called") retry: print("b") #3 try: len(None) except TypeError: print("spam spam spam") retry: print("a") retry: print("b")
The use case, as mentioned, is avoiding doing EAFP without repeating the code in the exception handler. I.e., the choices without retry are things like (LBYL):
I think that the idiom of a while or for loop is easy enough to read and write: for _ in range(5): # retry five times try: do_something(x) except SpamError: x = fix_up(x) else: break else: raise HamError("tried 5 times, giving up now") I just wish that break and continue could be written outside of a loop, so you can factor out common code: def do_the_thing(x): try: do_something(x) except SpamError: x = fix_up(x) else: break def try_repeatedly(n, func): for _ in range(n): func() else: raise HamError('tried %d times, giving up now" % n) try_repeatedly(5, do_the_thing) -- Steven