2525import time
2626
2727from enum import Enum
28- from typing import Any , Callable , Optional , TYPE_CHECKING
28+ from typing import Any , Callable , Optional , Iterator , TYPE_CHECKING
2929
3030import requests .exceptions
3131
@@ -174,7 +174,7 @@ def build_retry_error(
174174def _retry_error_helper (
175175 exc : Exception ,
176176 deadline : float | None ,
177- next_sleep : float ,
177+ sleep_iterator : Iterator [ float ] ,
178178 error_list : list [Exception ],
179179 predicate_fn : Callable [[Exception ], bool ],
180180 on_error_fn : Callable [[Exception ], None ] | None ,
@@ -183,7 +183,7 @@ def _retry_error_helper(
183183 tuple [Exception , Exception | None ],
184184 ],
185185 original_timeout : float | None ,
186- ):
186+ ) -> float :
187187 """
188188 Shared logic for handling an error for all retry implementations
189189
@@ -194,13 +194,15 @@ def _retry_error_helper(
194194 Args:
195195 - exc: the exception that was raised
196196 - deadline: the deadline for the retry, calculated as a diff from time.monotonic()
197- - next_sleep: the next sleep interval
197+ - sleep_iterator: iterator to draw the next backoff value from
198198 - error_list: the list of exceptions that have been raised so far
199199 - predicate_fn: takes `exc` and returns true if the operation should be retried
200200 - on_error_fn: callback to execute when a retryable error occurs
201201 - exc_factory_fn: callback used to build the exception to be raised on terminal failure
202202 - original_timeout_val: the original timeout value for the retry (in seconds),
203203 to be passed to the exception factory for building an error message
204+ Returns:
205+ - the sleep value chosen before the next attempt
204206 """
205207 error_list .append (exc )
206208 if not predicate_fn (exc ):
@@ -212,6 +214,12 @@ def _retry_error_helper(
212214 raise final_exc from source_exc
213215 if on_error_fn is not None :
214216 on_error_fn (exc )
217+ # next_sleep is fetched after the on_error callback, to allow clients
218+ # to update sleep_iterator values dynamically in response to errors
219+ try :
220+ next_sleep = next (sleep_iterator )
221+ except StopIteration :
222+ raise ValueError ("Sleep generator stopped yielding sleep values." ) from exc
215223 if deadline is not None and time .monotonic () + next_sleep > deadline :
216224 final_exc , source_exc = exc_factory_fn (
217225 error_list ,
@@ -222,6 +230,7 @@ def _retry_error_helper(
222230 _LOGGER .debug (
223231 "Retrying due to {}, sleeping {:.1f}s ..." .format (error_list [- 1 ], next_sleep )
224232 )
233+ return next_sleep
225234
226235
227236class _BaseRetry (object ):
0 commit comments