@@ -5,7 +5,7 @@ Validations and Guards are checked before an transition is started. They are mea
55transition to occur.
66
77The main difference, is that {ref}` validators ` raise exceptions to stop the flow, and {ref}` guards `
8- act like predicates that should resolve for a `` boolean `` value.
8+ act like predicates that shall resolve to a `` boolean `` value.
99
1010``` {seealso}
1111Please see {ref}`dynamic-dispatch` to know more about how this lib supports multiple signatures
@@ -18,13 +18,12 @@ Also known as **Conditional transition**.
1818
1919A guard is a condition that may be checked when a statemachine wants to handle
2020an {ref}` event ` . A guard is declared on the {ref}` transition ` , and when that transition
21- would trigger, then the guard (if any) is checked. If the guard is ` True `
21+ would trigger, then the guard (if any) is checked. If the guard is ` True `
2222then the transition does happen. If the guard is ` False ` , the transition
2323is ignored.
2424
2525When transitions have guards, then it's possible to define two or more
26- transitions for the same event from the same {ref}` state ` , i.e. that a state has
27- two (or more) transitions for the same event. When the event happens, then
26+ transitions for the same event from the same {ref}` state ` . When the event happens, then
2827the guarded transitions are checked, one by one, and the first transition
2928whose guard is true will be used, the others will be ignored.
3029
@@ -37,9 +36,13 @@ There are two variations of Guard clauses available:
3736cond
3837: A list of conditions, acting like predicates. A transition is only allowed to occur if
3938all conditions evaluate to `` True `` .
39+ * Single condition: ` cond="condition" `
40+ * Multiple conditions: ` cond=["condition1", "condition2"] `
4041
4142unless
42- : Same as ` cond ` , but the transition is allowed if all conditions evaluate to ` False ` .
43+ : Same as ` cond ` , but the transition is only allowed if all conditions evaluate to `` False `` .
44+ * Single condition: ` unless="condition" `
45+ * Multiple conditions: ` unless=["condition1", "condition2"] `
4346
4447``` {hint}
4548In Python, a boolean value is either `True` or `False`. However, there are also specific values that
@@ -48,9 +51,9 @@ are considered "**falsy**" and will evaluate as `False` when used in a boolean c
4851These include:
4952
50531. The special value `None`.
51- 1 . Numeric values of `0` or `0.0`.
52- 1 . **Empty** strings, lists, tuples, sets, and dictionaries.
53- 1 . Instances of certain classes that define a `__bool__()` or `__len__()` method that returns
54+ 2 . Numeric values of `0` or `0.0`.
55+ 3 . **Empty** strings, lists, tuples, sets, and dictionaries.
56+ 4 . Instances of certain classes that define a `__bool__()` or `__len__()` method that returns
5457 `False` or `0`, respectively.
5558
5659On the other hand, any value that is not considered "**falsy**" is considered "**truthy**" and will evaluate to `True` when used in a boolean context.
@@ -64,8 +67,14 @@ So, a condition `s1.to(s2, cond=lambda: [])` will evaluate as `False`, as an emp
6467
6568Are like {ref}` guards ` , but instead of evaluating to boolean, they are expected to raise an
6669exception to stop the flow. It may be useful for imperative style programming when you don't
67- wanna to continue evaluating other possible transitions and exit immediately.
70+ want to continue evaluating other possible transitions and exit immediately.
6871
72+ * Single validator: ` validators="validator" `
73+ * Multiple validator: ` validators=["validator1", "validator2"] `
74+
75+ Both conditions and validators can also be combined for a single event.
76+
77+ <event> = <state1>.to(<state2>, cond="condition1", unless="condition2", validators="validator")
6978
7079Consider this example:
7180
@@ -76,16 +85,23 @@ class InvoiceStateMachine(StateMachine):
7685 paid = State(" paid" )
7786 failed = State(" failed" )
7887
88+ paused = False
89+ offer_valid = True
90+
7991 pay = (
80- unpaid.to(paid, cond = " payment_success" )
81- | failed .to(paid)
82- | unpaid .to(failed )
92+ unpaid.to(paid, cond = " payment_success" ) |
93+ unpaid .to(failed, validators = " validator " , unless = " paused " ) |
94+ failed .to(paid, cond = [ " payment_success " , " offer_valid " ] )
8395 )
84-
8596 def payment_success (self , event_data ):
86- return < validation logic goes here>
97+ return < condition logic goes here>
8798
99+ def validator (self ):
100+ return < validator logic goes here>
101+ ```
102+ ``` {seealso}
103+ See the example {ref}`sphx_glr_auto_examples_all_actions_machine.py` for a complete example of
104+ validators and guards.
88105```
89-
90106
91107Reference: [ Statecharts] ( https://statecharts.dev/ ) .
0 commit comments