Commit 68ba609
committed
Merge tag 'v2.5.0' into develop
*November 5, 2024*
This release introduces powerful new features for the `StateMachine`
library: {ref}`Condition expressions` and explicit definition of
{ref}`Events`. These updates make it easier to define complex transition
conditions and enhance performance, especially in workflows with nested
or recursive event structures.
StateMachine 2.4.0 supports Python 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, and
3.13.
This release introduces support for conditionals with Boolean algebra.
You can now use expressions like `or`, `and`, and `not` directly within
transition conditions, simplifying the definition of complex state
transitions. This allows for more flexible and readable condition setups
in your state machine configurations.
Example (with a spoiler of the next highlight):
```py
>>> from statemachine import StateMachine, State, Event
>>> class AnyConditionSM(StateMachine):
... start = State(initial=True)
... end = State(final=True)
...
... submit = Event(
... start.to(end, cond="used_money or used_credit"),
... name="finish order",
... )
...
... used_money: bool = False
... used_credit: bool = False
>>> sm = AnyConditionSM()
>>> sm.submit()
Traceback (most recent call last):
TransitionNotAllowed: Can't finish order when in Start.
>>> sm.used_credit = True
>>> sm.submit()
>>> sm.current_state.id
'end'
```
```{seealso}
See {ref}`Condition expressions` for more details or take a look at the
{ref}`sphx_glr_auto_examples_lor_machine.py` example.
```
Now you can explicit declare {ref}`Events` using the {ref}`event` class.
This allows custom naming, translations, and also helps your IDE to know
that events are callable.
```py
>>> from statemachine import StateMachine, State, Event
>>> class StartMachine(StateMachine):
... created = State(initial=True)
... started = State(final=True)
...
... start = Event(created.to(started), name="Launch the machine")
...
>>> [e.id for e in StartMachine.events]
['start']
>>> [e.name for e in StartMachine.events]
['Launch the machine']
>>> StartMachine.start.name
'Launch the machine'
```
```{seealso}
See {ref}`Events` for more details.
```
We removed a note from the docs saying to avoid recursion loops. Since
the {ref}`StateMachine 2.0.0` release we've turned the RTC model enabled
by default, allowing nested events to occour as all events are put on an
internal queue before being executed.
```{seealso}
See {ref}`sphx_glr_auto_examples_recursive_event_machine.py` for an
example of an infinite loop state machine declaration using `after`
action callback to call the same event over and over again.
```
- Fixes
[#484](#484)
issue where nested events inside loops could leak memory by incorrectly
referencing previous `event_data` when queuing the next event. This
fix improves performance and stability in event-heavy workflows.File tree
7 files changed
+75
-46
lines changed- docs
- statemachine
- tests
7 files changed
+75
-46
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
| 80 | + | |
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | 103 | | |
117 | 104 | | |
118 | 105 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
| 85 | + | |
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
| |||
112 | 113 | | |
113 | 114 | | |
114 | 115 | | |
115 | | - | |
| 116 | + | |
116 | 117 | | |
117 | 118 | | |
118 | 119 | | |
| |||
126 | 127 | | |
127 | 128 | | |
128 | 129 | | |
129 | | - | |
| 130 | + | |
130 | 131 | | |
131 | 132 | | |
132 | 133 | | |
| |||
178 | 179 | | |
179 | 180 | | |
180 | 181 | | |
181 | | - | |
| 182 | + | |
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
218 | 218 | | |
219 | 219 | | |
220 | 220 | | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments