From ffacefd25038b66678a147075620c76b4904e29d Mon Sep 17 00:00:00 2001 From: Fernando Macedo Date: Fri, 3 Apr 2026 09:45:46 -0300 Subject: [PATCH 1/2] docs: improve StateChart docstrings and complete 3.1.0 release notes Document missing StateChart members: **kwargs on __init__, model and history_values instance attributes, events property. Fix typo in listeners parameter ("provies" -> "provides"). Add missing bugfixes to 3.1.0 release notes: Configuration write-through (#596) and States.from_enum() in compound/parallel states (#607). --- docs/releases/3.1.0.md | 10 ++++++++++ statemachine/statemachine.py | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/releases/3.1.0.md b/docs/releases/3.1.0.md index 6748db51..3756ecd6 100644 --- a/docs/releases/3.1.0.md +++ b/docs/releases/3.1.0.md @@ -170,4 +170,14 @@ machine instance concurrently. This is now documented in the The docstring also now includes a `deprecated` directive for Sphinx autodoc. [#604](https://github.com/fgmacedo/python-statemachine/issues/604). +- `Configuration.add()`/`discard()` now write through the model setter, ensuring state + changes are persisted correctly on domain models (e.g., Django models with custom setters). + Previously the configuration was updated in-place without notifying the model layer. + [#596](https://github.com/fgmacedo/python-statemachine/pull/596). + +- `States.from_enum()` now works correctly inside compound and parallel states. Previously + it raised an error when used as a nested state declaration. + [#607](https://github.com/fgmacedo/python-statemachine/pull/607), + fixes [#606](https://github.com/fgmacedo/python-statemachine/issues/606). + ## Misc in 3.1.0 diff --git a/statemachine/statemachine.py b/statemachine/statemachine.py index 1f9b12f9..ca36f0c1 100644 --- a/statemachine/statemachine.py +++ b/statemachine/statemachine.py @@ -55,9 +55,13 @@ class StateChart(Generic[TModel], metaclass=StateMachineMetaclass): start_value: An optional start state value if there's no current state assigned on the :ref:`domain models`. Default: ``None``. - listeners: An optional list of objects that provies attributes to be used as callbacks. + listeners: An optional list of objects that provides attributes to be used as callbacks. See :ref:`listeners` for more details. + **kwargs: Additional keyword arguments available for dependency injection into + callbacks. These are passed to class listener ``setup()`` methods and to the + initial activation callbacks (e.g. ``on_enter_``). + """ TransitionNotAllowed = TransitionNotAllowed @@ -145,9 +149,13 @@ def __init__( **kwargs: Any, ): self.model: TModel = model if model is not None else Model() # type: ignore[assignment] - self.history_values: Dict[ - str, List[State] - ] = {} # Mapping of compound states to last active state(s). + """The external model object that holds domain state, or an internal + :class:`Model` instance when none is provided. See :ref:`domain models`.""" + + self.history_values: Dict[str, List[State]] = {} + """Mapping from compound state IDs to the list of states that were active + the last time that compound state was exited. Used by history pseudo-states + to restore previous configurations.""" self.state_field = state_field self.start_configuration_values = ( [start_value] if start_value is not None else list(self.start_configuration_values) @@ -416,6 +424,7 @@ def current_state(self, value): @property def events(self) -> "List[Event]": + """List of all :ref:`Event` instances declared on this state machine.""" return [getattr(self, event) for event in self.__class__._events] @property From 58dfe6c452c132c3f9f45a4cb943309dbd58c3fa Mon Sep 17 00:00:00 2001 From: Fernando Macedo Date: Fri, 3 Apr 2026 09:49:37 -0300 Subject: [PATCH 2/2] docs: fix States.from_enum() bugfix description in release notes The bug was a silent failure (states not collected), not an error. --- docs/releases/3.1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/releases/3.1.0.md b/docs/releases/3.1.0.md index 3756ecd6..f5334276 100644 --- a/docs/releases/3.1.0.md +++ b/docs/releases/3.1.0.md @@ -176,7 +176,7 @@ machine instance concurrently. This is now documented in the [#596](https://github.com/fgmacedo/python-statemachine/pull/596). - `States.from_enum()` now works correctly inside compound and parallel states. Previously - it raised an error when used as a nested state declaration. + the states were silently not collected when used as a nested state declaration. [#607](https://github.com/fgmacedo/python-statemachine/pull/607), fixes [#606](https://github.com/fgmacedo/python-statemachine/issues/606).