python retry with retrying, disable for unittest

3.3k Views Asked by At

EDIT: Since tenacity is a more recent for of retrying, this question can be considered a duplicate of the linked question, with the solution being to upgrade to tenacity.

Similar to this question, I want to unittest a function in python that has a retry decorator:

from retrying import retry # from retrying pypi module

WAIT_EXPONENTIAL_MULTIPLIER = 4 * 1000  # ms
STOP_MAX_ATTEMPT_NUMBER = 5

@retry(
   wait_exponential_multiplier=WAIT_EXPONENTIAL_MULTIPLIER,
   stop_max_attempt_number=STOP_MAX_ATTEMPT_NUMBER
)
def get_from_remote(key):
    raise ValueError() # for example

In my unittest, I want to call this function sometimes without retrying at all, sometimes with different parameters.

I tried setting the variables in setUp()/tearDown(), but it did not work. I tried patching the retry decorator, but it also did not work.

1

There are 1 best solutions below

3
Joe On

Not sure if this is possible due to the line

Retrying(*dargs, **dkw).call(f, *args, **kw)

in retrying. The Retrying instance is created on-the-fly when the function is run and it is not possible to change its attributes anymore.

One approach could be to keep an undecorated reference to the function and decorate old-school at runtime.

from retrying import retry

WAIT_EXPONENTIAL_MULTIPLIER = 1 * 1000  # ms

# the "normal" decorator
retry_dec = retry(wait_exponential_multiplier=WAIT_EXPONENTIAL_MULTIPLIER)

# the undecorated function
def get_from_remote_undecorated(key):
    raise ValueError()

# this is the "normal" decorated function
get_from_remote = retry_dec(get_from_remote_undecorated)

This can be repeated in the unittests:

# some test
retry_dec_test_1 = retry(wait_exponential_multiplier=WAIT_EXPONENTIAL_MULTIPLIER)
get_from_remote_test_1 = retry_dec_test_1(get_from_remote_undecorated)

# another test with different parameters
retry_dec_test_2 = retry(stop_max_attempt_number=STOP_MAX_ATTEMPT_NUMBER)
get_from_remote_test_2 = retry_dec_test_2 (get_from_remote_undecorated)

But I am not really happy with this approach and will try to find a better solution.