Catalog PyPI
PACKAGE EXPLORERView in registry

acornwalk

PyPI

Pure Python ECMAScript 2026 and JSX traversal for native and mapping ESTree ASTs

acornastecmascriptestreejavascriptjsxwalker
Versions collected1
Direct dependencies0From release 2.0.0
Last observed20 Oct, 18:21 UTC

README

Version 2.0.0 documentation

acornwalk

A pure Python semantic walker for ECMAScript ESTree ASTs, targeting node shapes used by ECMAScript 2026 and the explicit JSX extension. Python 3.11+; no runtime dependencies. Native parser objects and deserialized mappings are accepted without copying nodes or mutating the AST.

python -m pip install "acornwalk>=2,<3"

The 2.x release preserves the import and camelCase APIs and requires Python 3.11 or newer. It has no runtime dependencies. For native parser ASTs, install esprima-fork 5.x separately (imported as esprima) and request range=True when using position searches. See the migration notes for the changes to searches, callback state and result objects.

import acornwalk as walk
ast = {"type": "Program", "range": [0, 2], "body": [
    {"type": "ExpressionStatement", "range": [0, 2], "expression":
        {"type": "Identifier", "name": "x", "range": [0, 1]}}
]}
names = []
walk.simple(ast, {"Identifier": lambda node, state: state.append(node["name"])}, state=names)
assert names == ["x"]
assert walk.findNodeAt(ast, 0, 1, "Identifier").node is ast["body"][0]["expression"]
APICallback or result
simple(node, visitors, baseVisitor=None, state=None, override=None)Postorder visitor(node, state)
ancestor(node, visitors, baseVisitor=None, state=None, override=None)Postorder visitor(node, state, ancestors)
recursive(node, state, funcs, baseVisitor=None, override=None)visitor(node, state, recurse) controls child recursion
full(node, callback, baseVisitor=None, state=None, override=None)callback(node, state, category)
fullAncestor(node, callback, baseVisitor=None, state=None, override=None)callback(node, state, ancestors, category)
make(funcs, baseVisitor=None)Independent handler overlay
findNodeAt(node, start, end, test=None, baseVisitor=None, state=None)Innermost exact range match; None bounds are wildcards
findNodeAround(node, pos, test=None, baseVisitor=None, state=None)Innermost containing match, including end boundary
findNodeAfter(node, pos, test=None, baseVisitor=None, state=None)First outermost match starting at/after pos
findNodeBefore(node, pos, test=None, baseVisitor=None, state=None)Greatest end at/before pos; ties favor outer nodes

Searches return Found(node, state) or None. Tests are node type strings, None for any type, or (category, node) -> bool callables. Callback exceptions propagate. Ancestor stacks contain the current node and are reused; copy the list when retaining it. State None supplies ancestors as state for ancestor walkers. Explicit False, 0, "", {} and [] remain the supplied state.

seen = []
walk.fullAncestor(ast, lambda node, state, stack, category:
    seen.append((walk.getField(node, "type"), len(stack))))
walk.recursive(ast, names, {"Identifier": lambda node, state, recurse:
    state.append(walk.getField(node, "name"))})
base = walk.make({"MyExtension": lambda node, state, recurse:
    recurse(walk.getField(node, "argument"), state, "Expression")})
walk.simple({"type": "MyExtension", "argument": ast["body"][0]["expression"]}, {}, base)

Visitor keys may be concrete types or categories such as Expression, Statement, Pattern and VariablePattern. Bindings use VariablePattern; ordinary references use Identifier. Noncomputed keys, labels, import binding metadata, export specifier metadata and meta-property names are skipped as evaluated references. Import attributes visit their value, not their key. This is semantic traversal, not an exhaustive serialization visitor.

Custom bases may be mappings, Base objects or overlays. Instance and subclass overrides are honored. Base handlers have the unbound signature (node, state, recurse); subclass handlers should use that signature or @staticmethod. make does not mutate the supplied base. Unknown types raise ValueError naming the type and the extension mechanism.

