how to check how many times retry function called in python

75 Views Asked by At

I'm using a retry decorator to run the test case if failed. So, want to know how many times the retry function called

   def retry(tries=3, delay=10):
       def decorator(func):
           @wraps(func)
           def func_retry(*args, **kwargs):
              n_tries, n_delay = tries, delay
              output = error = None
              while n_tries >= 1:
                  try:
                      output = func(*args, **kwargs)
                      return output
                  except AssertionError as e:
                      n_tries = n_tries - 1
                      error = e.__str__()
                      print(f'Retry error: "{func.__name__}" due to "{error}". So, Retrying execution [{(tries - n_tries)}/{tries}] in {delay} second(s)...')
                      time.sleep(n_delay)
                   return output
           return func_retry
       return decorator

Sample function for testing purpose

   @retry()
   def test():
      assert "x" == "y"

I want to know how many times retry function in retry decorator called like retry.count or retry.tries

1

There are 1 best solutions below

2
Daraan On

You can work with attributes of the final function that is returned. (You can also do it on the decorator but then it is not accessible from the outside).

def retry(tries=3, delay=10):
    def decorator(func):
        @wraps(func)
        def func_retry(*args, **kwargs):
           func_retry.n_tries = 0
           output = error = None
           while func_retry.n_tries < tries:
               try:
                   output = func(*args, **kwargs)
                   return output
               except AssertionError as e:
                   func_retry.n_tries += 1
                   error = e.__str__()
                   print(f'Retry error: "{func.__name__}" due to "{error}". So, Retrying execution [{(func_retry.n_tries)}/{tries}] in {delay} second(s)...')
                   time.sleep(delay)
           return output
        func_retry.n_tries = 0 # set initial attribute
        return func_retry
    return decorator

@retry(tries=5, delay=0.1)
def foo():
   assert 1==2

print("Tries done", foo.n_tries)
foo()
print("Tries done", foo.n_tries)

Output:

Tries done 0
Retry error: "foo" due to "". So, Retrying execution [1/5] in 0.1 second(s)...
Retry error: "foo" due to "". So, Retrying execution [2/5] in 0.1 second(s)...
Retry error: "foo" due to "". So, Retrying execution [3/5] in 0.1 second(s)...
Retry error: "foo" due to "". So, Retrying execution [4/5] in 0.1 second(s)...
Retry error: "foo" due to "". So, Retrying execution [5/5] in 0.1 second(s)...
Tries done 5