Getting started¶
Install¶
redef is not yet on PyPI. It is a single stdlib-only module; until release, vendor it:
Python 3.10 through 3.14 are supported and tested, including under -O and -OO.
Your first rewrite¶
A transform is an ast.NodeTransformer (or any callable from ast.Module to ast.Module). Here is one that doubles every integer constant, applied to a function:
import ast
from redef import rewrite
class Double(ast.NodeTransformer):
def visit_Constant(self, node):
if isinstance(node.value, int) and not isinstance(node.value, bool):
return ast.copy_location(ast.Constant(node.value * 2), node)
return node
@rewrite(Double())
def answer(x):
return x + 20
print(answer(1)) # 41: the constant 20 became 40 at definition time
Three things happened when Python executed the def:
redefrecovered the function's source, applied the repairs (dedent, decorator stripping, line-number offsets), and checked that the recovered text really definesanswer, including recompiling it and comparing code objects (see Verification).- Your transform received the parsed tree and returned it modified.
- The result was compiled under the module's own compiler flags and
answerwas re-defined from it, keeping its original defaults,__qualname__, and attributes.
Seeing what you did¶
A rewrite you cannot display is a rewrite you cannot review:
When it refuses¶
redef fails loudly wherever the naive pipeline misbehaves silently. All errors derive from RedefError:
from redef import rewrite, RedefError
def outer():
secret = 7
def uses(x):
return x + secret
return rewrite(Double())(uses)
outer()
# ClosureUnsupported: closes over ('secret',); recompiling would turn
# these into global lookups (E5 F5)
Lambdas, functions carrying __wrapped__, sourceless contexts, and stale sources each raise their own error with the reason named. The catalogue is in Support matrix; the API in Reference.
The innermost rule¶
@rewrite(...) must be the decorator closest to def. Decorators apply bottom-up, so anything applied below the rewrite would be discarded by recompiling from source. redef refuses functions that advertise a wrapper (__wrapped__) and documents the rest of the contract; see Design.
Next¶
- Writing transforms: locations, hygiene, templates.
- Support matrix: where recovery works, and the remedies where it can.
- Verification: what the stale-source detector catches and what it costs.