A lightweight, object-oriented finite state machine implementation in Python with many extensions
MIT License
Bot releases are visible (Hide)
Published by aleneum 2 months ago
Release 0.9.2 is a minor release and contains a new mermaid diagram backend, a new model decoration mode for easier development with types and some more features and bugfixes.
HierarchicalMachine
is passed to add_state
(thanks @e0lithic)may_<trigger>
check all parallel states in processing order (thanks @spearsear)HSM.is_state
works with parallel states nowmodel_override
to Machine constructor to determine the mode of operation. With model_override=Fale
(default), transitions
will not override already defined methods on a model just as it did before. For workflows relying on typing, model_override=True
will override methods already defined on the model and only those (!). This allows to control which convenience methods shall be assigned to the model and keeps the statically 'assumed' model in sync with its runtime counterpart. Since defining each and every method manually is rather tiresome, transitions.experimental.utils.generate_base_model
features a way to convert a machine configuration into a BaseClass
with all convenience functions and callbacks.transitions.experimental.utils.{add_transitions, event, with_model_definitions, transition}
to define trigger methods in a class model for more convenient type checking. add_transitions
can be used as a function decorator and is stackable. event
returns a placeholder object for attribute assigment. add_transitions
and event
have the same signature and support transition definition like machine constructors. The function transition
can used for better typing and returns a dictionary that can be passed to the utility functions but also to a machine constructor. add_transitions
and event
require a machine decorated with with_model_definitions
. Decorating a machine with_model_definitions
implies model_override=True
.may_trigger
to models to check whether transitions can be conducted by trigger name.use_pygraphviz
is deprecated in favour for graph_engine
which may be pygraphviz
(default), graphviz
or mermaid
.Release 0.9.1 is a minor release and contains several bugfixes and some (typing) improvements. This release also introduces on_final
callbacks on machines (as well as NestedState
) and final
flags for states.
EventData
context in 'may' check (thanks @msclock)Exception
is not broad enough and does not catch asyncio.CancelledError
or KeyboardInterrupt
; use BaseException
instead (thanks @e0lithic and @ofacklam)on_final
to Machine
and NestedState
constructor and final
to State
. Callbacks passed to on_final
will be executed when a State with final=True
is entered or all children of a parallel state are final.Machine.on_exception
in may_ as well (thanks @match1)GraphMachine
and HiearachicalMachine
(thanks @drpjm)GraphMachine
--strict
mypy flag for transitions
type checks (not tests
though)Published by aleneum about 2 years ago
Release 0.9.0 is a major release and contains improvements to ease development, adds some new features and removes the legacy hierarchical machine:
HierarchicalMachine
from the packageGraphMachine
(thanks @betaboon)HierachicalMachine
(thanks @jankrejci)graphviz
when pygraphviz
was not installed (thanks @FridjofAmundsen)on_timeout
callback resolution when timeout had been initialized with timeout=0
(thanks @Rysbai)GraphSupport
was not correctly aligned when show_attributes=True
(thanks @spagh-eddie)may
transition check to transitions (thanks @artofhuman)MachineError
in on_exception
callbacks (thanks @kpihus)mypy
to test workflowRetry
state to supported state stereotypes (thanks @rgov)Machine._identify_callback
has been converted to instance method from class methodLockedMachine._get_qualified_state_name
has been converted to instance method from static method_super
workaround related to dill (see https://github.com/pytransitions/transitions/issues/236)Published by aleneum over 2 years ago
Release 0.8.11 is the last 0.8 release and contains fixes for Python 3.10 compatibility issues:
Published by aleneum about 3 years ago
Release 0.8.10 is a minor release and contains two bug fixes for the HSM extension and changes how the 'self' literal string is handled.
Machine
) has been replaced by the class variable Machine.self_literal = 'self'
. Machine
now performs an identity check (instead of a value check) with mod is self.self_literal
to determine whether it should act as a model. While 'self' should still work when passed to the model
parameter, we encourage using Machine.self_literal
from now on. This was done to enable easier override of Machine.__eq__
in subclasses (thanks @VKSolovev).HierarchicalMachine.prefix_path
to resolve global state names since the HSM stack is not reliable when queued=True
(thanks @jankrejci).HSM
source states were exited even though they are parents of the destination state (thanks @wes-public-apps).Published by aleneum about 3 years ago
Release 0.8.9 is a minor release and contains a bugfix for HSM, a feature for GraphSupport
and changes internal cache handling:
NestedEvent
now wraps the machine's scope into partials passed to HierarchicalMachine._process
. This prevents queued transitions from losing their scope.(A)Graph.draw
function (object returned by GraphMachine.get_graph()
) can be passed a file/stream object as first parameter or None
. The later will result in draw
returning a binary string. (thanks @Blindfreddy).LockedMachine
, AsyncMachine
and GraphMachine
. This might influence pickling (thanks @thedrow).Published by aleneum over 3 years ago
Release 0.8.8 is a minor release and contains a bugfix and several new or improved features:
AsyncMachine
does not remove models when remove_models
is called (thanks @Plazas87)try/except
for finalize callbacks in Machine
and HierachicalMachine
. Thus, errors occurring in finalize callbacks will be suppressed and only the original error will be raised.MarkupMachine.format_references
to tweak reference formatting (thanks @StephenCarboni)Machine.on_exception
to handle raised exceptions in callbacks (thanks @thedrow)Machine.get_triggers
now supports State
and Enum
as arguments (thanks @luup2k)NestedState
and HierachicalMachine.add_states
now accept (lists of) states and enums as initial
parameterPublished by aleneum over 3 years ago
Release 0.8.7 is a minor release and contains bugfixes and new features:
HierarchicalMachine
can also use states
as a keyword to define substates. If children
and states
are present, only children
will be considered.HierarchicalMachine
with custom separator now adds is_state
partials for nested states (e.g. is_C.s3.a()
) to models (thanks @alterscape)model_attribute
consistently in AsyncMachine
(thanks @thedrow)pygraphviz.Agraph
in diagrams_pygraphviz
are now copied by transitions
since AGraph.copy
as of version 1.6
does not close temporary files appropriatelyHierarchicalMachine
now checks whether state_cls
, event_cls
and transition_cls
have been subclassed from nested base classes (e.g. NestedState
) to prevent hard to debug inheritance errorsPublished by aleneum almost 4 years ago
Release 0.8.6 is a minor release and contains bugfixes and new features:
HierarchicalMachine.add_states
will raise a ValueError
when an Enum
name contains the currently used NestedState.separator
.NestedState._scope
when enter/exit callbacks raise an exception (thanks @m986883511)HierarchicalMachine._get_trigger
which is bound to model.trigger
raise a MachineError
for invalid events and AttributeError
for unknown events (thanks @hsharrison)HierarchicalMachine.has_trigger
to determine whether an event is valid for an HSMAsyncMachine
features an event queue dictionary for individual models when queued='model'
(thanks @jekel)Machine.remove_model
will now also remove model events from the event queue when queued=True
Machine.get_transitions
and its HSM counterpart now accept Enum
and State
for source
and dest
(thanks @thedrow)Published by aleneum almost 4 years ago
Release 0.8.5 is a minor release and contains bugfixes:
AsyncMachine.switch_model_context
is expected to be async
now for easier integration of async code during model switch.GraphSupport
threw an exception when initial was set to a nested or parallel state (thanks @nickvazztau)Published by aleneum about 4 years ago
Release 0.8.4 is a minor release and contains bugfixes as well as new features:
AsyncMachine.protected_tasks
list which can be used to prevent transitions
to cancel certain tasks.HierarchicalMachine
now accepts substates ('A_1_c') and parallel states (['A', 'B']) as initial
parameterPublished by aleneum about 4 years ago
Release 0.8.3 is a minor release and contains several bugfixes mostly related to HierarchicalStateMachine
:
is_<model_attribute>_<state_name>
instead of is_<state_name>
when model_attribute != "state"
to enable multiple versions of such convenience functions. A warning will be raised when is_<state_name>
is used. (thanks @artofhuman)to_<state_name>
) will be assigned as to_<model_attribute>_<state_name>
. to_<state_name>
will work as before but raise a warning until version 0.9.0.allow_substates
did not consider enum stateschildren
with initial
parameterTransitionGraphSupport
(thanks @badiku)State.enter/exit
debug message emitted when callbacks have been processed.before_state_change/before
and after/after_state_change
in AsyncMachine
(thanks @tzoiker and @vishes-shell)Graph.get_graph()
did not consider enum
states when show_roi=True
(thank @termim)Published by aleneum over 4 years ago
Release 0.8.2 is a minor release and contains several bugfixes and improvements:
graphviz
package_check_event_result
failed when model was in parallel statedest=None
in Machine.add_transition
(not just falsy) for internal transitions (thanks @Pathfinder216)Model.trigger
now considers the machine's and current state's ignore_invalid_triggers
attribute and can be called with non-existing events (thanks @potens1)transitions.extensions.asyncio.AsyncTimeout
as a state decorator to avoid threads used in transitions.extensions.state.Timeout
(thanks @potens1)transitions
can now be tested online at mybinder.orgPublished by aleneum over 4 years ago
Release 0.8.1 is a minor release of HSM improvements and bugfixes in the diagram and async extension
HierarchicalAsync(Graph)Machine
HierarchicalMachine
(thanks @thedrow)Enum
(thanks @kbinpgh)HierarchicalMachine
(thanks @xiaohuihui1024)xdist
for parallel testing with pytest
(thanks @thedrow)Published by aleneum over 4 years ago
Release 0.8.0 is a major release and introduces asyncio support for Python 3.7+, parallel state support and some bugfixes
HierarchicalMachine
has been rewritten to support parallel states. Please have a look at the ReadMe.md to check what has changed.
transitions.extensions.nesting_legacy
for nowAsyncMachine
(see discussion #259); note that async HSMs are not yet supportedEnum
into strings in MarkupMachine
when necessaryMachine.add_ordered_transitions
to be called without the initial state (thanks @mkaranki and @facundofc)GraphMachine
now attempts to fall back to graphviz
when importing pygraphviz
failsPublished by aleneum almost 5 years ago
Release 0.7.2 is a minor release and contains bugfixes and and a new feature:
Published by aleneum about 5 years ago
Release 0.7.1 is a minor release and contains several documentation improvements and a new feature:
enum
Python 2.7: enum34
) support (thanks @artofhuman and @justinttl)nosetests
with pytest
(thanks @artofhuman)add_ordered_transitions
documentation in Readme.md
examples/Frequently asked questions.ipynb
long_description
in setup.py
(thanks @artofhuman)Published by aleneum about 5 years ago
Release 0.7.0 is a major release with fundamental changes to the diagram extension. It also introduces an intermediate MarkupMachine
which can be used to transfer and (re-)initialize machine configurations.
MarkupMachine
can be used to retrieve a Machine's dictionary representation
GraphMachine
uses this representation for Graphs now and does not rely on Machine
attributes any longerState.ignore_invalid_triggers
changed to None
. If it is not explicitly set, the Machine
's value is used instead.pygraphviz
and graphviz
for the creation of diagrams. Currently, GraphMachine
will check for pygraphviz
first and fall back to graphviz
. To use graphviz
directly pass use_pygraphiv=False
to the constructor of GraphMachine
GraphMachine
's attributes machine_attributes
and style_attributes
to adjust it to your needs.get_graph
was not assigned to models added during machine runtimePublished by aleneum almost 6 years ago
Published by aleneum over 6 years ago