import logging from tenacity import ( before_sleep_log, retry, stop_after_attempt, wait_random_exponential, ) class UnreliableRemote: def __init__(self, responses): self.responses = responses self.counter = 0 def request(self): res = self.responses[self.counter] self.counter += 1 if isinstance(res, Exception): raise res return res def should_retry(retry_state) -> bool: attempt = retry_state.outcome if attempt.failed: return isinstance(attempt.exception(), IOError) return False io_retry = retry( retry=should_retry, wait=wait_random_exponential(multiplier=1), stop=stop_after_attempt(3), before_sleep=before_sleep_log(logging.getLogger(__name__), logging.DEBUG), ) exc = IOError("RemoteException") responses = [exc, exc, exc, 3] def test_io_retry(): r = UnreliableRemote(responses) r.request = io_retry(r.request) r.request() # DEBUG:__main__:Retrying __main__.UnreliableRemote.request in 0.8281996260225647 seconds as it raised OSError: RemoteException. # RetryError: RetryError[]