async-claim-audit
Audit documented awaitability promises against static Python evidence.
A standard-library-only, offline checker for documentation contracts. It never executes inspected code, uses no network, and never reads .env contents. Symlinked files and directories are skipped; inspected files stay inside the supplied tree.
Usage
python3 -m pip install .
async-claim-audit path/to/project
python3 -m async_claim_audit path/to/project --json
async-claim-audit path/to/project --ignore 'vendor/*' --verbose --fail-on HIGH
async-claim-audit --version
PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m build
The optional path defaults to the current directory. --ignore accepts repeatable relative-path globs, including directory paths; ignoring a directory prunes its subtree. --verbose includes evidence in text output. JSON always includes findings, verified_claims, and parse errors. Findings include rule, severity, claim sentences and evidence locations. Exit codes: 0 passes the severity threshold, 2 fails it, 1 indicates usage, filesystem, decoding or parsing errors. MEDIUM is the default threshold; HIGH allows MEDIUM findings without failing.
Rules
| Rule | Severity | Condition |
|---|---|---|
documented-async-claim-false |
HIGH | Positive promise with no production evidence |
documented-async-claim-false-test-only |
MEDIUM | Positive promise supported only by tests or fixtures |
documented-sync-claim-false |
HIGH | Synchronous promise contradicted by production evidence |
documented-sync-claim-false-test-only |
MEDIUM | Synchronous promise with evidence only in tests or fixtures |
One finding is emitted per family, with all associated claim sentences and relevant evidence. A family with no production Python source gets a HIGH finding carrying no-source, overriding the test-only rule. Both families are evaluated independently. A positive promise with production evidence is verified; a synchronous promise with no evidence anywhere is verified. With no claims, any amount of evidence passes (assuming readable, parseable input).
Documentation matching
Only root README.md and docs/**/*.md are checked. Fenced blocks are excluded; inline code counts as prose. Sentences are lowercased, contractions ending in n't expand to not, hyphens become spaces, and whitespace collapses. Matching uses exact phrases with word boundaries. Synchronous phrases are matched first and their spans masked before positive matching. Any negation word (no, not, never, without) suppresses positive matching for that sentence, while listed synchronous negations still count.
The full phrase vocabulary and illustrative edge cases are below. Phrase lists are deliberately fenced so this tool can audit itself without manufacturing claims.
ASYNC:
async support; supports async; async api; asyncio support;
supports asyncio; asyncio compatible; async compatible; fully async;
async first; async interface; async client; asyncio client;
asynchronous api; asynchronous support; awaitable api; can be awaited
SYNC:
synchronous api; sync api; synchronous interface; synchronous client;
synchronous only; sync only; blocking api; blocking only;
runs synchronously; no async support; no asyncio support;
does not support async; does not support asyncio; not async;
not asyncio compatible
no async support -> sync only (overlap masking)
isn't async -> is not async -> sync
async-first -> async first -> async
never async -> no claim (intentional negation asymmetry)
async -> no claim; asyncio -> no claim
Evidence
| AST evidence | Kind |
|---|---|
async def, including nested functions and methods |
async-def |
await expression |
await |
async with statement |
async-with |
async for statement |
async-for |
Dotted calls to asyncio.run, asyncio.create_task, asyncio.gather, asyncio.ensure_future, asyncio.wait |
asyncio-call |
Calls with terminal names ending in AsyncClient or AsyncSession |
async-constructor |
Evidence is deduplicated by relative path, line, and kind. Production excludes tests/, fixtures/, test_*.py, *_test.py, docs/, examples/, and symlinks. Tests and fixtures provide separate evidence; docs and examples provide none. Common environment, build and version-control directories are pruned.
Differentiation
- concurrency-claim-audit checks existence of parallelism, never awaitability.
- api-claim-audit checks symbol existence and signatures, never awaitability.
- thread-safety-claim-audit checks synchronisation, never awaitability.
- Bandit and Ruff detect code issues, never documentation promises.
- The asyncio, AnyIO and Trio documentation explains primitives and runtimes, never documentation-versus-code truth.
Honest limitations
This is exact-phrase and project-wide evidence matching, not symbol-level contract verification. Dead code counts, including uncalled definitions. Presence of machinery cannot establish that a particular documented callable is awaitable or correct.
A bare import asyncio or from asyncio import ... does not count. Bare names, comments and string literals do not count. A plain function returning an already-built coroutine does not count by itself. Third-party decorators and context managers, including AnyIO and Trio task groups, are not inferred beyond the named constructor rule. An asynchronous route written with async def is covered normally.
Only the exact dotted asyncio calls in the table count: aliases and bare run(...) calls are not resolved. Constructor matching is an intentional over-approximation; receiver types are not inferred. A synchronous wrapper calling asyncio.run(...) counts as evidence and contradicts a synchronous promise by design. Syntax errors are reported with exit 1 rather than treated as a successful audit. Parsing follows the interpreter running the tool; inspected syntax must be supported by that interpreter.
License
MIT.
Metadata
Release files for async-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 |
|---|---|---|---|---|
| async_claim_audit-0.1.0.tar.gz | 10.8 kB | Without provenance | Details for async_claim_audit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| async_claim_audit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for async_claim_audit-0.1.0-py3-none-any.whl |
Total release size: 19.1 kB
Release files / async_claim_audit-0.1.0.tar.gz
| Download URL | async_claim_audit-0.1.0.tar.gz |
|---|---|
| Size | 10.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5e214f2df9c31591b0e0a29685aa6b9784ea473c1a9c2bd347df153c2124ec83
|
|
BLAKE2b-256 checksum How to use checksums |
cfd3d67f8f97e63f094e03bf070ec016446082c7e94a6c67ef73ae44588c8286
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / async_claim_audit-0.1.0-py3-none-any.whl
| Download URL | async_claim_audit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9b142eebeb32e593e1ce7bc3cec08d9837b6150e6b49a9885d9d3693129a6447
|
|
BLAKE2b-256 checksum How to use checksums |
1471311c50ca3e798a72fae10fd9384af7f6a5a66a8a44fb5e93637a4b20d11d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for async-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.