API reference¶
One module, four callables, seven exception types. Everything is stdlib-only.
rewrite(transform, verify=True)¶
Decorator factory. Returns a decorator that re-defines the function from its transformed AST.
- transform: an
ast.NodeTransformerinstance (itsvisitis called on theModule) or a callable fromast.Moduletoast.Module. Returning anything except theModuleraisesRedefError. - verify: run verify-by-recompile during acquisition. Default
True. - Contract: must be the innermost decorator. Functions carrying
__wrapped__are refused withInnermostViolation. - Preserved from the original:
__defaults__,__kwdefaults__,__qualname__,__dict__entries. The module's__future__compiler flags are inherited into the recompile. - Raises: any
RedefErrorsubclass below;ClosureUnsupportedif the function has free variables.
rewrite.expansion(f)¶
The unparsed source of the transformed function, as compiled. Raises RedefError if f was not produced by rewrite. Stored on the function as __redef_source__.
recover(fn, verify=True)¶
Acquisition without transformation: returns (tree, meta).
- tree: an
ast.Modulewhose single statement is theFunctionDef(orAsyncFunctionDef), decorator list stripped, line numbers offset to true file positions. - meta: a dict with:
filename: the code object'sco_filenamefirst_lineno: where the recovered snippet started in its filerepairs: which repairs ran, from"dedent","strip-decorators","increment-lineno","verify-recompile","verify-recompile-structural"freevars: the function'sco_freevars
- Closures are accepted here; only recompilation refuses them. Verification compiles closures inside a synthetic enclosing scope.
- Also available as
rewrite.recover.
Use recover when your tool analyzes or relocates the body rather than re-defining it in place: transpilers, remote executors, DSL projectors.
gensym(base="tmp", avoid=None)¶
A fresh identifier of the form _{base}_{n}, guaranteed absent from every Name and argument in avoid (any AST node) when given. Process-global counter; successive calls never repeat.
Exceptions¶
All derive from RedefError.
| Exception | Raised when | Attributes |
|---|---|---|
SourceUnavailable |
no source exists in this context | reason ("frozen-or-sourceless", "stdin", "repl", "bare-exec", "unknown: ..."), remedy (str or None) |
SourceMismatch |
recovered text defines a different function, or a same-named body fails verification | |
SourceUnparseable |
recovered text does not parse | |
NotAFunction |
not a plain def (lambdas, non-functions) |
|
ClosureUnsupported |
recompiling a function with free variables | |
InnermostViolation |
the function carries __wrapped__ |
Catching RedefError at your tool's boundary and re-raising in your own vocabulary is the intended pattern:
try:
tree, meta = recover(fn)
except RedefError as exc:
raise MyToolError(f"cannot read {fn.__name__}: {exc}") from exc
Versioning and stability¶
Unreleased. The shapes above are stable in intent; names (including the package name) are not. Supported interpreters: CPython 3.10 through 3.14, tested at -O and -OO.