Skip to main content

astToolkit

Easily and Confidently Transform Python Code Using Unadulterated AST Classes

astToolkit provides composable, typed tools for analyzing, transforming, and generating Python code. Select the nodes you care about, describe an action, and apply it through a visitor.

Compatibility with the standard library's ast is an intentional design goal. astToolkit works directly with the same ast.AST objects. You can parse with ast, transform with astToolkit, and return to ast for inspection, unparsing, or compilation. There is no conversion step or separate tree representation.

import ast
from astToolkit import Grab, IfThis, NodeChanger, Then

astModule: ast.Module = ast.parse('result = value * 2')

NodeChanger(
    IfThis.isNameIdentifier('value'),
    Grab.idAttribute(Then.replaceWith('amount')),
).visit(astModule)

print(ast.unparse(astModule))
# result = amount * 2

This changes the identifier on the existing ast.Name node. The module and its nodes remain available to your own visitors and other tools that work with stdlib ASTs.

Installation

Requires Python 3.14 or later.

pip install astToolkit

Compose the operation you need

The core pattern is predicate + action + visitor. A predicate identifies a node; an action reads or changes it; a visitor applies that operation throughout a tree.

Tool Purpose
Be Check node types with TypeIs guards, such as Be.FunctionDef, and compose conditions on their fields.
DOT Read node attributes through typed getters, such as DOT.name or DOT.value.
Grab Transform an attribute while retaining its containing node.
Make Construct AST nodes with typed parameters and convenient defaults.
IfThis Match identifiers, structure, and combinations of conditions.
Then Collect, extract, insert, replace, or remove matched nodes.
NodeTourist Visit nodes for inspection and collection; captureLastMatch returns the last action result.
NodeChanger Transform matching nodes, including replacing or removing them.

NodeTourist extends ast.NodeVisitor; NodeChanger extends ast.NodeTransformer. A matching NodeChanger node is handed to its action without automatically visiting that node's children. Compose visitors or attribute actions when a transformation needs to continue inside a match.

Read and collect

Use a DOT getter to retrieve an attribute directly, or Then.appendTo to collect matching nodes:

import ast
from astToolkit import Be, DOT, NodeTourist, Then

astModule: ast.Module = ast.parse('result = value * 2')

identifier: str | None = NodeTourist(
    Be.Name, DOT.id,
).captureLastMatch(astModule)

print(identifier)
# value

list_astName: list[ast.Name] = []
NodeTourist(Be.Name, Then.appendTo(list_astName)).visit(astModule)

The collected nodes are the original objects in astModule. Extraction does not copy or wrap them.

Build nodes

Make works with stdlib node types. For example, Make.Name('amount') returns an ast.Name with a Load context:

import ast
from astToolkit import Make

astName: ast.Name = Make.Name('amount')

print(type(astName) is ast.Name)
# True

print(ast.compare(astName, ast.Name(id='amount', ctx=ast.Load())))
# True

Operator joins assemble expressions without manually nesting each binary operation:

import ast
from astToolkit import Make

ast_expr: ast.expr = Make.Add.join([
    Make.Name('subtotal'),
    Make.Name('tax'),
    Make.Name('shipping'),
])

print(ast.unparse(ast_expr))
# subtotal + tax + shipping

astModule: ast.Module = Make.Module([Make.Expr(ast_expr)])
compile(ast.fix_missing_locations(astModule), '<generated>', 'exec')

Some Make operator classes, including Make.Add, subclass their stdlib counterparts to provide join. They work with stdlib AST tools; ast.compare distinguishes those subclasses from the exact stdlib classes. I want to change this.

Match structure

Use IfThis.astIs(referenceNode) for structural matching through ast.compare. Field predicates, such as Be.Assign.valueIs(...), select a containing node by a condition on one of its fields. IfThis.isAllOf(...) applies every condition to the same node; nested visitors search within a selected subtree.

Find the function you need

Utility functions have focused module homes:

Module Functions
astToolkit.changeDef extractClassDef, extractFunctionDef, makeDictionaryAsyncFunctionDef, makeDictionaryClassDef, makeDictionaryFunctionDef, makeDictionaryMosDef, inlineFunctionDef, removeUnusedParameters
astToolkit.filesystem parsePathFilename2astModule, parseLogicalPath2astModule, write_astModule
astToolkit.ohWow pythonCode2ast_expr, unjoinBinOP, unparseFindReplace
  • Definitions: extract a named function or class, index definitions by name, inline supported local function calls, or remove unused parameters.
  • Files: parse a source file without importing it, parse an importable module's source, or write an ast.Module as formatted Python. parseLogicalPath2astModule imports the module; write_astModule removes unused imports and organizes imports.
  • Expressions: parse expression text, collect binary-operation operands, or replace nodes by matching their unparsed text.

Import these functions from their modules, for example:

from astToolkit.changeDef import extractFunctionDef, removeUnusedParameters
from astToolkit.filesystem import parsePathFilename2astModule, write_astModule

Type aliases describe AST fields and the node types that contain them. The package includes py.typed for static type checking.

Breaking change in 0.13.0: IngredientsFunction, IngredientsModule, and LedgerOfImports have been removed.

Larger workflows

mapFolding uses astToolkit to transform readable algorithms into specialized variants and generate Python modules.

Most of the core toolkit code is generated by the separate astToolFactory project.

Support my work

If astToolkit saves you time, please sponsor my work on GitHub. Monthly or one-time support helps me survive. You can also choose another way to support me.

Homeless since August 2011

Citation and license

Citation metadata is available in CITATION.cff.

CC-BY-NC-4.0

Metadata

Release files for astToolkit 0.13.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 astToolkit 0.13.0
File Size Uploaded Provenance Actions
asttoolkit-0.13.0.tar.gz 122.1 kB Without provenance Details for asttoolkit-0.13.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for astToolkit 0.13.0
File Interpreter ABI Platform Actions
asttoolkit-0.13.0-py3-none-any.whl Python 3 none any Details for asttoolkit-0.13.0-py3-none-any.whl

Total release size: 252.3 kB

Release files / asttoolkit-0.13.0.tar.gz

Download URL asttoolkit-0.13.0.tar.gz
Size 122.1 kB
Tags Source
SHA-256 checksum
How to use checksums
6fe3d3c943f7b55d887d3deffe9f033f5007cf0b271dd2db629b8a31e71fa421
BLAKE2b-256 checksum
How to use checksums
673d4d4c0be539d3e1f794fe0db42c21b268810e49abf387a95a5f10bdc660d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / asttoolkit-0.13.0-py3-none-any.whl

Download URL asttoolkit-0.13.0-py3-none-any.whl
Size 130.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
78f54bf7913da9aa154fbf5eeb83809057b25312dfb4b9ca4214ba5cbd1d66ce
BLAKE2b-256 checksum
How to use checksums
8e55864d9136e0540092f1bdc39059e63b5a2ac23cdaf293998bddd2900f4a37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Security for astToolkit 0.13.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.

Release history Release notifications | RSS feed

This release

0.13.0 This release

2 release files No provenance

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