async def __call__( # type: ignore # Change signature from supertype self, fn: typing.Callable[..., typing.Awaitable[_RetValT]], *args: typing.Any, **kwargs: typing.Any, ) -> _RetValT: self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do
def __call__( # type: ignore # Change signature from supertype self, fn: "typing.Callable[..., typing.Union[typing.Generator[typing.Any, typing.Any, _RetValT], Future[_RetValT]]]", *args: typing.Any, **kwargs: typing.Any, ) -> "typing.Generator[typing.Any, typing.Any, _RetValT]": self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = yield fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() yield self.sleep(do) else: raise gen.Return(do)
class AsyncRetrying(BaseRetrying): def __init__(self, sleep=sleep, **kwargs): super(AsyncRetrying, self).__init__(**kwargs) self.sleep = sleep async def __call__(self, fn, *args, **kwargs): self.begin(fn) retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def __aiter__(self): self.begin(None) self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) return self async def __anext__(self): while True: do = self.iter(retry_state=self._retry_state) if do is None: raise StopAsyncIteration elif isinstance(do, DoAttempt): return AttemptManager(retry_state=self._retry_state) elif isinstance(do, DoSleep): self._retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def wraps(self, fn): fn = super().wraps(fn) # Ensure wrapper is recognized as a coroutine function. async def async_wrapped(*args, **kwargs): return await fn(*args, **kwargs) # Preserve attributes async_wrapped.retry = fn.retry async_wrapped.retry_with = fn.retry_with return async_wrapped
async def __call__(self, fn, *args, **kwargs): self.begin(fn) retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do
class AsyncRetrying(BaseRetrying): def __init__(self, sleep=sleep, **kwargs): super(AsyncRetrying, self).__init__(**kwargs) self.sleep = sleep async def call(self, fn, *args, **kwargs): self.begin(fn) retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def __aiter__(self): self.begin(None) self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) return self async def __anext__(self): while True: do = self.iter(retry_state=self._retry_state) if do is None: raise StopAsyncIteration elif isinstance(do, DoAttempt): return AttemptManager(retry_state=self._retry_state) elif isinstance(do, DoSleep): self._retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do
def call(self, fn, *args, **kwargs): self.begin(fn) retry_state = RetryCallState( retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = yield fn(*args, **kwargs) except BaseException: retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() yield self.sleep(do) else: raise gen.Return(do)
def call(self, fn, *args, **kwargs): self.begin(fn) call_state = RetryCallState(fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(call_state=call_state) if isinstance(do, DoAttempt): call_state.attempt_number += 1 try: result = yield from fn(*args, **kwargs) except BaseException: call_state.set_exception(sys.exc_info()) else: call_state.set_result(result) elif isinstance(do, DoSleep): call_state.prepare_for_next_attempt() yield from self.sleep(do) else: return do
class AsyncRetrying(BaseRetrying): """This is a modified version of the tenacity.AsyncRetrying class that handles asynchronously defined retry or retry_error_callback parameters. There is an open PR for this change on the tenacity repository: https://github.com/jd/tenacity/pull/289 """ def __init__(self, sleep=asyncio.sleep, **kwargs): super().__init__(**kwargs) self.sleep = sleep async def iter(self, retry_state): fut = retry_state.outcome if fut is None: if self.before is not None: self.before(retry_state) return DoAttempt() is_explicit_retry = retry_state.outcome.failed and isinstance( retry_state.outcome.exception(), TryAgain) if iscoroutinefunction(self.retry): should_retry = await self.retry(retry_state=retry_state) else: should_retry = self.retry(retry_state=retry_state) if not (is_explicit_retry or should_retry): return fut.result() if self.after is not None: self.after(retry_state=retry_state) self.statistics[ "delay_since_first_attempt"] = retry_state.seconds_since_start if self.stop(retry_state=retry_state): if self.retry_error_callback: if iscoroutinefunction(self.retry_error_callback): return await self.retry_error_callback( retry_state=retry_state) return self.retry_error_callback(retry_state=retry_state) retry_exc = self.retry_error_cls(fut) if self.reraise: raise retry_exc.reraise() six.raise_from(retry_exc, fut.exception()) if self.wait: iteration_sleep = self.wait(retry_state=retry_state) else: iteration_sleep = 0.0 retry_state.next_action = RetryAction(iteration_sleep) retry_state.idle_for += iteration_sleep self.statistics["idle_for"] += iteration_sleep self.statistics["attempt_number"] += 1 if self.before_sleep is not None: self.before_sleep(retry_state=retry_state) return DoSleep(iteration_sleep) async def __call__(self, fn, *args, **kwargs): self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = await self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def __aiter__(self): self.begin(None) self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) return self async def __anext__(self): while True: do = await self.iter(retry_state=self._retry_state) if do is None: raise StopAsyncIteration if isinstance(do, DoAttempt): return AttemptManager(retry_state=self._retry_state) if isinstance(do, DoSleep): self._retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def wraps(self, fn): fn = super().wraps(fn) # Ensure wrapper is recognized as a coroutine function. async def async_wrapped(*args, **kwargs): return await fn(*args, **kwargs) # Preserve attributes async_wrapped.retry = fn.retry async_wrapped.retry_with = fn.retry_with return async_wrapped
class AsyncRetrying(BaseRetrying): def __init__(self, sleep: typing.Callable[[float], typing.Awaitable] = sleep, **kwargs: typing.Any) -> None: super().__init__(**kwargs) self.sleep = sleep async def __call__( # type: ignore # Change signature from supertype self, fn: typing.Callable[..., typing.Awaitable[_RetValT]], *args: typing.Any, **kwargs: typing.Any, ) -> _RetValT: self.begin() retry_state = RetryCallState(retry_object=self, fn=fn, args=args, kwargs=kwargs) while True: do = self.iter(retry_state=retry_state) if isinstance(do, DoAttempt): try: result = await fn(*args, **kwargs) except BaseException: # noqa: B902 retry_state.set_exception(sys.exc_info()) else: retry_state.set_result(result) elif isinstance(do, DoSleep): retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def __aiter__(self) -> "AsyncRetrying": self.begin() self._retry_state = RetryCallState(self, fn=None, args=(), kwargs={}) return self async def __anext__(self) -> typing.Union[AttemptManager, typing.Any]: while True: do = self.iter(retry_state=self._retry_state) if do is None: raise StopAsyncIteration elif isinstance(do, DoAttempt): return AttemptManager(retry_state=self._retry_state) elif isinstance(do, DoSleep): self._retry_state.prepare_for_next_attempt() await self.sleep(do) else: return do def wraps(self, fn: WrappedFn) -> WrappedFn: fn = super().wraps(fn) # Ensure wrapper is recognized as a coroutine function. @functools.wraps(fn) async def async_wrapped(*args: typing.Any, **kwargs: typing.Any) -> typing.Any: return await fn(*args, **kwargs) # Preserve attributes async_wrapped.retry = fn.retry async_wrapped.retry_with = fn.retry_with return async_wrapped