Skip to content

Releases: trendvidia/protowire-python

v1.0.0 — protowire v1.0 freeze line

13 May 13:39
9154de2

Choose a tag to compare

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

12 May 19:39
3a2d5f8

Choose a tag to compare

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. body is the verbatim bytes between { and }, suitable for handing to a follow-up pxf.unmarshal against the consumer's message type. type keeps the v0.72.0 single-prefix back-compat shape.
  • pxf.TableDirective(type, columns, rows)@table directives with cells modeled as None (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-cpp to the v0.75.0 tag (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 TableReader and bind_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.