All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Calendar Versioning.
The first number of the version is the year. The second number is incremented with each release, starting at 1 for each year. The third number is for emergencies when we need to start branches for older releases.
You can find our backwards-compatibility policy here.
26.1.0 - 2026-04-13
- Passing
timeout=0now raises a warning since it counterintuitively disables all retries. If you explicitly want to disable the timeout, usetimeout=None.
_compute_backoff()no longer raisesOverflowErrorwhen the attempt number exceeds 1024 with a float wait_exp_base. The exponential result is now clamped to wait_max on overflow. #137
25.2.0 - 2025-12-11
- Support for Python 3.8 and 3.9.
-
The type hints for our public API are now also verified using Pyrefly and ty. #124
-
stamina.retry()now retries wrapped generator functions and async generator functions.Warning: Being able to
asendandathrowinto wrapped async generators introduced nontrivial complexity in the implementation and is therefore provisional. If supporting these features causes problems, they may be removed again in a future version. #123 -
An on hook can now return a float or a
datetime.timedeltato specify a custom backoff that overrides the default backoff. #103 #125
-
Prevent unbounded stop condition when both attempts and timeout are non-
Nonefalsy values. #109 -
Default
wait_exp_baseparameter is now an integer to prevent anOverflowErrorafter the 1023th retry. #104 -
Attempt.next_waitnow returns the correct value. #115
25.1.0 - 2025-03-12
-
cap argument to
stamina.set_testing(). By default, the value passed as attempts is used strictly. Whencap=True, it is used as an upper cap; that means that if the original attempts number is lower, it's not changed. #80 -
stamina.set_testing()can now be used as a context manager. #94 -
Instrumentation hooks can now can return context managers. If they do, they are entered when a retry is scheduled and exited right before the retry is attempted. #95
24.3.0 - 2024-08-27
-
The on argument in all retry functions now can be a callable that takes an exception and returns a bool which decides whether or not a retry should be scheduled. #70
-
stamina.Attemptnow has anext_waitattribute that contains the time the next backoff will wait, if the current attempt fails (sans jitter). #72 -
It is now possible to switch stamina into a testing mode using
stamina.set_testing(). It disables backoffs and caps the number of retries. #73
24.2.0 - 2024-01-31
-
stamina.RetryingCallerandstamina.AsyncRetryingCallerthat allow even easier retries of single callables:stamina.RetryingCaller(attempts=5).on(ValueError)(do_something, "foo", bar=42)andstamina.RetryingCaller(attempts=5)(ValueError, do_something, "foo", bar=42)will calldo_something("foo", bar=42)and retry onValueErrorup to 5 times.stamina.RetryingCallerandstamina.AsyncRetryingCallertake the same arguments asstamina.retry(), except foronthat can be bound separately.
24.1.0 - 2024-01-03
- stamina doesn't retry successful blocks when it's deactivated anymore (yes, you read it right). #54
23.3.0 - 2023-12-05
23.2.0 - 2023-10-30
-
Instrumentation is now pluggable! You can define your own hooks that are run with retry details whenever a retry is scheduled. The documentation now has a whole chapter on instrumentation. #37
-
If structlog is not installed, the scheduled retry is now logged using the standard library
loggingmodule by default. #35
-
Tenacity's internal
AttemptManagerobject is no longer exposed to the user. This was an oversight and never documented.stamina.retry_context()now yields instances ofstamina.Attempt. #22 -
Initialization of instrumentation is now delayed. This means that if there's no retries, there's no startup overhead from importing structlog and prometheus-client. #34
-
Some key names in structlog log messages have been renamed to better reflect their meaning (
slept→waited_so_far,attempt→retry_num, anderror→caused_by). You can rename them back using structlog'sstructlog.processors.EventRenamer. #35
23.1.0 - 2023-07-04
- Official Python 3.12 support. #9
- Async support. #10
- Retries of arbitrary blocks using (async)
forloops and context managers. #12 - Proper documentation. #16
- A backwards-compatibility policy.
- The timeout, wait_initial, wait_max, and wait_jitter arguments can now also be of type
datetime.timedelta.
22.2.0 - 2022-10-06
- Retries are now instrumented.
If prometheus-client is installed, retries are counted using the Prometheus counter
stamina_retries_total. If structlog is installed, they are logged using a structlog logger at warning level. These two instrumentations are independent from each other.
22.1.0 - 2022-10-02
- Initial release.