StateMachine 2.2.0¶
May 6, 2024
What’s new in 2.2.0¶
In this release, we conducted a general cleanup and refactoring across various modules to enhance code readability and maintainability. We improved exception handling and reduced code redundancy.
As a result, we achieved a ~2.2x faster setup in our performance tests and significantly simplified the callback machinery.
Check of unreachable and non-final states¶
We included one more state machine definition validation for non-final states.
We already check if any states are unreachable from the initial state, if not, an InvalidDefinition exception is thrown.
>>> from statemachine import StateMachine, State
>>> class TrafficLightMachine(StateMachine):
... "A workflow machine"
... red = State('Red', initial=True, value=1)
... green = State('Green', value=2)
... orange = State('Orange', value=3)
... hazard = State('Hazard', value=4)
...
... cycle = red.to(green) | green.to(orange) | orange.to(red)
... blink = hazard.to.itself()
Traceback (most recent call last):
...
InvalidDefinition: There are unreachable states. The statemachine graph should have a single component. Disconnected states: ['hazard']
From this release, StateMachine will also check that all non-final states have an outgoing transition,
and warn you if any states would result in the statemachine becoming trapped in a non-final state with no further transitions possible.
Note
This will currently issue a warning, but can be turned into an exception by setting strict_states=True on the class.
>>> from statemachine import StateMachine, State
>>> class TrafficLightMachine(StateMachine, strict_states=True):
... "A workflow machine"
... red = State('Red', initial=True, value=1)
... green = State('Green', value=2)
... orange = State('Orange', value=3)
... hazard = State('Hazard', value=4)
...
... cycle = red.to(green) | green.to(orange) | orange.to(red)
... fault = red.to(hazard) | green.to(hazard) | orange.to(hazard)
Traceback (most recent call last):
...
InvalidDefinition: All non-final states should have at least one outgoing transition. These states have no outgoing transition: ['hazard']
Warning
strict_states=True will become the default behaviour in the next major release.
See State Transitions.
Bugfixes in 2.2.0¶
Fixes #424 allowing
deepcopyof state machines.Dispatch Mechanism: Resolved issues in the dispatch mechanism in
statemachine/dispatcher.pythat affected the reliability of event handling across different states. This fix ensures consistent behavior when events are dispatched in complex state machine configurations.