Skip to content

Commit 21161ba

Browse files
committed
refactor: move donedata support from SCXML module to core State
Add `donedata` parameter to `State.__init__()` so Python-defined final states can specify donedata callables directly. The SCXML processor now passes donedata as a separate key instead of mixing it into enter callbacks. Also removes the no-op `_processing_loop()` call from `ExecuteBlock`.
1 parent 7f409be commit 21161ba

4 files changed

Lines changed: 10 additions & 6 deletions

File tree

statemachine/io/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class BaseStateKwargs(TypedDict, total=False):
4545
parallel: bool
4646
enter: "str | ActionProtocol | Sequence[str] | Sequence[ActionProtocol]"
4747
exit: "str | ActionProtocol | Sequence[str] | Sequence[ActionProtocol]"
48+
donedata: "ActionProtocol | None"
4849

4950

5051
class StateKwargs(BaseStateKwargs, total=False):

statemachine/io/scxml/actions.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,9 @@ def __init__(self, content: ExecutableContent):
511511
self.action_callables = [create_action_callable(action) for action in content.actions]
512512

513513
def __call__(self, *args, **kwargs):
514-
machine: StateChart = kwargs["machine"]
515514
for action in self.action_callables:
516515
action(*args, **kwargs)
517516

518-
machine._processing_loop()
519-
520517

521518
class DoneDataCallable(CallableAction):
522519
"""Evaluates <donedata> params/content and returns the data for done events."""

statemachine/io/scxml/processor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ def _process_state(self, state: State) -> StateDefinition:
162162
if state.parallel:
163163
state_dict["parallel"] = True
164164

165-
# Process enter actions + donedata
165+
# Process enter actions
166166
enter_callables: list = [
167167
ExecuteBlock(content) for content in state.onentry if not content.is_empty
168168
]
169-
if state.final and state.donedata:
170-
enter_callables.append(DoneDataCallable(state.donedata))
171169
if enter_callables:
172170
state_dict["enter"] = enter_callables
171+
if state.final and state.donedata:
172+
state_dict["donedata"] = DoneDataCallable(state.donedata)
173173

174174
# Process exit actions
175175
if state.onexit:

statemachine/state.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .callbacks import CallbackGroup
99
from .callbacks import CallbackPriority
1010
from .callbacks import CallbackSpecList
11+
from .exceptions import InvalidDefinition
1112
from .exceptions import StateMachineError
1213
from .i18n import _
1314
from .transition import Transition
@@ -190,6 +191,7 @@ def __init__(
190191
history: "List[HistoryState] | None" = None,
191192
enter: Any = None,
192193
exit: Any = None,
194+
donedata: Any = None,
193195
_callbacks: Any = None,
194196
):
195197
self.name = name
@@ -212,6 +214,10 @@ def __init__(
212214
self.exit = self._specs.grouper(CallbackGroup.EXIT).add(
213215
exit, priority=CallbackPriority.INLINE
214216
)
217+
if donedata is not None:
218+
if not final:
219+
raise InvalidDefinition(_("'donedata' can only be specified on final states."))
220+
self.enter.add(donedata, priority=CallbackPriority.INLINE)
215221
self.document_order = 0
216222
self._init_states()
217223

0 commit comments

Comments
 (0)