You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unified dispatch mecanism for callbacks (actions and guards)
Every single callback, being actions or guards, is now handled equally by the library.
Also, we've improved the internals in a way that you can implement your callbacks with any
number of arbritrary positional or keyword arguments (*args, **kwargs), and the dispatch will
match the available arguments with your method signature.
This means that if on your on_enter_<state>() or on_execute_<event>() method, you also
need to know the source (state), or the event (event), or access a keyword
argument passed with the trigger, you're covered. Just add this parameter to the method and It
will be passed by the dispatch mechanics.
Observers are a way do generically add behaviour to a StateMachine without
changing it's internal implementation.
The StateMachine itself is registered as an observer, so by using StateMachine.add_observer()
an external object can have the same level of functionalities provided to the built-in class.
Minor features in 1.0
Fixed mypy complaining about incorrect type for StateMachine class.
The initial state is now entered when the machine starts. The actions, if defined, on_enter_state and on_enter_<state> are now called.
Backwards incompatible changes in 1.0
Multiple targets from the same origin state
Prior to this release, as we didn't have validators-and-guards, there wasn't an elegant way
to declare multiples target states starting from the same pair (event, state). But the library
allowed a near-hackish way, by declaring a target state as the result of the on_<event> callback.
Now StateMachine will execute the actions associated with the on_enter_state and on_enter_<state> when initialized, if they exists.
Integrity is checked at class definition
Statemachine integrity checks are now performed at class declaration (import time) instead of on
instance creation. This allows early feedback of invalid definitions.
This was the previous behaviour, you only got an error when trying to instantiate a StateMachine:
classCampaignMachine(StateMachine):
"A workflow machine"draft=State('Draft', initial=True)
producing=State('Being produced')
closed=State('Closed', initial=True) # Should raise an Exception when instantiatedadd_job=draft.to(draft) |producing.to(producing)
produce=draft.to(producing)
deliver=producing.to(closed)
withpytest.raises(exceptions.InvalidDefinition):
CampaignMachine()
Not this is performed as the class definition is performed:
withpytest.raises(exceptions.InvalidDefinition):
classCampaignMachine(StateMachine):
"A workflow machine"draft=State("Draft", initial=True)
producing=State("Being produced")
closed=State(
"Closed", initial=True
) # Should raise an Exception right after the class is definedadd_job=draft.to(draft) |producing.to(producing)
produce=draft.to(producing)
deliver=producing.to(closed)
Other backwards incompatible changes in 1.0
Due to the check validations and setup performed at the machine initialization, it's now harder
to perform monkey-patching to add callbacks at runtime (not a bad thing after all).
TransitionNotAllowed changed internal attr from transition to event.
CombinedTransition does not exist anymore. State now holds a flat Transition list
called TransitionList that implements de OR operator. This turns a valid StateMachine
traversal much easier: [transition for state in machine.states for transition in state.transitions].
StateMachine.get_transition is removed. See event.
The previous excetions MultipleStatesFound and MultipleTransitionCallbacksFound are removed.
Since now you can have more than one callback defined to the same transition.
on_enter_state and on_exit_state now accepts any combination of parameters following the dynamic-dispatch rules. Previously it only accepted the state param.
Transition.__init__ param on_execute renamed to simply on, and now follows the dynamic-dispatch.
Transition.destinations removed in favor of Transition.target (following SCXML convention).
Now each transition only points to a unique target. Each source->target pair is holded by a
single Transition.
Deprecated features in 1.0
Statemachine class
StateMachine.run is deprecated in favor of StateMachine.send.
StateMachine.allowed_transitions is deprecated in favor of StateMachine.allowed_events.
Statemachine.is_<state> is deprecated in favor of StateMachine.<state>.is_active.
State class
State.identification is deprecated in favor of State.id.
This discussion was created from the release v1.0.1.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
StateMachine 1.0.1
January 11, 2023
Welcome to StateMachine 1.0!
This version is a huge refactoring adding a lot of new and exiting features. We hope that
you enjoy.
These release notes cover the , as well as
some backwards incompatible changes you'll
want to be aware of when upgrading from StateMachine 0.9.0 or earlier. We've
begun the deprecation process for some features.
Python compatibility in 1.0
StateMachine 1.0 supports Python 2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, and 3.11.
This is the last release to support Python 2.7, 3.5 and 3.6.
What's new in 1.0
Validators and Guards
Transitions now support
cond
andunless
parameters, to restrictthe execution.
Support for diagrams
You can generate diagrams from your statemachine.
Example:
Unified dispatch mecanism for callbacks (actions and guards)
Every single callback, being
actions
orguards
, is now handled equally by the library.Also, we've improved the internals in a way that you can implement your callbacks with any
number of arbritrary positional or keyword arguments (
*args, **kwargs
), and the dispatch willmatch the available arguments with your method signature.
This means that if on your
on_enter_<state>()
oron_execute_<event>()
method, you alsoneed to know the
source
(state
), or theevent
(event
), or access a keywordargument passed with the trigger, you're covered. Just add this parameter to the method and It
will be passed by the dispatch mechanics.
Example of what's available:
Add observers to a running StateMachine
Observers are a way do generically add behaviour to a StateMachine without
changing it's internal implementation.
The
StateMachine
itself is registered as an observer, so by usingStateMachine.add_observer()
an external object can have the same level of functionalities provided to the built-in class.
Minor features in 1.0
StateMachine
class.state
is now entered when the machine starts. Theactions
, if defined,on_enter_state
andon_enter_<state>
are now called.Backwards incompatible changes in 1.0
Multiple targets from the same origin state
Prior to this release, as we didn't have
validators-and-guards
, there wasn't an elegant wayto declare multiples target states starting from the same pair (event, state). But the library
allowed a near-hackish way, by declaring a target state as the result of the
on_<event>
callback.So, the previous code (not valid anymore):
Should be rewriten to use
guards
, like this:StateMachine now enters the initial state
This issue was reported at #265.
Now StateMachine will execute the actions associated with the
on_enter_state
andon_enter_<state>
when initialized, if they exists.Integrity is checked at class definition
Statemachine integrity checks are now performed at class declaration (import time) instead of on
instance creation. This allows early feedback of invalid definitions.
This was the previous behaviour, you only got an error when trying to instantiate a StateMachine:
Not this is performed as the class definition is performed:
Other backwards incompatible changes in 1.0
to perform monkey-patching to add callbacks at runtime (not a bad thing after all).
TransitionNotAllowed
changed internal attr fromtransition
toevent
.CombinedTransition
does not exist anymore.State
now holds a flatTransition
listcalled
TransitionList
that implements deOR
operator. This turns a valid StateMachinetraversal much easier:
[transition for state in machine.states for transition in state.transitions]
.StateMachine.get_transition
is removed. Seeevent
.MultipleStatesFound
andMultipleTransitionCallbacksFound
are removed.Since now you can have more than one callback defined to the same transition.
on_enter_state
andon_exit_state
now accepts any combination of parameters following thedynamic-dispatch
rules. Previously it only accepted thestate
param.Transition.__init__
paramon_execute
renamed to simplyon
, and now follows thedynamic-dispatch
.Transition.destinations
removed in favor ofTransition.target
(following SCXML convention).Now each transition only points to a unique target. Each
source->target
pair is holded by asingle
Transition
.Deprecated features in 1.0
Statemachine class
StateMachine.run
is deprecated in favor ofStateMachine.send
.StateMachine.allowed_transitions
is deprecated in favor ofStateMachine.allowed_events
.Statemachine.is_<state>
is deprecated in favor ofStateMachine.<state>.is_active
.State class
State.identification
is deprecated in favor ofState.id
.This discussion was created from the release v1.0.1.
Beta Was this translation helpful? Give feedback.
All reactions