Releases: trendvidia/protowire-python
v1.0.0 — protowire v1.0 freeze line
Lockstep major-version cut alongside the protowire v1.0 spec freeze and `protowire-cpp` v1.0.0, which this port wraps via the nanobind FFI. Breaking — there is no alias period; v1.0 is itself the major bump.
Python API rename
| Before | After |
|---|---|
| `pxf.TableDirective` | `pxf.DatasetDirective` |
| `pxf.TableReader` | `pxf.DatasetReader` |
| `pxf.Result.tables` | `pxf.Result.datasets` |
| — | `pxf.ProtoDirective` + `pxf.ProtoShape` (new) |
| — | `pxf.Result.protos: tuple[ProtoDirective, ...]` (new) |
FFI shape change
`_protowire.pxf_unmarshal_full` now returns a 6-tuple `(raw, set_paths, null_paths, directives, datasets, protos)`. The cpp side surfaces `ProtoDirective` as a `(shape, type_name, body)` tuple; Python wraps it into the new frozen dataclass with `shape` typed as `Literal["anonymous", "named", "source", "descriptor"]`.
Install
```
pip install protowire-python==1.0.0
```
Built with cibuildwheel — Linux x86_64/aarch64, Windows AMD64, macOS arm64, plus the sdist.
Lockstep v1.0 ports
See the protowire v1.0.0 release for the full lockstep table.
v0.75.0 — PXF v0.72-series feature catch-up
First release after the v0.70.0 baseline. Wraps the protowire-cpp v0.75.0 PXF v0.72-series feature set through the nanobind FFI; the Python port jumps directly from v0.70.0 to v0.75.0 to match the active wire revision across the protowire-* stack.
Highlights
pxf.Result.directives / pxf.Result.tables (#6)
unmarshal_full now surfaces the document-root directive shape the decoder saw, as immutable dataclasses:
pxf.Directive(name, prefixes, type, body, has_body, line, column)— generic@<name> *(prefix) [{ ... }]blocks.bodyis the verbatim bytes between{and}, suitable for handing to a follow-uppxf.unmarshalagainst the consumer's message type.typekeeps the v0.72.0 single-prefix back-compat shape.pxf.TableDirective(type, columns, rows)—@tabledirectives with cells modeled asNone(absent) or(kind, value)2-tuples for the three-state grammar (absent / present-but-null / present-with-value, draft §3.4.4).kind∈ {null,string,int,float,bool,bytes,ident,timestamp,duration}.
pxf.validate_descriptor + pxf.Violation (#6)
Schema reserved-name check (draft §3.13). Rejects schemas declaring a message field, oneof, or enum value whose name case-sensitively matches a PXF value keyword (null / true / false). Unmarshal and unmarshal_full invoke the validator automatically; pass skip_validate=True to bypass the per-call recheck after a one-time registry-load validation.
pxf.TableReader + pxf.bind_row (#7)
Streaming @table consumption, alternative to materializing every row up front:
reader = pxf.TableReader.from_bytes(open("trades.pxf", "rb").read())
for row in reader:
msg = TradeMsg()
pxf.bind_row(msg, reader.columns, row)
handle(msg)tail() returns the unconsumed buffer for chaining a second reader on multi-@table documents. bind_row is also exported as a free function for callers iterating Result.tables[i].rows from the materializing path. Strategy is format-and-reparse, matching the cpp port — cells render as a synthetic PXF body and run through unmarshal, reusing every branch of the existing decoder (WKT timestamps / durations, wrapper-nullability, enum-by-name, pxf.required / pxf.default, oneof).
CI
- pinned
protowire-cppto thev0.75.0tag (previously a pre-v0.72 commit) - wheel matrix unchanged: CPython 3.10–3.13 × {linux x86_64, linux aarch64, macos arm64, windows x86_64}
Test coverage
84 tests pass (+38 net new since v0.70.0):
- 16 tests for
Result.directives/Result.tables/validate_descriptor/skip_validate - 22 tests for
TableReaderandbind_row - Plus the pre-existing 46 PXF / SBE / envelope tests
Notes on supersedence
This release replaces the v0.70.x line; v0.72.x / v0.74.x are version numbers used by the Go and Java ports but were never cut on Python. Consumers upgrading from v0.70.0 pick up the three features above; no breaking changes to the existing public API surface.