|
| 1 | +# StateMachine 2.2.0 |
| 2 | + |
| 3 | +*Not released yet* |
| 4 | + |
| 5 | +## What's new in 2.2.0 |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +As a result, we achieved a **~1.8x** faster setup in our performance tests and significantly simplified the callback machinery. |
| 10 | + |
| 11 | + |
| 12 | +### Check of unreachable and non-final states |
| 13 | + |
| 14 | +We included one more state machine definition validation for non-final states. |
| 15 | + |
| 16 | +We already check if any states are unreachable from the initial state, if not, an `InvalidDefinition` exception is thrown. |
| 17 | + |
| 18 | +```py |
| 19 | +>>> from statemachine import StateMachine, State |
| 20 | + |
| 21 | +>>> class TrafficLightMachine(StateMachine): |
| 22 | +... "A workflow machine" |
| 23 | +... red = State('Red', initial=True, value=1) |
| 24 | +... green = State('Green', value=2) |
| 25 | +... orange = State('Orange', value=3) |
| 26 | +... hazard = State('Hazard', value=4) |
| 27 | +... |
| 28 | +... cycle = red.to(green) | green.to(orange) | orange.to(red) |
| 29 | +... blink = hazard.to.itself() |
| 30 | +Traceback (most recent call last): |
| 31 | +... |
| 32 | +InvalidDefinition: There are unreachable states. The statemachine graph should have a single component. Disconnected states: ['hazard'] |
| 33 | +``` |
| 34 | + |
| 35 | +From this release, `StateMachine` will also check that all non-final states have an outgoing transition, |
| 36 | +and warn you if any states would result in the statemachine becoming trapped in a non-final state with no further transitions possible. |
| 37 | + |
| 38 | +```{note} |
| 39 | +This will currently issue a warning, but can be turned into an exception by setting `strict_states=True` on the class. |
| 40 | +``` |
| 41 | + |
| 42 | +```py |
| 43 | +>>> from statemachine import StateMachine, State |
| 44 | + |
| 45 | +>>> class TrafficLightMachine(StateMachine, strict_states=True): |
| 46 | +... "A workflow machine" |
| 47 | +... red = State('Red', initial=True, value=1) |
| 48 | +... green = State('Green', value=2) |
| 49 | +... orange = State('Orange', value=3) |
| 50 | +... hazard = State('Hazard', value=4) |
| 51 | +... |
| 52 | +... cycle = red.to(green) | green.to(orange) | orange.to(red) |
| 53 | +... fault = red.to(hazard) | green.to(hazard) | orange.to(hazard) |
| 54 | +Traceback (most recent call last): |
| 55 | +... |
| 56 | +InvalidDefinition: All non-final states should have at least one outgoing transition. These states have no outgoing transition: ['hazard'] |
| 57 | +``` |
| 58 | + |
| 59 | +```{warning} |
| 60 | +`strict_states=True` will become the default behaviour in the next major release. |
| 61 | +``` |
| 62 | + |
| 63 | +See {ref}`State Transitions`. |
| 64 | + |
| 65 | + |
| 66 | +## Bugfixes in 2.2.0 |
| 67 | + |
| 68 | +- Fixes [#424](https://github.com/fgmacedo/python-statemachine/issues/424) allowing `deepcopy` of state machines. |
| 69 | +- **Dispatch Mechanism**: Resolved issues in the dispatch mechanism in `statemachine/dispatcher.py` that affected the reliability |
| 70 | +of event handling across different states. This fix ensures consistent behavior when events are dispatched in complex state |
| 71 | +machine configurations. |
0 commit comments