fix(deps): update dependency python-statemachine to v3#329
Open
renovate[bot] wants to merge 1 commit intomainfrom
Open
fix(deps): update dependency python-statemachine to v3#329renovate[bot] wants to merge 1 commit intomainfrom
renovate[bot] wants to merge 1 commit intomainfrom
Conversation
9707909 to
464cc93
Compare
464cc93 to
6f98cc4
Compare
6f98cc4 to
32e7971
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
==2.6.0→==3.0.0Release Notes
fgmacedo/python-statemachine (python-statemachine)
v3.0.0: StateMachine 3.0.0Compare Source
Upgrading from 2.x? See upgrade guide for a step-by-step
migration guide.
What's new in 3.0.0
Statecharts are here! 🎉
Version 3.0 brings full statechart support to the library — compound states, parallel states,
history pseudo-states, and an SCXML-compliant processing model. It also introduces a new
StateChartbase class with modern defaults, a richer event dispatch system (delayed events,internal queues, cancellation), structured error handling, and several developer-experience
improvements.
The implementation follows the SCXML specification (W3C),
which defines a standard for statechart semantics. This ensures predictable behavior on
edge cases and compatibility with other SCXML-based tools. The automated test suite now
includes W3C-provided
.scxmltest cases to verify conformance.While this is a major version with backward-incompatible changes, the existing
StateMachineclass preserves 2.x defaults. See the
upgrade guide for a smooth migration path.
Compound states
Compound states have inner child states. Use
State.Compoundto define themwith Python class syntax — the class body becomes the state's children:
Entering a compound activates both the parent and its initial child. Exiting removes
the parent and all descendants. See compound states for full details.
Parallel states
Parallel states activate all child regions simultaneously. Use
State.Parallel:Events in one region don't affect others. See parallel states for full details.
History pseudo-states
The History pseudo-state records the configuration of a compound state when it
is exited. Re-entering via the history state restores the previously active child.
Supports both shallow (
HistoryState()) and deep (HistoryState(type="deep")) history:See history states for full details on shallow vs deep history.
Eventless (automatic) transitions
Transitions without an event trigger fire automatically when their guard condition
is met:
The entire eventless chain cascades in a single macrostep. See eventless
for full details.
DoneData on final states
Final states can provide data to
done.statehandlers via thedonedataparameter:The
done_state_naming convention automatically registers thedone.state.{suffix}form — no explicit
id=needed. See done state convention for details.Invoke
States can now spawn external work when entered and cancel it when exited, following the
SCXML
<invoke>semantics (similar to UML'sdo/activity). Handlers run in a daemonthread (sync engine) or a thread executor wrapped in an asyncio Task (async engine).
Invoke is a first-class callback group — convention naming (
on_invoke_<state>),decorators (
@state.invoke), inline callables, and the fullSignatureAdapterdependencyinjection all work out of the box.
Passing a list of callables (
invoke=[a, b]) creates independent invocations — eachsends its own
done.invokeevent, so the first to complete triggers the transition andcancels the rest. Use
invoke_group()when you need allcallables to complete before transitioning:
Invoke also supports child state machines (pass a
StateChartsubclass) and SCXML<invoke>with<finalize>, autoforward, and#_<invokeid>/#_parentsend targetsfor parent-child communication.
See invoke for full documentation.
Event dispatch
Event matching following SCXML spec
Event matching now follows the SCXML spec — a
transition's event descriptor is a prefix match against the dot-separated event name. For
example, a transition with
event="error"matcheserror,error.send,error.send.failed, etc.An event designator consisting solely of
*can be used as a wildcard matching any event.See events for full details.
Delayed events
Events can be scheduled for future processing using
delay(in milliseconds). The enginetracks execution time and processes the event only when the delay has elapsed.
Delayed events can be cancelled before they fire using
send_idandcancel_event().Cancellation is most useful in async codebases, where other coroutines can cancel the
event while the delay is pending. In the sync engine, the delay is blocking — the
processing loop sleeps until the delay elapses.
See delayed events for details.
raise_()— internal eventsA new
raise_()method sends events to the internal queue, equivalent tosend(..., internal=True). Internal events are processed immediately within the currentmacrostep, before any external events. See sending events.
New
send()parametersThe
send()method now accepts additional optional parameters:delay(float): Time in milliseconds before the event is processed.send_id(str): Identifier for the event, useful for cancelling delayed events.internal(bool): IfTrue, the event is placed in the internal queue and processed in thecurrent macrostep.
Existing calls to
send()are fully backward compatible.Error handling with
error.executionWhen
catch_errors_as_eventsis enabled (default inStateChart), runtime exceptions duringtransitions are caught and result in an internal
error.executionevent. This followsthe SCXML error handling specification.
A naming convention makes this easy to use: any event attribute starting with
error_automatically matches both the underscore and dot-notation forms:
Errors are caught at the block level: each microstep phase (exit, transition
on,enter) is an independent block. An error in one block does not prevent subsequent blocks
from executing — in particular,
aftercallbacks always run, makingafter_<event>()anatural finalize hook.
The error object is available as
errorin handler kwargs. See error executionfor full details.
New API
configurationandconfiguration_valuesDue to compound and parallel states, the state machine can now have multiple active states.
The new
configurationproperty returns anOrderedSet[State]of all currently activestates, and
configuration_valuesreturns their values. These replace the deprecatedcurrent_stateproperty. See querying configuration.is_terminatedpropertyA new read-only property that returns
Truewhen the state machine has reached a finalstate and the engine is no longer running. Works correctly for all topologies — flat,
compound, and parallel. See checking termination.
In(state)condition checksConditions can now check if a state is in the current configuration using the
In('<state-id>')syntax. This is particularly useful in parallel regions wherea transition depends on the state of another region. See condition expressions.
prepare_event()callbackThe
prepare_eventcallback lets you inject custom data into**kwargsfor allother callbacks in the same event processing cycle. See preparing events.
Constructor kwargs forwarded to initial state callbacks
Constructor keyword arguments are forwarded to initial state callbacks, so self-contained
machines can receive context at creation time:
Developer experience
StateChartbase classThe new
StateChartclass is the recommended base for all new state machines. It enablesSCXML-compliant defaults:
catch_errors_as_events,enable_self_transition_entries, andnon-atomic configuration updates. The existing
StateMachineclass is now a subclass withbackward-compatible defaults. See behaviour for a comparison table.
Typed models with
Generic[TModel]StateChartnow supports a generic type parameter for the model, enabling full typeinference and IDE autocompletion on
sm.model:With this declaration, type checkers infer
sm.modelasMyModel(notAny), soaccessing
sm.model.nameorsm.model.valuegets full autocompletion and type safety.When no type parameter is given,
StateChartdefaults toStateChart[Any]for backwardcompatibility. See domain models for details.
Improved type checking with pyright
The library now supports pyright in addition to mypy.
Type annotations have been improved throughout the codebase, and a catch-all
__getattr__that previously returned
Anyhas been removed — type checkers can now detect misspelledattribute names and unresolved references on
StateChartsubclasses.Self-transition entry/exit behavior
In
StateChart, self-transitions now execute entry and exit actions, following the SCXMLspec. The
enable_self_transition_entriesclass attribute controls this behavior.StateMachinepreserves the 2.x default (no entry/exit on self-transitions).See self transition.
Class-level listener declarations
Listeners can now be declared at the class level using the
listenersattribute, so they areautomatically attached to every instance. The list accepts callables (classes,
partial, lambdas)as factories that create a fresh listener per instance, or pre-built instances that are shared.
A
setup()protocol allows factory-created listeners to receive runtime dependencies(DB sessions, Redis clients, etc.) via
**kwargsforwarded from the SM constructor.Inheritance is supported: child listeners are appended after parent listeners, unless
listeners_inherit = Falseis set to replace them entirely.See observers for full documentation.
Weighted (probabilistic) transitions
A new contrib module
statemachine.contrib.weightedprovidesweighted_transitions(),enabling probabilistic transition selection based on relative weights. This works entirely
through the existing condition system — no engine changes required.
See weighted transitions for full documentation.
State timeouts
A new contrib module
statemachine.contrib.timeoutprovides atimeout()invoke helperfor per-state watchdog timers. When a state is entered, a background timer starts; if the
state is not exited before the timer expires, an event is sent automatically. The timer is
cancelled on state exit, with no manual cleanup needed.
See timeout for full documentation.
Create state machine from a dict definition
Dynamically create state machine classes using
create_machine_class_from_definition():Async concurrent event result routing
When multiple coroutines send events concurrently via
asyncio.gather, eachcaller now receives its own event's result (or exception). Previously, only the
first caller to acquire the processing lock would get a result — subsequent
callers received
Noneand exceptions could leak to the wrong caller.This is implemented by attaching an
asyncio.Futureto each externallyenqueued event in the async engine. See async for details.
Fixes #509.
Migration guide from pytransitions
A new Coming from pytransitions guide helps users of the
transitions library evaluate the differences
and migrate their state machines. It includes side-by-side code comparisons and a feature matrix.
Migration guide from the GoF State Pattern
A new Coming from the State Pattern guide helps developers
familiar with the classic Gang of Four State Pattern understand how to port their hand-rolled
state implementations to python-statemachine. It walks through a complete example, compares
the two approaches, and highlights what you gain from the declarative style.
Validation flags
The
strict_statesclass parameter has been replaced by two independent, always-onclass-level attributes:
validate_trap_states: non-final states must have at least one outgoing transition.validate_final_reachability: when final states exist, all non-final states must havea path to at least one final state.
validate_disconnected_states: all states must be reachable from the initial state.See validations for details.
Known limitations
The following SCXML features are not yet implemented and are deferred to a future release:
#_internal,#_parent, and#_<invokeid>send targets are supported)For a step-by-step migration guide with before/after examples, see
Upgrading from 2.x to 3.0.
Backward incompatible changes in 3.0
This section summarizes the breaking changes. For detailed before/after examples and
migration instructions, see the upgrade guide.
rtcparameter (deprecated since 2.3.2) has been removed.All events are now queued before being processed.
current_statedeprecated. Useconfiguration/configuration_valuesinstead.With compound and parallel states, multiple states can be active simultaneously.
StateChart, states are exited beforeoncallbacksand entered after, following the SCXML spec. Two new kwargs —
previous_configurationandnew_configuration— are available inoncallbacks. Useatomic_configuration_update=Trueor the
StateMachineclass to restore the 2.x behavior.StateChart, self-transitions now triggeron_enter_*/on_exit_*callbacks. Setenable_self_transition_entries = Falseto restore the old behavior.add_observer()removed. Useadd_listener()instead.TransitionNotAllowedchanges. Now storesconfiguration(a set) instead ofstate,and
eventcan beNone.allow_event_without_transitionmoved to class level. No longer an__init__parameter.States.from_enumdefault changed.use_enum_instancenow defaults toTrue.get_machine_cls().strict_statesremoved. Replaced byvalidate_trap_statesandvalidate_final_reachability(both default toTrue).__repr__output changed. Now showsconfiguration=[...]instead ofcurrent_state=....Configuration
📅 Schedule: Branch creation - Between 01:00 AM and 05:59 AM ( * 1-5 * * * ) in timezone Europe/Amsterdam, Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.