astblock
Switch off individual Python statements without editing or redeploying the code.
You write a small JSON blocklist naming statements by an AST fingerprint. When
the program starts with that blocklist, each blocked statement is rewritten at
import time so that it either skips (does nothing) or raises
BlockedStatementError. Everything not on the list is compiled exactly as normal.
The intended use is emergency mitigation: a third-party call that hangs, a side effect that fires twice, a code path that corrupts data. It lets you turn that one statement off with a config change and a restart, while the proper fix goes through your normal release process.
Workflow
# 1. Find the statement's fingerprint
$ python -m astblock list shop.checkout --line 15
15 ebfa39018db86a24 checkout notify_partner_api(order)
# 2. Generate a rule (then add a reason)
$ python -m astblock list shop.checkout --line 15 --json --action skip > blocklist.json
# 3. Verify every rule matches the code you're about to run
$ python -m astblock check blocklist.json
OK shop.checkout ebfa39018db86a24 [skip] line 15: notify_partner_api(order)
# 4. Run with it
$ python -m astblock run --blocklist blocklist.json -m shop.checkout
examples/ contains this exact scenario.
Activating it in an application
Pick one:
- CLI wrapper:
python -m astblock run --blocklist FILE -m yourappor... run --blocklist FILE script.py. - One line at the top of your entry point, before your own modules are
imported:
import astblock; astblock.install_from_env(). It does nothing unlessASTBLOCK_FILEis set. - No code change: a
.pthfile in site-packages containing the single lineimport astblock; astblock.install_from_env()runs at interpreter startup. This is powerful, so only do it in environments you control.
If ASTBLOCK_FILE is set but the file is missing or invalid, startup fails
rather than running unpatched.
Fingerprints
A fingerprint is a hash of the module name, the enclosing function/class path, the statement's AST (without positions), and an occurrence index for identical statements in the same scope. So it:
- survives reformatting, comment changes and code added above it;
- changes if the statement itself changes or moves to another function, so an
old rule stops matching instead of hitting the wrong code. Stale rules are
logged at import time and reported by
astblock check.
Generate fingerprints with the same Python minor version you run in production: AST shapes occasionally change between versions.
Blocklist format
{
"version": 1,
"rules": [
{
"module": "shop.checkout",
"fingerprint": "ebfa39018db86a24",
"action": "skip",
"reason": "Partner API outage, INC-2231"
}
]
}
action is "raise" (the default) or "skip". Scripts run directly use the
module name __main__; code run with -m pkg.mod uses pkg.mod.
Semantics and limits: read before using in an incident
- Skipping is not free. A skipped assignment leaves the name undefined, a
skipped
returnfalls through to the following code, and a skippeddeforimportremoves the name entirely. Block the narrowest statement that does the job, and preferraisewhere the caller already handles errors. - Blocking a compound statement (
if,for,with,def) blocks all of it. - If you block a function's only
yield, it stays a generator (it just yields nothing). - Import time only. Rules apply when a module is imported, so the process
must restart. Modules imported before
install()are not patched, and a warning names them. - Only modules loaded from
.pysource are patchable, not extension modules or pyc-only distributions. Targeted modules are always compiled from source and never cached, so a stale.pyccan't bypass a rule. - Hits are logged to the
astblocklogger (first hit at WARNING, later hits at DEBUG) and counted inastblock.hits(). - Security: whoever can write the blocklist can disable any statement,
including an authorization check. Treat the file and the
ASTBLOCK_FILEvariable with the same care as your deploy credentials.
Python API
import astblock
astblock.install("blocklist.json") # or a Blocklist object
astblock.fingerprint_source(src, "mod") # -> list[Statement]
astblock.hits() # {fingerprint: count}
astblock.uninstall()
Development
pip install -e ".[test]"
pytest
Release files for astblock 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 | |
|---|---|---|---|
| astblock-0.1.0.tar.gz | 15.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| astblock-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.3 kB
Release files / astblock-0.1.0.tar.gz
| Download URL | astblock-0.1.0.tar.gz |
|---|---|
| Size | 15.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8778f590cddf925a30e49765a0e2f3a109e94ca148bd09e86050f91ae1130cc7
|
|
BLAKE2b-256 checksum How to use checksums |
0ef4839304b072b0972467441e9f362b74480a4b29a7889dd36a8ae3e0d9130f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / astblock-0.1.0-py3-none-any.whl
| Download URL | astblock-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c305f3880d8c276c10cd94bf72f7838a49468894377953fbf0fcf7452b8340ca
|
|
BLAKE2b-256 checksum How to use checksums |
e30dcdb7a1177932dece90a89203e3e78c4a6deed76e526c3f2ebff791007a3d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log