api-parity.tsv is the exhaustive, reviewable mapping from the
in-scope public Rust API to the installed Python package. It covers
jbotci-source (including diagnostics returned through that API),
jbotci-dialect, jbotci-morphology, jbotci-syntax,
jbotci-dictionary, jbotci-dictionary-data, jbotci-jvozba, and only the
references module of jbotci-semantics.
The tab-separated format keeps the large generated portion easy to diff and
validate without maintaining hand-counted totals. Each row is keyed by
rust_path plus kind, because Rust permits a field and method to share a
name. The columns are:
rust_path,kind, andrust_signature: mechanically extracted identity;disposition: exactly one ofdirect,python-equivalent,subsumed, orrust-only;python_path: the named public Python symbol for the first three dispositions;exclusion_kindandrationale: a typed, concrete explanation required only for Rust-only machinery.
The subsumed rows are generated from the following reviewed patterns. The
counts describe the current checked-in matrix and sum to its 6,504 subsumed
rows; the generator and drift check derive membership mechanically rather than
relying on these documentation counts.
| Pattern | Rows | Meaning |
|---|---|---|
| Generated grammar traversal | 3,249 | A Rust walker callback or descent function is represented by the same immutable typed child fields and structural matching in Python. |
| Recovered-boundary conversion | 1,365 | Rust ownership conversions between valid and recovered nodes are performed by the public strict-or-recovered parse operation. |
| Named public concept | 916 | A method, constructor, field, or normalized operation is carried by the named immutable Python class or closed union. |
| Borrowed generated node reference | 912 | Rust's borrowed NodeRef/AtomRef tag becomes the corresponding independently owned typed Python node or token. |
WithIndicators convenience operation |
16 | Named variants and their typed fields retain the word, indicator, quote-marker, and span information used by the Rust helper. |
| Token convenience operation | 13 | Token.core_word or Token.source_spans retains the result of a Rust predicate, constructor, or caller-owned accumulator helper. |
WithFreeModifiers convenience operation |
12 | The immutable value and free_modifiers projections retain the wrapper data and support the corresponding token inspection. |
| Exact string carrier | 12 | A Rust kind method returning code, message, label, detail, or display text names the exact Python value property or diagnostic field that carries that string. |
| Rendered-message error | 5 | The Rust error has no structured payload beyond its rendered message, which the named Python exception preserves exactly. |
| Dictionary rafsi storage target | 3 | Dictionary.lookup_rafsi returns the referenced entry and RafsiSource, replacing an internal static-index target without information loss. |
| Recovery optional payload | 1 | SkippedTokens.tokens exposes the optional recovery payload directly on the concrete Python variant. |
The matrix is generated by
tools/generate_api_matrix.py. Its
classification rules are deliberately source-controlled code: adding a broad
fallback would make review harder and is not permitted. Run:
uv run --project bindings/python --group dev \
python bindings/python/tools/generate_api_matrix.pyThe jbotci-python-api-parity workspace tool parses Rust source with syn.
Ordinary public declarations come from the scoped crate sources. Generated
strict and recovered syntax declarations come from the same binding schema
macro that drives the syntax generators, rather than a duplicated model list.
The tool also fingerprints both generator implementations so changes to
fixed, generic generated helpers require an explicit matrix review.
pytest runs the generator in check mode against the installed package, then
deletes one row from a temporary copy and verifies that the Rust checker rejects
the missing classification. Thus a new in-scope public declaration, a changed
signature, a changed generated schema, or a stale/nonexistent Python target
fails the check.
Private dictionary snapshot import and owned-index construction values are classified as build/serialization machinery. The installed package instead ships a validated, immutable embedded dictionary and typed lookup results. Borrowed ownership adapters, caller-owned accumulators, generic traversal traits, and raw pointer/path identity are likewise classified as Rust representation only when their information is available through a named typed Python operation. No semantic result, parser option, query operation, or consumer-visible error is omitted merely because it would be inconvenient to bind.