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 (
175175exc :Exception ,
176176deadline :float | None ,
177- next_sleep : float ,
177+ sleep_iterator : Iterator [ float ] ,
178178error_list :list [Exception ],
179179predicate_fn :Callable [[Exception ],bool ],
180180on_error_fn :Callable [[Exception ],None ]| None ,
@@ -183,7 +183,7 @@ def _retry_error_helper(
183183tuple [Exception ,Exception | None ],
184184 ],
185185original_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 nextsleep interval
197+ -sleep_iterator: iterator to draw the nextbackoff 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 """
205207error_list .append (exc )
206208if not predicate_fn (exc ):
@@ -212,6 +214,12 @@ def _retry_error_helper(
212214raise final_exc from source_exc
213215if on_error_fn is not None :
214216on_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
215223if deadline is not None and time .monotonic ()+ next_sleep > deadline :
216224final_exc ,source_exc = exc_factory_fn (
217225error_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 ):