Skip to content

Deliver typed session events to the Python callback - #5

Merged
knipknap merged 1 commit into
mainfrom
feat/typed-session-events
Oct 17, 2026
Merged

knipknap merged 1 commit into
mainfrom
feat/typed-session-events

Conversation

@knipknap

Copy link
Copy Markdown
Contributor

Summary

The session reported events as (name: str, payload) tuples, so every embedder had to dispatch on raw strings and unpack payloads unchecked. This PR replaces that contract with a single typed object:

  • SessionEvent is a PyO3 complex enum (StateChanged, ConnectionStatusChanged, CommandStatusChanged, JobFinished, ProbeStatusChanged, WcsUpdated, ConfigChanged, RawRx, RawTx); event_callback(event) receives it on the loop thread. Python matches on the variant classes and reads typed attributes (event.status, event.line, event.state, ...).
  • The generated stubs expose @typing.final variant classes with __match_args__, so pyright can verify the callback contract and match destructuring works.
  • Fixes the mirror image of the Emit raw RX/TX line events from the GRBL session #4 routing bug: a drainer scheduled for a progress report delivered any session events sharing its batch to the progress callback. EventDrainer now carries both callbacks and routes by event kind.

Breaking change

event_callback(event) replaces event_callback(name, payload). Rayforge is the only known Python embedder and pins ==; this lands as 0.5.0. The Rust-embedder SessionEvents trait is unchanged.

Test plan

  • All session, streaming, stress, raw-line and CLI tests migrated to typed events: 159 passed.
  • make lint (cargo fmt, clippy -D warnings, ruff, pyright) green; also fixes a pre-existing clone_on_copy clippy error in types.rs.
  • README usage example updated to the typed callback.

Rayforge-side migration (PR #576) follows once 0.5.0 is released.

The session reported events as (name: str, payload) tuples, so every
embedder dispatches on raw strings and unpacks payloads unchecked.

The session now delivers a single typed SessionEvent (a PyO3 complex
enum: StateChanged, ConnectionStatusChanged, CommandStatusChanged,
JobFinished, ProbeStatusChanged, WcsUpdated, ConfigChanged, RawRx,
RawTx); Python matches on the variant classes and reads typed
attributes. The stubs expose final variant classes with
__match_args__, so pyright can check the callback contract.

This also fixes event routing for batches drained by a progress
report: a drainer scheduled for a progress report delivered any
session events in its batch to the progress callback. EventDrainer
now carries both callbacks and routes by event kind.

Breaking change: event_callback(event) replaces
event_callback(name, payload) (bump to 0.5.0 when releasing).
knipknap added a commit to barebaric/rayforge that referenced this pull request Oct 17, 2026
raydriver 0.5.0 delivers a typed SessionEvent to the driver's
event callback instead of (name, payload) string tuples, so
_on_session_event now matches on the event variants; each former
branch became a small named handler. The callback is annotated as
a union of the stub's variant classes with assert_never in the
fall-through, so an event added on the Rust side fails the type
check here until it is handled.

Also regenerates pixi.lock (raydriver 0.3.0 -> 0.4.0) and syncs
requirements.txt and debian/requirements-bundle.txt with the
pixi.toml pin; both were left at 0.3.0.

Requires the raydriver typed-events change (barebaric/raydriver#5);
the pin and lockfile move to 0.5.0 once it is released.
@knipknap
knipknap merged commit 40c9ed6 into main Oct 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant