fix: floor retry/aretry attempts at 1 (v0.2.1)
retry(fn, attempts=0) (or negative) silently returned None without ever calling fn, looking like success. floor attempts at max(1, attempts) so the callable always runs at least once; a failing call now fails loud after one try instead of no-op None. verified: attempts=0/-5 -> 1 call (sync + async); failing fn raises after 1 try; 31/31 retry regression intact. Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
parent
0939917172
commit
c6e3dd1b54
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "commons"
|
name = "commons"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
description = "small stdlib-only sync helpers: time/timezone deltas, dotted-path dict access, display masking, ip/address tooling, and retry/backoff"
|
description = "small stdlib-only sync helpers: time/timezone deltas, dotted-path dict access, display masking, ip/address tooling, and retry/backoff"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|||||||
@ -63,4 +63,4 @@ __all__ = [
|
|||||||
"aretry",
|
"aretry",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "0.2.0"
|
__version__ = "0.2.1"
|
||||||
|
|||||||
@ -77,8 +77,10 @@ def retry(
|
|||||||
`retry(fn, ...)` runs immediately; `@retry(...)` wraps a function. retries on the
|
`retry(fn, ...)` runs immediately; `@retry(...)` wraps a function. retries on the
|
||||||
`on` exceptions, stops early if `give_up(exc)` is true, re-raises the last
|
`on` exceptions, stops early if `give_up(exc)` is true, re-raises the last
|
||||||
exception once `attempts` are exhausted. `sleep`/`rand` are injectable for tests.
|
exception once `attempts` are exhausted. `sleep`/`rand` are injectable for tests.
|
||||||
|
`attempts` is floored at 1 so the callable always runs at least once.
|
||||||
"""
|
"""
|
||||||
types = _as_types(on)
|
types = _as_types(on)
|
||||||
|
attempts = max(1, attempts)
|
||||||
|
|
||||||
def run(target: Callable, args, kwargs):
|
def run(target: Callable, args, kwargs):
|
||||||
delays = list(_delays(attempts, backoff, factor, max_backoff))
|
delays = list(_delays(attempts, backoff, factor, max_backoff))
|
||||||
@ -128,8 +130,10 @@ def aretry(
|
|||||||
async twin of `retry`. `await aretry(coro_fn, ...)` runs immediately;
|
async twin of `retry`. `await aretry(coro_fn, ...)` runs immediately;
|
||||||
`@aretry(...)` wraps a coroutine function. same semantics: retry on `on`, stop on
|
`@aretry(...)` wraps a coroutine function. same semantics: retry on `on`, stop on
|
||||||
`give_up`, re-raise the last exception after `attempts`. `sleep`/`rand` injectable.
|
`give_up`, re-raise the last exception after `attempts`. `sleep`/`rand` injectable.
|
||||||
|
`attempts` is floored at 1 so the callable always runs at least once.
|
||||||
"""
|
"""
|
||||||
types = _as_types(on)
|
types = _as_types(on)
|
||||||
|
attempts = max(1, attempts)
|
||||||
|
|
||||||
async def run(target: Callable, args, kwargs):
|
async def run(target: Callable, args, kwargs):
|
||||||
delays = list(_delays(attempts, backoff, factor, max_backoff))
|
delays = list(_delays(attempts, backoff, factor, max_backoff))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user