0.2.0

Incremental parsing, AST diffing, visitor/transform, serialization

1 min read 292 words 3 days ago

Released: 2026-02-13

AST tooling and incremental parsing for editor integrations and incremental builds.

Highlights

  • Incremental re-parsing — O(change) updates instead of O(document) full re-parse
  • AST differ — Structural diff between two Documents for change detection
  • Visitor + transform — Typed traversal and immutable rewriting
  • Serialization — JSON round-trip for caching and wire transfer
  • Thread-safety fixget_headingsnow safe under free-threading

Features

Incremental Parsing

from patitas import parse_incremental, parse

prev = parse("# Hello\nWorld")
# User edits "World" → "Updated" (char 7–12)
new_doc = parse_incremental(
    "# Hello\nUpdated", prev, edit_start=7, edit_end=12, new_length=7
)

Re-parses only blocks overlapping the edit. Unaffected blocks are reused.

AST Diffing

from patitas import parse, diff_documents

old_doc = parse("# Hello\nWorld")
new_doc = parse("# Hello\nUpdated world")

for change in diff_documents(old_doc, new_doc):
    print(f"{change.kind} at {change.path}")

Use for incremental builds, live preview, or change detection.

Visitor and Transform

from patitas import parse, BaseVisitor, transform, Heading

class HeadingCollector(BaseVisitor[None]):
    def __init__(self) -> None:
        self.headings: list[Heading] = []

    def visit_heading(self, node: Heading) -> None:
        self.headings.append(node)

doc = parse(source)
collector = HeadingCollector()
collector.visit(doc)

transform(doc, fn)rewrites the AST immutably (bottom-up).

Serialization

from patitas import parse, to_dict, from_dict, to_json, from_json

doc = parse("# Hello **World**")

# Dict format (in-memory caching, e.g. Bengal incremental builds)
data = to_dict(doc)
restored = from_dict(data)

# JSON format (persistence, wire transfer)
json_str = to_json(doc)
restored = from_json(json_str)

Deterministic output for cache-key stability. See Serialization.

Installation

pip install patitas>=0.2.0
pip install patitas[syntax]   # Syntax highlighting via Rosettes

Breaking Changes

None — all additions are backwards compatible.

Documentation