Basic Finite State Machine (FSM) tools.
Short summary:
-
CancellationError: Subclass ofFSMErrorRaised when trying to make use of anFSMwhich is cancelled. -
FSM: Base class for a finite state machine (FSM). -
FSMError: An exception associated with anFSM. -
FSMSubType: Type variable. -
FSMTransitionEvent: FSMTransitionEvent(old_state, new_state, event, when, extra).
Symbols
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases::
class Sequence[T]: # T is a TypeVar
...
This syntax can also be used to create bound and constrained type variables::
# S is a TypeVar bound to str
class StrSequence[S: str]:
...
# A is a TypeVar constrained to str or bytes
class StrOrBytesSequence[A: (str, bytes)]:
...
Type variables can also have defaults:
class IntDefault[T = int]:
...
However, if desired, reusable type variables can also be constructed manually, like so::
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes D = TypeVar('D', default=int) # Defaults to int
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they
are created through the type parameter syntax and when
infer_variance=True is passed. Manually created type variables may
be explicitly marked covariant or contravariant by passing
covariant=True or contravariant=True. By default, manually
created type variables are invariant. See PEP 484 and PEP 695 for more
details.
FSMSubType = ~FSMSubType
Classes
class CancellationError(FSMError)
Subclass of FSMError Raised when trying to make use of an
FSM which is cancelled.
For example, this is raised by a cs.result.Result
when accessing .result or .exc_info after cancellation.
CancellationError.__init__(self, message=None, *, fsm=None, **kw)
Initialise the CancellationError.
The optional message parameter (default "cancelled")
is set as the message attribute.
Other keyword parameters set their matching attributes.
class FSM(cs.gvutils.DOTNodeMixin)
Base class for a finite state machine (FSM).
The allowed states and transitions are defined by the class
attribute FSM_TRANSITIONS, a mapping of
state->event->new_state.
Each instance has the following attributes:
fsm_state: the current state value.fsm_history: an optional iterable ofFSMTransitionEventstate transitions recorded by thefsm_eventmethod. Usually this would beNone(the default) or alist.
FSM.__init__(self, state=None, *, history=None, lock=None, transitions=None)
Initialise the FSM from:
state: optional positional parameter for the initial state, defaultself.FSM_DEFAULT_STATEor the first key fromself.FSM_TRANSITIONShistory: an optional object to record state transition history, defaultNone; if notNonethis should be an iterable object with a.append(entry)method such as alist.lock: an optional mutex to control access; if presupplied and shared with the caller it should probably be anRLock; the default is aLock, which is enough forFSMprivate usetransitions: optional state->event->state mapping; if provided, this will override the classFSM_TRANSITIONSmapping
Note that the FSM base class does not provide a
FSM_DEFAULT_STATE attribute; a default state value of
None will leave .fsm_state unset.
This behaviour is is chosen mostly to support subclasses
with unusual behaviour, particularly Django's Model class
whose refresh_from_db method seems to not refresh fields
which already exist, and setting .fsm_state from a
FSM_DEFAULT_STATE class attribute thus breaks this method.
Subclasses of this class and Model should not provide a
FSM_DEFAULT_STATE attribute, instead relying on the field
definition to provide this default in the usual way.
FSM.FSM_ANY_STATE
<object object at 0x10c4ed270>
FSM.FSM_TRANSITIONS
{}
FSM.__getattr__(self, attr)
Provide the following attributes:
- present the state names as attributes, for example:
self.PENDING=='PENDING'if there is a'PENDING'state - present
is_statename as a Boolean testing whetherself.fsm_state==statename.upper() - a callable calling
self.fsm_event(attr)ifattris an event name for the current state Fall back to the superclass__getattr__.
FSM.dot_node_palette_key
<property object at 0x10e10eca0>
FSM.fsm_as_svg(self, layout=None, history_style=None, **dot_kw) -> str
Render the state transition diagram as SVG.
FSM.fsm_callback(self, state, callback)
Register a callback to be called immediately on transition
to state as callback(self,FSMEventTransition).
The special state value FSM.FSM_ANY_STATE may be supplied
to register a callback which fires for every state transition.
>>> fsm = FSM('state1',transitions={
... 'state1':{'ev_a':'state2'},
... 'state2':{'ev_b':'state1'},
... })
>>> fsm.fsm_callback('state2',lambda task, transition: print(task, transition))
>>> fsm.fsm_callback(FSM.FSM_ANY_STATE,lambda task, transition: print("ANY", task, transition))
>>> fsm.ev_a(foo=3) # doctest: +ELLIPSIS
ANY FSM:state2 FSMTransitionEvent(old_state='state1', new_state='state2', event='ev_a', when=..., extra={'foo': 3})
FSM:state2 FSMTransitionEvent(old_state='state1', new_state='state2', event='ev_a', when=..., extra={'foo': 3})
'state2'
>>> fsm.ev_b(foo=4) # doctest: +ELLIPSIS
ANY FSM:state1 FSMTransitionEvent(old_state='state2', new_state='state1', event='ev_b', when=..., extra={'foo': 4})
'state1'
FSM.fsm_callback_discard(self, state, callback)
Deregister a callback for state.
FSM.fsm_dot
<property object at 0x10e10ec50>
FSM.fsm_event(self, event, **extra)
Transition the FSM from the current state to a new state based on event.
Call any callbacks associated with the new state.
Returns the new state.
Optional information may be passed as keyword arguments.
A transition instance of FSMTransitionEvent is created
with the following attributes:
old_state: the state whenfsm_eventwas callednew_state: the new stateevent: theeventwhen: a UNIX timestamp fromtime.time()extra: adictwith theextrainformation
If self.fsm_history is not None,
transition is appended to it.
If there are callbacks for new_state or FSM.FSM_ANY_STATE,
call each callback as callback(self,transition).
Important note: the callbacks are run in series in the
current Thread. If you need to dispatch a long running
activity from a state transtion, the callback should still
return promptly.
FSM.fsm_event_is_allowed(self, event)
Test whether event is permitted in the current state.
This can be handy as a pretest.
FSM.fsm_events
<property object at 0x10e10ebb0>
FSM.fsm_history
<property object at 0x10e10f010>
FSM.fsm_print(self, file=None, fmt=None, layout=None, **dot_kw)
Print the state transition diagram to file, default sys.stdout,
in format fmt using the engine specified by layout, default 'dot'.
This is a wrapper for cs.gvutils.gvprint.
FSM.fsm_print_state_diagram(file=None, *, fmt=None, graph_name=None, history=None, history_style=None, state=None, transitions=None, **gvprint_kw)
Print the state diagram via cs.gvutils.gvprint.
The DOT syntax graph description is computed with
FSM.fsm_state_diagram_as_dot and the graph_name,
history, history_style, state and transitions
parameters are passed through to this.
If fmt is specified as dot then the DOT and any remaining
keyword arguments are passed to print().
Otherwise any remaining keyword paramaeters are passed to gvprint.
FSM.fsm_state_diagram_as_dot(transitions=None, *, sep='\n', state=None, graph_name=None, history=None, history_style=None) -> str
Compute a DOT syntax graph description of the state diagram.
Parameters:
transitions: optional mapping of state->event->state, defaultcls.FSM_TRANSITIONSstate: optional current state name, a key of the transitionssep: optional separator between "lines", default'\n'graph_name: optional name for the graph, default the class namehistory: optional event transition historyhistory_style: optional style mapping for event transition history, used to style edges which have been traversed
FSM.fsm_svg
<property object at 0x10e10ed40>
FSM.fsm_transitions_as_dot(self, transitions=None, **diagram_kw) -> str
Compute a DOT syntax graph description of the state diagram.
Parameters:
transitions: optional mapping of state->event->state, defaultself.FSM_TRANSITIONSsep: optional separator between "lines", default'\n'graph_name: optional name for the graph, default the class namehistory_style: optional style mapping for event transition history, used to style edges which have been traversed
class FSMError(builtins.Exception)
An exception associated with an FSM.
These have a .fsm attribute storing an (optional) FSM
reference supplied at initialisation.
class FSMTransitionEvent(builtins.tuple)
FSMTransitionEvent(old_state, new_state, event, when, extra)
FSMTransitionEvent.__replace__(self, /, **kwds)
Return a new FSMTransitionEvent object replacing specified fields with new values
FSMTransitionEvent.event
_tuplegetter(2, 'Alias for field number 2')
FSMTransitionEvent.extra
_tuplegetter(4, 'Alias for field number 4')
FSMTransitionEvent.new_state
_tuplegetter(1, 'Alias for field number 1')
FSMTransitionEvent.old_state
_tuplegetter(0, 'Alias for field number 0')
FSMTransitionEvent.when
_tuplegetter(3, 'Alias for field number 3')
Metadata
Release files for cs-fsm 20261016
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cs_fsm-20261016.tar.gz | 8.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cs_fsm-20261016-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 18.8 kB
Release files / cs_fsm-20261016.tar.gz
| Download URL | cs_fsm-20261016.tar.gz |
|---|---|
| Size | 8.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9dc8a2ba667601a720fead6321dccd82704250b2cc018bb799ce959cba322a32
|
|
BLAKE2b-256 checksum How to use checksums |
00b7b563a0e0651d0679a5dde0a332c6a4c014ed2c2957efd0f80d13f080a543
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.1
|
Release files / cs_fsm-20261016-py2.py3-none-any.whl
| Download URL | cs_fsm-20261016-py2.py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
dea2a68889dc8998d42ad7de2fc81ff98514e33b4aed12150a49a72fbe1d1e4b
|
|
BLAKE2b-256 checksum How to use checksums |
354a5f48b7200a4073143c83839d1cd0d62ca7ce3d2ea4825f61e3ec3c6bcad8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.1
|