Positions are nonnegative integer UTF-16 code-unit offsets. Searches use start/end or two-element range; start/end take precedence. Astral characters occupy two units. Offsets are read as supplied, not converted from Python scalar indices. With esprima-fork, request range=True. Missing/invalid positions raise ValueError. nodeRange(node) exposes this accessor. getField(node, name, default=None) reads mapping/attribute fields and native isAsync/async_ and allowAwait/await_ aliases. An explicit canonical mapping field takes precedence. Missing native fields honor the supplied default even for esprima's permissive attribute lookup; declared null fields retain None.

Modern traversal covers object rest/spread, async functions/generators, for-await metadata, chains, private names, public/private fields, static blocks, module attributes and dynamic import options. Operators and literal metadata use ordinary expression/leaf shapes. Legacy FieldDefinition is accepted as a PropertyDefinition alias. Explicit JSX handlers cover elements, fragments, names, attributes, expression containers, spread attributes/children and empty expressions. JSX names keep their JSX-specific node types.

TypeScript, Flow, decorators and other proposal nodes require custom visitors. The walker does not validate grammar or editions. Mechanically walking an unknown declaration kind with existing node shapes does not advertise parser support for proposals. Circular graphs and excessive recursion depth are outside the AST contract.

See contributor instructions and CI results. Core parity is pinned to acorn-walk in acorn 8.15.0. Python differences include None state handling, mappings/ranges, validated offsets, native aliases and the documented JSX extension.

Performance measurements compare the original, modern starting and current versions, including the old destructuring omission and remaining native validation cost.

Release automation and version bumps are documented in RELEASING.md.

Downloads & popularity

6downloads
1-day window · source-reported counts20 Oct 2026
7537.50
2026-07-23: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-07-23–2026-07-232026-07-26: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-07-26–2026-07-262026-07-27: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-07-27–2026-07-272026-08-01: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-01–2026-08-012026-08-02: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-02–2026-08-022026-08-03: 4 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-03–2026-08-032026-08-04: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-04–2026-08-042026-08-05: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-05–2026-08-052026-08-07: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-07–2026-08-072026-08-08: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-08–2026-08-082026-08-13: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-13–2026-08-132026-08-14: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-14–2026-08-142026-08-17: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-17–2026-08-172026-08-18: 18 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-18–2026-08-182026-08-19: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-19–2026-08-192026-08-20: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-20–2026-08-202026-08-23: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-23–2026-08-232026-08-24: 8 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-24–2026-08-242026-08-27: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-27–2026-08-272026-08-28: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-08-31–2026-08-312026-09-03: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-03–2026-09-032026-09-06: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-06–2026-09-062026-09-07: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-07–2026-09-072026-09-09: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-09–2026-09-092026-09-10: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-10–2026-09-102026-09-12: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-12–2026-09-122026-09-22: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-22–2026-09-222026-09-23: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-23–2026-09-232026-09-24: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-24–2026-09-242026-09-26: 4 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-26–2026-09-262026-09-27: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-27–2026-09-272026-09-30: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-09-30–2026-09-302026-10-01: 3 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-01–2026-10-012026-10-06: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-06–2026-10-062026-10-07: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-07–2026-10-072026-10-08: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-08–2026-10-082026-10-09: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-09–2026-10-092026-10-10: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-10–2026-10-102026-10-11: 2 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-11–2026-10-112026-10-12: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-12–2026-10-122026-10-13: 75 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-13–2026-10-132026-10-14: 14 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-14–2026-10-142026-10-15: 5 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-15–2026-10-152026-10-16: 4 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-16–2026-10-162026-10-17: 4 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-17–2026-10-172026-10-18: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-18–2026-10-182026-10-19: 1 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-19–2026-10-192026-10-20: 6 · observed 2026-10-21T11:57:14.6767860Z · period 2026-10-20–2026-10-20
23 Jul20 Oct

