Skip to main content

state machine for python classes

Project description

.. figure:: https://travis-ci.org/gemerden/statessvg?branch=master
:alt: Travis

Travis

statemachine
============

Easy to use state machine to manage the state of python objects.

Introduction
------------

This state machine implementation is developed with the following goals
in mind:

- Easy to use API, for configuration of the state machine and
triggering state transitions,
- Usable for any (almost, I'm sure) python class with a finite number
of states,
- Fully featured, including nested states, conditional transitions,
shorthand notations, many ways to configure callbacks,
- Simple state machines do not require advanced knowledge; complexity
of configuration scales with complexity of requirements,
- One state machine instance can manage the state of many stateful
objects; the objects only store their current state string,
- Reasonably fast

Limitations
-----------

The state machine module has been tested with python 2.7, if requested I
will definitely consider python 3 support, depending on time
constraints.

Documentation
-------------

To learn more check the extensive
`tutorial <https://github.com/gemerden/statemachine/blob/master/statemachine/docs/tutorial.md>`__.

Concepts
--------

The following basic state machine concepts are used

- *state*: state of an stateful object; objects can be in one state at
the time,
- *transition*: transition of the object from one state to another
resulting,
- *state machine*: system that manages the states of objects according
to predefined states and transitions,
- *trigger*: method called on an object that can result in a state
transition,
- *callbacks*: functions called on state transitions by the state
machine,
- *condition*: conditions for a specific state transition to take
place.

Features
--------

The module has the following basic and some more advanced features:

- trigger state transitions by setting trigger name in machine
configuration:

- same trigger can be set for different transitions,
- trigger method can pass arguments to callbacks like ``on_exit``
and ``on_entry``,

- conditions (also callbacks) can be set on states and transitions:

- if a transition is triggered, but the condition is not met, the
transition does not take place

- switched transitions can be used to go from one state to another
depending on conditions

- trigger can be used for conditional (switched) transition,
- to do this, create multiple trasnitions from the same state to
different states and give them different conditions

- state transitions can be started by explicitly setting the state
(obj.state = "some\_state"):

- if a condition is set and not met on the transition an exception
is raised, because the callbacks would not be called,
- if the callbacks function require extra arguments (apart from the
state managed object), this method will fail

- a number of callbacks can be installed for each state and transition,
with obj the state managed object and **args, **\ \*kwargs the
arguments passed via the trigger to the callback, in calling order:

- StateMachine.prepare(self, obj. **args, **\ \*kwargs),
- StateMachine.before\_any\_exit(self, obj. **args, **\ \*kwargs),
- State.on\_exit(self, obj. **args, **\ \*kwargs),
- Transition.on\_transfer(self, obj. **args, **\ \*kwargs), # after
this the state is changed on the object
- State.on\_entry(self, obj. **args, **\ \*kwargs),
- StateMachine.after\_any\_entry(self, obj. **args, **\ \*kwargs)
- note that if a condition is present and not met, none of these
functions are called, apart from prepare

- callbacks can be methods on the class of which the state is managed
by the machine:

- This is the case when the calback is configured as a string (e.g.
"on\_entry": "do\_callback"),

- wildcards and listed states can be used to define multiple
transitions at once:

- e.g. transition {"old\_state": "\*", "new\_state": ["A", "B"]}
would create transitions from all states to both state A and B

- nested states can be used to better organize states and transitions,
states can be nested to any depth,
- context managers can be used to create a context for all callbacks,
- custom exceptions:

- MachineError: raised in case of a misconfiguration of the state
machine,
- TransitionError: raised in case of e.g. an attempt to trigger a
non-existing transition,

Rules (for the mathematically minded)
-------------------------------------

The state machine in the module has the following rules for setting up
states and transitions:

- notation:

- A, B, C : states of a state managed object (called 'object' from
now)
- A(B, C) : state A with nested states B, C, with \* indicating that
B is the default initial state
- A.B : sub-state B of A; A.B is called a state path
- : transition between state A and state B
- : transition from A to B or C, depending on condition functions
(there is no 'and')
- : shorthand for transitions and
- : shorthand for all transitions from A to states in the same
machine

- an object cannot just be in state A if A has substates; given state
A(B, C), the object can be in A.B or A.C, not in A
- allowed transitions, given states A, B, C(E, F) and D(G, H):

- : basic transition, configured as {"old\_state": "A",
"new\_state": "B"}
- : transition from a state to itself
- <C.E, A>: transition from a specific sub-state of C to A
- : transition from any sub-state of C to specific state D.G
- : transition from A to C.E, E being the initial state of C because
it was explicitly set or because it is the first state in E
- <C.F, D.H>: transitioning from one sub-state in a state to another
sub-state in another state. Note that this would call (if present)
on\_exit on F and C and on\_entry on D and H in that order.

- non-allowed transitions:

- <C.E, C.F>: inner transitions cannot be defined on the top level;
define in state C

- adding switched transitions, given transition :

- B and C must have conditions attached in the transition, these
condition will be run though in order
- D does not need to have a condition attached meaning it will
always be the next state if the conditions on the transition to B
and C fail

Authors
-------

Lars van Gemerden (rational-it) - initial code and documentation.

License
-------

This project is licensed under the license in LICENSE.txt.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

states-0.1.4.zip (16.7 kB view hashes)

Uploaded Source

Built Distribution

states-0.1.4-py2-none-any.whl (16.0 kB view hashes)

Uploaded Python 2

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page