This package exposes the language-native representation of the stable Vinary Tree resource ABI. It is the neutral handoff layer used by dictionary, automaton, WFST, lattice, and semiring packages, and it can export custom Python providers without owning algorithm-specific policy.
| Property | Contract |
|---|---|
| Binding | Python |
| Languages/runtime | Python 3.10+ |
| Support tier | Tier 1 |
| Distribution | PyPI package vinary-tree-interop |
| Native boundary | This adapter represents the two-word VtResource capability and its versioned interfaces; it does not implement a dictionary or automaton. |
| Canonical facade source | vinary-tree-interop/bindings/python |
The support tier controls release gating, not semantic quality: every tier has the same snapshot, ownership, status, and ABI compatibility laws. Consult the binding architecture before implementing a custom provider and the family hub when combining independently packaged projects.
src/vinary_tree_interop/__init__.py
is the complete public facade. The wheel carries the standard py.typed
marker so downstream type checkers consume its inline annotations. The
package includes hosted-provider
conformance tests and a maintained public example:
python -m pip install ./bindings/python
python bindings/python/examples/host_providers.pyProject-specific algorithm constructors live in their owning packages. This
neutral module models and validates the shared handoff, exports Python
dictionary, WFST, lattice, and semiring providers, and supplies ScalarWfst
as the reusable consuming view for any compatible WFST resource. See the
Python resource guide
for complete APIs, semantics, and runnable integration patterns.
The idiomatic facade groups the stable surface into these concepts:
| Concept | Semantics |
|---|---|
VtResource |
Two pointer-sized words: an opaque context and a base vtable. A borrowed value transfers no ownership. |
| Base vtable | struct_size, ABI version, retain, release, and query_interface; it is the only mandatory interface. |
| Dictionary interface | Snapshot capture, node paging, finality, optional values, unit/value domains, and capability flags. |
| Dictionary entries interface | Optional finite lexicographic stream over one captured revision, with bounded arena batches, exact generation leases, cancellation, and a reducer path. |
| Scalar-WFST interface | ScalarWfstResource exports Python graphs; ScalarWfst retains and traverses any compatible resource through snapshot capture, start state, final weights, bounded arc pages, explicit domains, and capability flags. |
| Lattice interface | Host-defined immutable join/meet values with exact domain IDs, borrowed operands, stable bytes, diagnostics, and bounded bulk operations. |
| Semiring interfaces | Host-defined algebra with provider-scoped value leases, optional division/star/numeric capabilities, declared laws, and bounded folds. |
Unit and value domains are explicit enum fields on the discovered interface; adapters must never infer them from host container types. Empty terms, embedded zero bytes, non-ASCII text, and the full unsigned 64-bit identifier range are represented explicitly; no facade may use a sentinel value that removes a valid input from the domain.
For the exhaustive native function contract—including exact preconditions, returnable statuses, complexity, and thread-safety—use the family resource ABI reference. The facade source linked above is the authoritative idiomatic symbol inventory; its exhaustive coverage is pinned by the canonical C header and the Rust layout and discriminant tests.
Use with for every hosted resource. Finalizers are leak containment, not a deterministic resource policy. Close every entries cursor, and release its current generation before advancing or closing it.
A borrowed resource becomes owned only after a successful retain. Interface
discovery does not transfer ownership, and a failed validation must release any
retain already acquired. A captured snapshot owns an independent revision and
may outlive the producing project handle. Release exactly once for every
successful retain; never release an unretained borrowed pair. An entries cursor is move-only and owns its
captured revision until close. Exactly one generation may be live: release
that exact generation before advancing, reducing, or closing; reducer batch
views expire when their callback returns.
ScalarWfst(resource) obtains an independent retain, so the producing facade
may close as soon as construction succeeds. snapshot() returns another
independently owned view pinned to the captured revision. Use both as context
managers. Project packages alone should call ScalarWfst.adopt(raw_resource):
that constructor transfers one already-owned retain and deliberately avoids a
second retain/release pair.
Borrowed results are intentionally lexical. Copy data that must outlive the callback; retaining a raw address, slice, memory segment, or foreign pointer is an API violation even when the next operation happens to reuse the same arena.
Interop validation failures preserve VtStatus; project facades map that status into their own public error currency.
Null resource words, truncated vtables, incompatible interface identities or versions, invalid domains, forged node/state identifiers, malformed page counts or entry arenas, stale or mismatched batch generations, live-batch conflicts, provider faults, and contained panics are distinct failures. Never parse diagnostic prose to branch on an error: inspect the typed status/exception first and treat the message as human context. Diagnostics must be copied before another native call on the same thread.
A retained resource may cross threads only when its advertised interface flags permit it. Retain and release remain balanced under every failure path. One entries cursor and its live batch are single-consumer; reducer callbacks must not reenter that cursor.
Snapshot capture is a linearization point, not a dictionary-wide query lock. First-party immutable snapshots can be walked concurrently. A foreign provider that does not advertise parallel callbacks is serialized at its callback gate; the host language must not add a weaker promise.
- Pass the two-word resource by value; do not serialize or copy the graph.
- Capture one immutable snapshot and page nodes/arcs through bounded buffers.
- Use
ScalarWfst.state_info()when arcs are unnecessary and choose a boundedbatch_sizeforarcs()orstate(); the consumer rejects non-progressing or internally inconsistent pages. - Negotiate entries-v1 when exact lexicographic enumeration is needed; honor all entry/unit/value limits on every batch.
- Supply hosted lattice and semiring bulk methods to amortize Python/native callback cost.
- Keep semiring values immutable; the facade uses provider-scoped leases rather than copying Python objects into native memory.
- Cache a validated optional interface only while the owning resource remains retained.
- Respect capability flags before enabling parallel callback entry.
- Prefer a compact immutable graph interface when advertised; retain the paged callback fallback for compatibility.
Treat a foreign resource provider and all user-controlled queries as untrusted inputs. Validate lengths before allocation, preserve paging bounds, reject unknown enum values, contain callbacks/panics at the boundary, and never trust capability flags until interface negotiation succeeds. The normative duties are in the binding trust model.
The project ABI revision, family ABI version, interface identity/version, package version, and umbrella-runtime version are independent counters. Follow the ABI evolution policy; never infer compatibility from a package version alone.
When loading fails, check—in order—the documented runtime/toolchain version, CPU/OS artifact, native-access permission, loader search path, dependent interop package pin, and process-wide JavaScript runtime identity. When a query fails after construction, report the typed status and copied diagnostic before reducing the case to the smallest dictionary/query pair.
- Update the interop generator model before changing a layout, identifier, flag, or enum.
- Regenerate headers/constants and the API coverage matrix.
- Extend the canonical executable example and negative-path tests.
- Run the language package, snapshot, leak, property, and cross-project suites.
- Verify package staging contains this guide and uses coherent sibling pins.
- Render diagrams headlessly and run the documentation/link/math gates.