Skip to content

Commit 0b5e851

Browse files
rodrigobnogueirarodrigo.nogueira
andauthored
docs: Clarify conditional transition evaluation order (#546)
* docs: Clarify conditional transition evaluation order Addresses issue #541 by clarifying that conditional transitions are evaluated in declaration order (when state.to() is called), not in the order they appear when combined with the | operator. Changes: - Update description to explicitly mention "declaration order" - Add Important note box with clear examples showing: - How declaration order differs from composition order - Common pitfall where variable names don't match check order - Correct way to control evaluation order This documentation fix helps prevent user confusion about which transition will be checked first when using multiple conditional transitions for the same event. Closes #541 * docs: Update reStructuredText admonition syntax in guards documentation. * docs: Rename example variables for clarity in guard evaluation order. --------- Co-authored-by: rodrigo.nogueira <rodrigo.nogueira@prf.gov.br>
1 parent 9a089ed commit 0b5e851

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

docs/guards.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,37 @@ A conditional transition occurs only if specific conditions or criteria are met.
2222

2323
When a transition is conditional, it includes a condition (also known as a _guard_) that must be satisfied for the transition to take place. If the condition is not met, the transition does not occur, and the state machine remains in its current state or follows an alternative path.
2424

25-
This feature allows for multiple transitions on the same {ref}`event`, with each {ref}`transition` checked in the order they are declared. A condition acts like a predicate (a function that evaluates to true/false) and is checked when a {ref}`statemachine` handles an {ref}`event` with a transition from the current state bound to this event. The first transition that meets the conditions (if any) is executed. If none of the transitions meet the conditions, the state machine either raises an exception or does nothing (see the `allow_event_without_transition` parameter of {ref}`StateMachine`).
25+
This feature allows for multiple transitions on the same {ref}`event`, with each {ref}`transition` checked in **declaration order** — that is, the order in which the transitions themselves were created using `state.to()`. A condition acts like a predicate (a function that evaluates to true/false) and is checked when a {ref}`statemachine` handles an {ref}`event` with a transition from the current state bound to this event. The first transition that meets the conditions (if any) is executed. If none of the transitions meet the conditions, the state machine either raises an exception or does nothing (see the `allow_event_without_transition` parameter of {ref}`StateMachine`).
26+
27+
````{important}
28+
**Evaluation order is based on declaration order, not composition order.**
29+
30+
When using conditional transitions, the order of evaluation is determined by **when each transition was created** (the order of `state.to()` calls), **not** by the order they appear when combined with the `|` operator.
31+
32+
For example:
33+
34+
```python
35+
# These are evaluated in DECLARATION ORDER (when state.to() was called):
36+
created_first = state_a.to(state_x) # Created FIRST → Checked FIRST
37+
created_second = state_a.to(state_y) # Created SECOND → Checked SECOND
38+
created_third = state_a.to(state_z) # Created THIRD → Checked THIRD
39+
40+
# The | operator does NOT change evaluation order:
41+
my_event = created_third | created_second | created_first
42+
# Evaluation order is still: created_first → created_second → created_third
43+
```
44+
45+
To control the evaluation order, declare transitions in the desired order:
46+
47+
```python
48+
# Declare in the order you want them checked:
49+
first = state_a.to(state_b, cond="check1") # Checked FIRST
50+
second = state_a.to(state_c, cond="check2") # Checked SECOND
51+
third = state_a.to(state_d, cond="check3") # Checked THIRD
52+
53+
my_event = first | second | third # Order matches declaration
54+
```
55+
````
2656

2757
When {ref}`transitions` have guards, it is possible to define two or more transitions for the same {ref}`event` from the same {ref}`state`. When the {ref}`event` occurs, the guarded transitions are checked one by one, and the first transition whose guard is true will be executed, while the others will be ignored.
2858

0 commit comments

Comments
 (0)