pyfcstm.simulate.decorators

Decorators for abstract handler registration.

This module provides decorators that allow users to define abstract handlers as methods in a class, making it easy to organize complex handler logic.

The module contains the following main components:

  • abstract_handler() - Decorator to mark a method as an abstract handler.

  • register_handlers_from_object() - Register all decorated methods from an object.

Example:

>>> from pyfcstm.simulate import abstract_handler, SimulationRuntime
>>> class MyHandlers:
...     def __init__(self):
...         self.call_count = 0
...
...     @abstract_handler('System.Active.Init')
...     def handle_init(self, ctx):
...         self.call_count += 1
...         print(f"Init called, counter={ctx.get_var('counter')}")
...
...     @abstract_handler('System.Active.Monitor')
...     def handle_monitor(self, ctx):
...         print(f"Monitoring: {ctx.get_full_state_path()}")
...
>>> runtime = SimulationRuntime(state_machine)
>>> handlers = MyHandlers()
>>> runtime.register_handlers_from_object(handlers)

abstract_handler

pyfcstm.simulate.decorators.abstract_handler(action_path: str) Callable[[Callable], Callable][source]

Decorator to mark a method as an abstract handler for a specific action path.

This decorator attaches metadata to the method, which can later be used by SimulationRuntime.register_handlers_from_object() to automatically register all handlers from a class instance.

Parameters:

action_path (str) – The full path to the abstract action (e.g., ‘System.Active.Init’)

Returns:

Decorator function that marks the method

Return type:

Callable[[Callable], Callable]

Raises:

ValueError – If action_path is empty

Example:

>>> class MyHandlers:
...     @abstract_handler('System.Active.Init')
...     def handle_init(self, ctx: ReadOnlyExecutionContext):
...         print(f"Initializing: {ctx.get_full_state_path()}")
...
...     @abstract_handler('System.Active.Monitor')
...     def handle_monitor(self, ctx: ReadOnlyExecutionContext):
...         counter = ctx.get_var('counter')
...         print(f"Monitoring, counter={counter}")

Note

The decorated method must accept exactly one parameter (besides self): a ReadOnlyExecutionContext instance.

get_handler_metadata

pyfcstm.simulate.decorators.get_handler_metadata(func: Callable) str | None[source]

Get the action path metadata from a decorated method.

Parameters:

func (Callable) – The function to check

Returns:

The action path if the function is decorated, None otherwise

Return type:

Optional[str]

Example:

>>> @abstract_handler('System.Active.Init')
... def my_handler(ctx):
...     pass
>>> get_handler_metadata(my_handler)
'System.Active.Init'

is_abstract_handler

pyfcstm.simulate.decorators.is_abstract_handler(func: Callable) bool[source]

Check if a function is decorated as an abstract handler.

Parameters:

func (Callable) – The function to check

Returns:

True if the function has handler metadata

Return type:

bool

Example:

>>> @abstract_handler('System.Active.Init')
... def my_handler(ctx):
...     pass
>>> is_abstract_handler(my_handler)
True