Skip to main content

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 yourapp or ... 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 unless ASTBLOCK_FILE is set.
  • No code change: a .pth file in site-packages containing the single line import 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 return falls through to the following code, and a skipped def or import removes the name entirely. Block the narrowest statement that does the job, and prefer raise where 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 .py source are patchable, not extension modules or pyc-only distributions. Targeted modules are always compiled from source and never cached, so a stale .pyc can't bypass a rule.
  • Hits are logged to the astblock logger (first hit at WARNING, later hits at DEBUG) and counted in astblock.hits().
  • Security: whoever can write the blocklist can disable any statement, including an authorization check. Treat the file and the ASTBLOCK_FILE variable 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)

Source distribution for astblock 0.1.0
File Size Uploaded
astblock-0.1.0.tar.gz 15.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for astblock 0.1.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page