Search code examples
pythonretryingtenacity

Python retry with dynamic parameters


Tried this in the retrying and tenacity python libraries to no avail.

Retries are typically used with a decorator, for example as shown in metacode below:

class FooBar:

   @retry(attempts=3)
   def dosomething():
      ...

I want the retry parameters to be configurable on the class

class FooBar:
   def __init__(retries=0):
       self.retries = retries

   @retry(attempts=self.retries)
   def dosomething():
      ...

Obviously this will break because the decorator cannot accedss object attributes (ie. cannot access self). So figured this would work:

def dosomething():
   with retry(attempts=self.retries):
       ...

But neither library allows for retry to be called in a with block

>  with retry():
E  AttributeError: __enter__

What is the preferred way to wrap retry logic with dynamic parameters?


Solution

  • You needn't use deorators with the @ syntax - they can also be used as functions.

    from tenacity import retry, stop_after_attempt
    
    class CustomClass:
        def __init__(self, retries):
            decorator = retry(stop=stop_after_attempt(retries), reraise=True)
            self.method_with_retry = decorator(self.method)
        
        def method(self, x):
            print('Trying...')
            if x % 2:
                raise ValueError
            return x
    
    CustomClass(3).method_with_retry(11)