pyfcstm.model.model
State machine module for parsing and representing hierarchical state machines.
This module provides classes and functions for working with state machines, including:
Representation of states, transitions, events, and operations
Parsing state machine DSL nodes into state machine objects
Exporting state machines to AST nodes and PlantUML diagrams
The module implements a hierarchical state machine model with support for:
Nested states
Entry, during, and exit actions
Guards and effects on transitions
Abstract function declarations
Variable definitions
Operation
- class pyfcstm.model.model.Operation(var_name: str, expr: Expr)[source]
Represents an operation that assigns a value to a variable.
An operation consists of a variable name and an expression that will be assigned to the variable when the operation is executed.
- Parameters:
var_name (str) – The name of the variable to assign to
expr (Expr) – The expression to evaluate and assign to the variable
- to_ast_node() OperationAssignment[source]
Convert this operation to an AST node.
- Returns:
An operation assignment AST node
- Return type:
dsl_nodes.OperationAssignment
Event
- class pyfcstm.model.model.Event(name: str, state_path: Tuple[str, ...])[source]
Represents an event that can trigger state transitions.
An event has a name and is associated with a specific state path in the state machine hierarchy.
- Parameters:
name (str) – The name of the event
state_path (Tuple[str, ...]) – The path to the state that owns this event
- property path: Tuple[str, ...]
Get the full path of the event including the state path and event name.
- Returns:
The full path to the event
- Return type:
Tuple[str, …]
Transition
- class pyfcstm.model.model.Transition(from_state: str | _StateSingletonMark, to_state: str | _StateSingletonMark, event: Event | None, guard: Expr | None, effects: List[Operation], parent_ref: ReferenceType | None = None)[source]
Represents a transition between states in a state machine.
A transition defines how the state machine moves from one state to another, potentially triggered by an event, guarded by a condition, and with effects that execute when the transition occurs.
- Parameters:
from_state (Union[str, dsl_nodes._StateSingletonMark]) – The source state name or special state marker
to_state (Union[str, dsl_nodes._StateSingletonMark]) – The target state name or special state marker
event (Optional[Event]) – The event that triggers this transition, if any
guard (Optional[Expr]) – The condition that must be true for the transition to occur, if any
effects (List[Operation]) – Operations to execute when the transition occurs
parent_ref (Optional[weakref.ReferenceType]) – Weak reference to the parent state
- property parent: State | None
Get the parent state of this transition.
- Returns:
The parent state or None if no parent is set
- Return type:
Optional[‘State’]
- to_ast_node() TransitionDefinition[source]
Convert this transition to an AST node.
- Returns:
A transition definition AST node
- Return type:
dsl_nodes.TransitionDefinition
OnStage
- class pyfcstm.model.model.OnStage(stage: str, aspect: str | None, name: str | None, doc: str | None, operations: List[Operation])[source]
Represents an action that occurs during a specific stage of a state’s lifecycle.
OnStage can represent enter, during, or exit actions, and can be either concrete operations or abstract function declarations.
- Parameters:
stage (str) – The lifecycle stage (‘enter’, ‘during’, or ‘exit’)
aspect (Optional[str]) – For ‘during’ actions in composite states, specifies if the action occurs ‘before’ or ‘after’ substates
name (Optional[str]) – For abstract functions, the name of the function
doc (Optional[str]) – For abstract functions, the documentation string
operations (List[Operation]) – For concrete actions, the list of operations to execute
- property is_abstract: bool
Check if this is an abstract function declaration.
- Returns:
True if this is an abstract function, False otherwise
- Return type:
bool
- property is_aspect: bool
Check if this is an aspect-oriented action.
- Returns:
False for OnStage instances (always)
- Return type:
bool
- to_ast_node() EnterStatement | DuringStatement | ExitStatement[source]
Convert this OnStage to an appropriate AST node based on the stage.
- Returns:
An enter, during, or exit statement AST node
- Return type:
Union[dsl_nodes.EnterStatement, dsl_nodes.DuringStatement, dsl_nodes.ExitStatement]
- Raises:
ValueError – If the stage is not one of ‘enter’, ‘during’, or ‘exit’
OnAspect
- class pyfcstm.model.model.OnAspect(stage: str, aspect: str | None, name: str | None, doc: str | None, operations: List[Operation])[source]
Represents an aspect-oriented action that occurs during a specific stage of a state’s lifecycle.
OnAspect is specifically used for aspect-oriented programming features in the state machine, allowing actions to be defined that apply across multiple states.
- Parameters:
stage (str) – The lifecycle stage (currently only supports ‘during’)
aspect (Optional[str]) – Specifies if the action occurs ‘before’ or ‘after’ substates
name (Optional[str]) – For abstract functions, the name of the function
doc (Optional[str]) – For abstract functions, the documentation string
operations (List[Operation]) – For concrete actions, the list of operations to execute
- property is_abstract: bool
Check if this is an abstract function declaration.
- Returns:
True if this is an abstract function, False otherwise
- Return type:
bool
- property is_aspect: bool
Check if this is an aspect-oriented action.
- Returns:
True for OnAspect instances (always)
- Return type:
bool
- to_ast_node() DuringAspectStatement[source]
Convert this OnAspect to an appropriate AST node based on the stage.
- Returns:
A during aspect statement AST node
- Return type:
Union[dsl_nodes.DuringAspectStatement]
- Raises:
ValueError – If the stage is not ‘during’
State
- class pyfcstm.model.model.State(name: str, path: Tuple[str, ...], substates: Dict[str, State], events: Dict[str, Event] | None = None, transitions: List[Transition] | None = None, on_enters: List[OnStage] | None = None, on_durings: List[OnStage] | None = None, on_exits: List[OnStage] | None = None, on_during_aspects: List[OnAspect] | None = None, parent_ref: ReferenceType | None = None, substate_name_to_id: Dict[str, int] | None = None)[source]
Represents a state in a hierarchical state machine.
A state can contain substates, transitions between those substates, and actions that execute on enter, during, or exit of the state.
- Parameters:
name (str) – The name of the state
path (Tuple[str, ...]) – The full path to this state in the hierarchy
substates (Dict[str, 'State']) – Dictionary mapping substate names to State objects
events (Dict[str, Event]) – Dictionary mapping event names to Event objects
transitions (List[Transition]) – List of transitions between substates
on_enters (List[OnStage]) – List of actions to execute when entering the state
on_durings (List[OnStage]) – List of actions to execute while in the state
on_exits (List[OnStage]) – List of actions to execute when exiting the state
on_during_aspects (List[OnAspect]) – List of aspect-oriented actions for the during stage
parent_ref (Optional[weakref.ReferenceType]) – Weak reference to the parent state
substate_name_to_id (Dict[str, int]) – Dictionary mapping substate names to numeric IDs
- property abstract_on_during_aspects: List[OnAspect]
Get all abstract during aspect actions.
- Returns:
List of abstract during aspect actions
- Return type:
List[OnAspect]
- property abstract_on_durings: List[OnStage]
Get all abstract during actions.
- Returns:
List of abstract during actions
- Return type:
List[OnStage]
- property abstract_on_enters: List[OnStage]
Get all abstract enter actions.
- Returns:
List of abstract enter actions
- Return type:
List[OnStage]
- property abstract_on_exits: List[OnStage]
Get all abstract exit actions.
- Returns:
List of abstract exit actions
- Return type:
List[OnStage]
- property is_leaf_state: bool
Check if this state is a leaf state (has no substates).
- Returns:
True if this is a leaf state, False otherwise
- Return type:
bool
- property is_root_state: bool
Check if this state is the root state (has no parent).
- Returns:
True if this is the root state, False otherwise
- Return type:
bool
- iter_on_during_after_aspect_recursively(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, State, OnAspect | OnStage] | Tuple[State, OnAspect | OnStage]][source]
Recursively iterate through ‘after’ aspect during actions from this state to the root state.
This method traverses the state hierarchy from this state to the root state, yielding all ‘after’ aspect during actions along the way.
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
with_ids (bool) – Whether to include numeric IDs with the actions
- Yield:
Tuples of (state, action) or (id, state, action) if with_ids is True
- Return type:
List[Union[Tuple[int, ‘State’, Union[OnAspect, OnStage]], Tuple[‘State’, Union[OnAspect, OnStage]]]]
- iter_on_during_aspect_recursively(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, State, OnAspect | OnStage] | Tuple[State, OnAspect | OnStage]][source]
Recursively iterate through all during actions in the proper execution order.
This method yields actions in the following order:
‘Before’ aspect actions from root state to this state
Regular during actions for this state
‘After’ aspect actions from this state to root state
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
with_ids (bool) – Whether to include numeric IDs with the actions
- Yield:
Tuples of (state, action) or (id, state, action) if with_ids is True
- Return type:
List[Union[Tuple[int, ‘State’, Union[OnAspect, OnStage]], Tuple[‘State’, Union[OnAspect, OnStage]]]]
- iter_on_during_before_aspect_recursively(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, State, OnAspect | OnStage] | Tuple[State, OnAspect | OnStage]][source]
Recursively iterate through ‘before’ aspect during actions from parent states to this state.
This method traverses the state hierarchy from the root state to this state, yielding all ‘before’ aspect during actions along the way.
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
with_ids (bool) – Whether to include numeric IDs with the actions
- Yield:
Tuples of (state, action) or (id, state, action) if with_ids is True
- Return type:
List[Union[Tuple[int, ‘State’, Union[OnAspect, OnStage]], Tuple[‘State’, Union[OnAspect, OnStage]]]]
- list_on_during_aspect_recursively(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, State, OnAspect | OnStage] | Tuple[State, OnAspect | OnStage]][source]
Get a list of all during actions in the proper execution order.
This is a convenience method that collects the results of iter_on_during_aspect_recursively.
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
with_ids (bool) – Whether to include numeric IDs with the actions
- Returns:
List of during actions in execution order
- Return type:
List[Union[Tuple[int, ‘State’, Union[OnAspect, OnStage]], Tuple[‘State’, Union[OnAspect, OnStage]]]]
- list_on_during_aspects(is_abstract: bool | None = None, aspect: str | None = None, with_ids: bool = False) List[Tuple[int, OnAspect] | OnAspect][source]
Get a list of during aspect actions, optionally filtered by abstract status, aspect, and with IDs.
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
aspect (Optional[str]) – If provided, filter to only actions with the given aspect (‘before’ or ‘after’)
with_ids (bool) – Whether to include numeric IDs with the actions
- Returns:
List of during aspect actions, optionally with IDs
- Return type:
- list_on_durings(is_abstract: bool | None = None, aspect: str | None = None, with_ids: bool = False) List[Tuple[int, OnStage] | OnStage][source]
Get a list of during actions, optionally filtered by abstract status, aspect, and with IDs.
- Parameters:
is_abstract (Optional[bool]) – If provided, filter to only abstract (True) or non-abstract (False) actions
aspect (Optional[str]) – If provided, filter to only actions with the given aspect (‘before’ or ‘after’)
with_ids (bool) – Whether to include numeric IDs with the actions
- Returns:
List of during actions, optionally with IDs
- Return type:
- list_on_enters(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, OnStage] | OnStage][source]
Get a list of enter actions, optionally filtered by abstract status and with IDs.
- list_on_exits(is_abstract: bool | None = None, with_ids: bool = False) List[Tuple[int, OnStage] | OnStage][source]
Get a list of exit actions, optionally filtered by abstract status and with IDs.
- property non_abstract_on_during_aspects: List[OnAspect]
Get all non-abstract during aspect actions.
- Returns:
List of non-abstract during aspect actions
- Return type:
List[OnAspect]
- property non_abstract_on_durings: List[OnStage]
Get all non-abstract during actions.
- Returns:
List of non-abstract during actions
- Return type:
List[OnStage]
- property non_abstract_on_enters: List[OnStage]
Get all non-abstract enter actions.
- Returns:
List of non-abstract enter actions
- Return type:
List[OnStage]
- property non_abstract_on_exits: List[OnStage]
Get all non-abstract exit actions.
- Returns:
List of non-abstract exit actions
- Return type:
List[OnStage]
- property parent: State | None
Get the parent state of this state.
- Returns:
The parent state or None if this is the root state
- Return type:
Optional[‘State’]
- to_ast_node() StateDefinition[source]
Convert this state to an AST node.
- Returns:
A state definition AST node
- Return type:
dsl_nodes.StateDefinition
- to_plantuml() str[source]
Convert this state to PlantUML notation.
- Returns:
PlantUML representation of the state
- Return type:
str
- to_transition_ast_node(transition: Transition) TransitionDefinition[source]
Convert a transition to an AST node in the context of this state.
- Parameters:
transition (Transition) – The transition to convert
- Returns:
A transition definition AST node
- Return type:
dsl_nodes.TransitionDefinition
- classmethod transition_to_ast_node(self: State | None, transition: Transition) TransitionDefinition[source]
Convert a transition to an AST node, considering the context of its parent state.
- Parameters:
self (Optional['State']) – The parent state, or None
transition (Transition) – The transition to convert
- Returns:
A transition definition AST node
- Return type:
dsl_nodes.TransitionDefinition
- property transitions_entering_children: List[Transition]
Get all transitions that start from the initial state (INIT_STATE).
These are the transitions that define the initial substate when entering this state.
- Returns:
List of transitions from INIT_STATE
- Return type:
List[Transition]
- property transitions_entering_children_simplified: List[Transition | None]
Get a simplified list of transitions entering child states.
If there’s a default transition (no event or guard), only include that one. Otherwise include all transitions and add None at the end.
- Returns:
List of transitions, possibly with None at the end
- Return type:
List[Optional[Transition]]
- property transitions_from: List[Transition]
Get all transitions that start from this state.
For non-root states, these are transitions in the parent state where this state is the source. For the root state, a synthetic transition to EXIT_STATE is returned.
- Returns:
List of transitions from this state
- Return type:
List[Transition]
- property transitions_to: List[Transition]
Get all transitions that end at this state.
For non-root states, these are transitions in the parent state where this state is the target. For the root state, a synthetic transition from INIT_STATE is returned.
- Returns:
List of transitions to this state
- Return type:
List[Transition]
VarDefine
- class pyfcstm.model.model.VarDefine(name: str, type: str, init: Expr)[source]
Represents a variable definition in a state machine.
- Parameters:
name (str) – The name of the variable
type (str) – The type of the variable
init (Expr) – The initial value expression
- name_ast_node() Name[source]
Convert the variable name to an AST node.
- Returns:
A name AST node
- Return type:
dsl_nodes.Name
- to_ast_node() DefAssignment[source]
Convert this variable definition to an AST node.
- Returns:
A definition assignment AST node
- Return type:
dsl_nodes.DefAssignment
StateMachine
- class pyfcstm.model.model.StateMachine(defines: Dict[str, VarDefine], root_state: State)[source]
Represents a complete state machine with variable definitions and a root state.
- Parameters:
- to_ast_node() StateMachineDSLProgram[source]
Convert this state machine to an AST node.
- Returns:
A state machine DSL program AST node
- Return type:
dsl_nodes.StateMachineDSLProgram
parse_dsl_node_to_state_machine
- pyfcstm.model.model.parse_dsl_node_to_state_machine(dnode: StateMachineDSLProgram) StateMachine[source]
Parse a state machine DSL program AST node into a StateMachine object.
This function validates the state machine structure and builds a complete StateMachine object with all states, transitions, events, and variable definitions.
- Parameters:
dnode (dsl_nodes.StateMachineDSLProgram) – The state machine DSL program AST node to parse
- Returns:
The parsed state machine
- Return type:
- Raises:
SyntaxError – If there are syntax errors in the state machine definition, such as duplicate variable definitions, unknown states in transitions, missing entry transitions, etc.