1 Commits
Author SHA1 Message Date
dsql 5a8ca8327d release: 1.0.0
first stable release. pre-1.0.0 verification complete: all surviving MED regressions and
gaps resolved and independently re-fired, tree audited clean across the suite.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-06 21:21:00 -04:00
2 changed files with 5 additions and 14 deletions

No files matched your search

+3 -8
View File
@@ -12,15 +12,15 @@ Small sync helpers shared across projects. Base is stdlib only — **no dependen
## Install
```
commons @ git+ssh://git@git.rethinkstudios.io/rethink-public/commons.git@v1.0.0
commons @ git+ssh://git@git.rethinkstudios.io/rethink-public/commons.git@v0.3.5
# async address/geo lookups (fetch_ip / ip_location / fetch_location) need the extra:
commons[addr] @ git+ssh://git@git.rethinkstudios.io/rethink-public/commons.git@v1.0.0
commons[addr] @ git+ssh://git@git.rethinkstudios.io/rethink-public/commons.git@v0.3.5
```
The base install pulls **nothing** (stdlib). Only `commons[addr]` adds `aiohttp`, and
only for the geo lookups — the pure `commons.addr.ip` utilities ship in base.
Drop the `@v1.0.0` suffix from the line above to install the latest unpinned.
Drop the `@v0.3.5` suffix from the line above to install the latest unpinned.
## timing
@@ -202,11 +202,6 @@ async def pull():
...
```
The decorator always needs parentheses, even with no kwargs: `@retry()` / `@aretry()`. A
bare `@retry` / `@aretry` is the call form applied to the function: `@retry` runs it once
at import time and replaces it with its return value, and `@aretry` replaces it with a
coroutine that is never awaited.
Knobs: `attempts` (total tries), `backoff` / `factor` / `max_backoff` (delay is
`min(backoff * factor**n, max_backoff)`), `jitter` (full jitter, on by default),
`on=` (tuple of retryable exception types), and `give_up=lambda exc: ...` to stop early
+2 -6
View File
@@ -56,9 +56,7 @@ def retry(
):
"""retry a sync callable with exponential backoff; call form (`retry(fn, ...)`) or decorator
the decorator needs parentheses - `@retry()` / `@retry(attempts=5)`. a bare `@retry`
is the call form: it runs the function once at import time and replaces it with the
result. `attempts` is floored at 1 so the callable always runs at least once.
`attempts` is floored at 1 so the callable always runs at least once.
"""
types = _as_types(on)
attempts = max(1, attempts)
@@ -108,9 +106,7 @@ def aretry(
):
"""async twin of `retry`; call form (`await aretry(coro_fn, ...)`) or decorator, same semantics
the decorator needs parentheses - `@aretry()` / `@aretry(attempts=5)`. a bare `@aretry`
is the call form: it replaces the function with a never-awaited coroutine. `attempts`
is floored at 1 so the callable always runs at least once.
`attempts` is floored at 1 so the callable always runs at least once.
"""
types = _as_types(on)
attempts = max(1, attempts)