v2.2.2
·
25 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
Follow-up to #27. When I folded the copy-pasted retry loop into _get_json_with_retry, I flagged that its retry path had no test coverage — the fake aiohttp session never raised, so only the happy path was exercised. Same was true of list_gcr_tags, which kept its own retry loop (it has a pre-raise_for_status 401 check).
Test-only, no source changes.
Adds:
_get_json_with_retry— recovers after transient errors; exhaustsmax_retriesthen re-raises; sleeps with exponential backoff (2**0, 2**1, …) between attempts and not after the last;max_retriesis honoured.list_gcr_tags— a401returns[]immediately with no retry/sleep; transient errors are retried then succeed; after exhausting retries the outer handler swallows the raise and returns[].list_ghcr_tags— a transient error on the tags request recovers through the shared helper.
Infra: a SequencedSession fake (each URL maps to a queue of outcomes, so a call can fail then succeed) and an autouse fixture that stubs asyncio.sleep and records the delays instead of waiting.
pytest 153 passed · ruff check + ruff format --check clean.