retry-claim-audit
Offline audit of documented retry claims against Python source.
A standard-library-only static auditor for Python 3.9+. It executes no audited
code, makes no network calls, and never reads .env contents. Symlinked files
and directories are skipped. Files are read only within the audited tree.
Usage
python3 -m pip install .
retry-claim-audit /path/to/project
python3 -m retry_claim_audit /path/to/project --json
retry-claim-audit . --ignore 'vendor/*' --ignore 'generated/*' --verbose
retry-claim-audit . --fail-on HIGH
retry-claim-audit --version
PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m build
--ignore is repeatable and matches globs against relative paths. --verbose
shows verified families and parse/read warnings. JSON always includes
findings, verified_claims, and errors; findings include rule, severity,
claims, and evidence with relative paths and line numbers. Exit 0 means PASS
at the selected threshold, 2 means FAIL, and 1 means usage error. The default
threshold is MEDIUM; HIGH retains MEDIUM findings in output but exits 0 for
a MEDIUM-only report. Version: 0.1.0.
Rules
| Rule | Severity | Condition |
|---|---|---|
| documented-retry-claim-false | HIGH | Retry family claimed, zero production evidence |
| documented-retry-claim-false-test-only | MEDIUM | Retry family claimed, evidence only in tests/fixtures |
| documented-single-attempt-claim-false | HIGH | Single-attempt family claimed, production evidence exists |
| documented-single-attempt-claim-false-test-only | MEDIUM | Single-attempt family claimed, evidence only in tests/fixtures |
Each family produces at most one finding, including all relevant evidence.
No production source produces a HIGH finding per claimed family with
no-source evidence. No claims means PASS. Retry claims with production
evidence are verified; single-attempt claims with zero evidence anywhere are
verified. Contradictory families are audited independently.
Honest limitations
Claims come only from root README.md and docs/**/*.md. Fenced code is excluded; inline code counts. Claims use case-insensitive exact phrases only:
Retry: “retries on failure”, “retries on error”, “retries transient errors”,
“retries failed requests”, “automatic retries”, “automatically retries”,
“retries automatically”, “with retries”, “retry logic”.
Single-attempt: “single attempt”, “one attempt”, “fails immediately”.
Bare retry/retries words do not count. Unlisted hyphen variants do not count. A sentence containing no, not, never, without, doesn't, don't, or isn't suppresses all claims in that sentence. Negation-phrased single-attempt claims such as “no retries” and “does not retry” are therefore not counted. Sentence boundaries use periods, question marks, and exclamation marks.
The named evidence table is deliberately limited:
| Evidence | Static recognition |
|---|---|
| Imports | tenacity, backoff, retrying, including aliases and submodules |
| Calls/decorators | retry, Retrying, wait_exponential, wait_fixed, wait_random, wait_random_exponential, retry_if_exception, retry_if_exception_type, retry_if_result, on_exception, on_predicate; any receiver |
| Attempt limit | stop_after_attempt with first argument literal greater than 1 |
| Adapters | Retry calls; HTTPAdapter/mount calls with literal max_retries greater than 0 |
| Loops | For/While (including async for) with a Try in the body and either an except-body continue or attempt/retry/tries in a target or iterable/bound identifier |
max_retries=0 and stop_after_attempt(1) are excluded. Nonliteral limits
are unknown and skipped. The loop heuristic can overcount nested handling
and cannot prove the number of attempts. Async loops use the same evidence
kind. Imports count even when unused; dead code counts. This intentional
over-approximation proves presence of primitives, not runtime correctness.
Bare requests/urllib3/httpx imports, time.sleep, standalone try/except, logging,
and catching/re-raising alone are not evidence. Other third-party libraries
are out of scope. Production excludes tests/, fixtures/, test_*.py, *_test.py,
docs/, and examples/; test/fixture evidence is collected separately, while
docs/examples source is excluded entirely. Invalid or unreadable source is
reported in JSON errors and verbose output; it supplies no evidence.
Differentiation
- error-claim-audit checks exit codes, exceptions, and messages rather than attempt counts.
- concurrency-claim-audit checks simultaneous work rather than repeated attempts.
- config-claim-audit checks documented default values rather than retry behaviour.
- bandit/ruff check code issues rather than documentation promises.
- tenacity/backoff documentation, pytest, and timing benchmarks describe or test runtime behaviour; this tool compares documentation to static evidence.
MIT licensed. Local analysis requires no service or credentials.
Metadata
Release files for retry-claim-audit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| retry_claim_audit-0.1.0.tar.gz | 10.8 kB | Without provenance | Details for retry_claim_audit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| retry_claim_audit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for retry_claim_audit-0.1.0-py3-none-any.whl |
Total release size: 19.2 kB
Release files / retry_claim_audit-0.1.0.tar.gz
| Download URL | retry_claim_audit-0.1.0.tar.gz |
|---|---|
| Size | 10.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f0638b8d9b7d95c71884ac2c5b939981f8d7e0f711b0f5418c364808312cacaf
|
|
BLAKE2b-256 checksum How to use checksums |
dcf151423df7285c6f817e3fd61d961a11f2468cf4fbaa033bcc96adc89813f6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / retry_claim_audit-0.1.0-py3-none-any.whl
| Download URL | retry_claim_audit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
23b69bd0dc3dc81f0b97028f755981890cf2da8d0feac5377e9c6f955fabe9aa
|
|
BLAKE2b-256 checksum How to use checksums |
f052551c5d334a7cf47b33aa36cfb450c0a4890bdeedd6fcc99ec97b0ea82c97
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for retry-claim-audit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.