pypistats · 49 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-20 – 2026-10-2062026-10-21T11:57:14.6767860Z
2026-10-19 – 2026-10-1912026-10-21T11:57:14.6767860Z
2026-10-18 – 2026-10-1812026-10-21T11:57:14.6767860Z
2026-10-17 – 2026-10-1742026-10-21T11:57:14.6767860Z
2026-10-16 – 2026-10-1642026-10-21T11:57:14.6767860Z
2026-10-15 – 2026-10-1552026-10-21T11:57:14.6767860Z
2026-10-14 – 2026-10-14142026-10-21T11:57:14.6767860Z
2026-10-13 – 2026-10-13752026-10-21T11:57:14.6767860Z
2026-10-12 – 2026-10-1212026-10-21T11:57:14.6767860Z
2026-10-11 – 2026-10-1122026-10-21T11:57:14.6767860Z
2026-10-10 – 2026-10-1012026-10-21T11:57:14.6767860Z
2026-10-09 – 2026-10-0912026-10-21T11:57:14.6767860Z
2026-10-08 – 2026-10-0812026-10-21T11:57:14.6767860Z
2026-10-07 – 2026-10-0712026-10-21T11:57:14.6767860Z
2026-10-06 – 2026-10-0612026-10-21T11:57:14.6767860Z
2026-10-01 – 2026-10-0132026-10-21T11:57:14.6767860Z
2026-09-30 – 2026-09-3022026-10-21T11:57:14.6767860Z
2026-09-27 – 2026-09-2712026-10-21T11:57:14.6767860Z
2026-09-26 – 2026-09-2642026-10-21T11:57:14.6767860Z
2026-09-24 – 2026-09-2422026-10-21T11:57:14.6767860Z
2026-09-23 – 2026-09-2322026-10-21T11:57:14.6767860Z
2026-09-22 – 2026-09-2232026-10-21T11:57:14.6767860Z
2026-09-12 – 2026-09-1212026-10-21T11:57:14.6767860Z
2026-09-10 – 2026-09-1012026-10-21T11:57:14.6767860Z
2026-09-09 – 2026-09-0922026-10-21T11:57:14.6767860Z
2026-09-07 – 2026-09-0712026-10-21T11:57:14.6767860Z
2026-09-06 – 2026-09-0622026-10-21T11:57:14.6767860Z
2026-09-03 – 2026-09-0322026-10-21T11:57:14.6767860Z
2026-08-31 – 2026-08-3122026-10-21T11:57:14.6767860Z
2026-08-28 – 2026-08-2812026-10-21T11:57:14.6767860Z
2026-08-27 – 2026-08-2712026-10-21T11:57:14.6767860Z
2026-08-24 – 2026-08-2482026-10-21T11:57:14.6767860Z
2026-08-23 – 2026-08-2332026-10-21T11:57:14.6767860Z
2026-08-20 – 2026-08-2012026-10-21T11:57:14.6767860Z
2026-08-19 – 2026-08-1932026-10-21T11:57:14.6767860Z
2026-08-18 – 2026-08-18182026-10-21T11:57:14.6767860Z
2026-08-17 – 2026-08-1732026-10-21T11:57:14.6767860Z
2026-08-14 – 2026-08-1432026-10-21T11:57:14.6767860Z
2026-08-13 – 2026-08-1322026-10-21T11:57:14.6767860Z
2026-08-08 – 2026-08-0812026-10-21T11:57:14.6767860Z
2026-08-07 – 2026-08-0712026-10-21T11:57:14.6767860Z
2026-08-05 – 2026-08-0512026-10-21T11:57:14.6767860Z
2026-08-04 – 2026-08-0432026-10-21T11:57:14.6767860Z
2026-08-03 – 2026-08-0342026-10-21T11:57:14.6767860Z
2026-08-02 – 2026-08-0212026-10-21T11:57:14.6767860Z
2026-08-01 – 2026-08-0112026-10-21T11:57:14.6767860Z
2026-07-27 – 2026-07-2712026-10-21T11:57:14.6767860Z
2026-07-26 – 2026-07-2612026-10-21T11:57:14.6767860Z
2026-07-23 – 2026-07-2312026-10-21T11:57:14.6767860Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
2.0.013 Oct 20260

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
0o120/acornwalk-python

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 18:21 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:2911bbef96708ac07f9b3d517da9c9d88c79bb1695334e7ea080d44de9ed84ac