I've implemented a retry decorator with some parameters:
def retry(max_tries: int = 3, delay_secs: float = 1, backoff: float = 1.5):
print("level 1:", max_tries, delay_secs, backoff)
def decorator(func):
print("level 2:", max_tries, delay_secs, backoff)
@functools.wraps(func)
def wrapper(*args, **kwargs):
nonlocal delay_secs ## UnboundLocalError if remove this line
print("level 3:", max_tries, delay_secs, backoff)
for attempt in range(max_tries):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"attempt {attempt} Exception: {e} Sleeping {delay_secs}")
time.sleep(delay_secs)
delay_secs *= backoff
print("exceeded maximun tries")
raise e
return wrapper
return decorator
@retry(max_tries=4, delay_secs=1, backoff=1.25)
def something():
raise Exception("foo")
something()
If I remove this line, I got UnboundLocalError
nonlocal delay_secs
But that only happens for delay_secs, NOT for max_tries or backoff! I tried reordering/renaming the params and still that delay param is problematic.
Can you help me understand why that parameter out of scope within the wrapper function but the other 2 parameters are just fine?
Python: 3.9.2
OS: Debian 11 Linux