A certain function operation, an external service, and sometimes fails. I want to try it N times before giving up. For this reason I wrote the retry code as a decorator, and now I want to unit-test it.
I made a simple mockup function for the possibly faulty operation: the function fails with exception for N-1 times, and succeed the N-th time.
This is the code:
def mock(retry):
def repl(*xs, **ks):
if retry == 0:
return 1
retry -= 1
raise error('boom')
return repl
This is how I want to apply it:
somemodule.library.operation = mock(N - 1)
somemodule.run() # calls somemodule.library.operation
Unexpectedly, by running mock(N -1)() I get the following error on the if retry == 0 line:
UnboundLocalError: local variable 'retry' referenced before assignment
After trying to understand why, I figured out that the error disappears as soon as I get rid of the retry -= 1 line.
I'm a bit puzzled by this fact, since in my opinion the retry variable should fully belong to the mock scope, and not just when it is accessed in read-only. If anything, I should always get the error, not only if I modify it.
Why is this a problem? And what is in your opinion the correct way of doing it?
Note:
- I can see this behavior both with Python2 and Python3
- I also tried to define
global retryjust before theif retry == 0conditional