2525from tenacity import DoAttempt
2626from tenacity import DoSleep
2727from tenacity import RetryCallState
28+ from tenacity import _utils
2829
2930WrappedFnReturnT = t .TypeVar ("WrappedFnReturnT" )
3031WrappedFn = t .TypeVar ("WrappedFn" , bound = t .Callable [..., t .Awaitable [t .Any ]])
@@ -46,7 +47,7 @@ async def __call__( # type: ignore[override]
4647
4748 retry_state = RetryCallState (retry_object = self , fn = fn , args = args , kwargs = kwargs )
4849 while True :
49- do = self .iter (retry_state = retry_state )
50+ do = await self .iter (retry_state = retry_state )
5051 if isinstance (do , DoAttempt ):
5152 try :
5253 result = await fn (* args , ** kwargs )
@@ -60,6 +61,47 @@ async def __call__( # type: ignore[override]
6061 else :
6162 return do # type: ignore[no-any-return]
6263
64+ @classmethod
65+ def _wrap_action_func (cls , fn : t .Callable [..., t .Any ]) -> t .Callable [..., t .Any ]:
66+ if _utils .is_coroutine_callable (fn ):
67+ return fn
68+
69+ async def inner (* args : t .Any , ** kwargs : t .Any ) -> t .Any :
70+ return fn (* args , ** kwargs )
71+
72+ return inner
73+
74+ def _add_action_func (self , fn : t .Callable [..., t .Any ]) -> None :
75+ self .iter_state .actions .append (self ._wrap_action_func (fn ))
76+
77+ async def _run_retry (self , retry_state : "RetryCallState" ) -> None : # type: ignore[override]
78+ self .iter_state .retry_run_result = await self ._wrap_action_func (self .retry )(
79+ retry_state
80+ )
81+
82+ async def _run_wait (self , retry_state : "RetryCallState" ) -> None : # type: ignore[override]
83+ if self .wait :
84+ sleep = await self ._wrap_action_func (self .wait )(retry_state )
85+ else :
86+ sleep = 0.0
87+
88+ retry_state .upcoming_sleep = sleep
89+
90+ async def _run_stop (self , retry_state : "RetryCallState" ) -> None : # type: ignore[override]
91+ self .statistics ["delay_since_first_attempt" ] = retry_state .seconds_since_start
92+ self .iter_state .stop_run_result = await self ._wrap_action_func (self .stop )(
93+ retry_state
94+ )
95+
96+ async def iter (
97+ self , retry_state : "RetryCallState"
98+ ) -> t .Union [DoAttempt , DoSleep , t .Any ]: # noqa: A003
99+ self ._begin_iter (retry_state )
100+ result = None
101+ for action in self .iter_state .actions :
102+ result = await action (retry_state )
103+ return result
104+
63105 def __iter__ (self ) -> t .Generator [AttemptManager , None , None ]:
64106 raise TypeError ("AsyncRetrying object is not iterable" )
65107
@@ -70,7 +112,7 @@ def __aiter__(self) -> "AsyncRetrying":
70112
71113 async def __anext__ (self ) -> AttemptManager :
72114 while True :
73- do = self .iter (retry_state = self ._retry_state )
115+ do = await self .iter (retry_state = self ._retry_state )
74116 if do is None :
75117 raise StopAsyncIteration
76118 elif isinstance (do , DoAttempt ):
0 commit comments