Skip to content

Commit

Permalink
fix: Fix parser of sub-final states
Browse files Browse the repository at this point in the history
  • Loading branch information
fgmacedo committed Dec 12, 2024
1 parent 3e48099 commit 1c1018d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 73 deletions.
9 changes: 9 additions & 0 deletions docs/releases/3.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ but would not match events named `errors.my.custom`, `errorhandler.mistake`, `er

An event designator consisting solely of `*` can be used as a wildcard matching any sequence of tokens, and thus any event.

### Delayed events

Specify an event to run in the near future. The engine will keep track of the execution time
and only process the event when `now > execution_time`.

TODO: Example of delayed events

Also, delayed events can be revoked by it's `send_id`.


## Bugfixes in 3.0.0

Expand Down
4 changes: 1 addition & 3 deletions statemachine/io/scxml/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
from .schema import ScriptAction

logger = logging.getLogger(__name__)
protected_attrs = _event_data_kwargs | {
"_sessionid",
}
protected_attrs = _event_data_kwargs | {"_sessionid", "_ioprocessors"}


class ParseTime:
Expand Down
4 changes: 4 additions & 0 deletions statemachine/io/scxml/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ def parse_state(
child_state = parse_state(child_state_elem, initial_states=initial_states)
child_state.initial = child_state.initial
state.states[child_state.id] = child_state
for child_state_elem in state_elem.findall("final"):
child_state = parse_state(child_state_elem, initial_states=initial_states, is_final=True)
child_state.initial = child_state.initial
state.states[child_state.id] = child_state
for child_state_elem in state_elem.findall("parallel"):
state = parse_state(child_state_elem, initial_states=initial_states, is_parallel=True)
child_state.initial = child_state.initial
Expand Down
46 changes: 26 additions & 20 deletions tests/scxml/w3c/mandatory/test326.fail.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,38 @@ Final configuration: `['fail']`

## Logs
```py
DEBUG statemachine.engines.base:base.py:374 States to enter: {S0}
DEBUG statemachine.io.scxml.actions:actions.py:443 Error executing actions
Traceback (most recent call last):
File "/home/macedo/projects/python-statemachine/statemachine/io/scxml/actions.py", line 441, in datamodel
act(machine=machine)
~~~^^^^^^^^^^^^^^^^^
File "/home/macedo/projects/python-statemachine/statemachine/io/scxml/actions.py", line 412, in data_initializer
value = _eval(action.expr, **kwargs)
File "/home/macedo/projects/python-statemachine/statemachine/io/scxml/actions.py", line 125, in _eval
return eval(expr, {}, kwargs)
File "<string>", line 1, in <module>
import sys;exec(eval(sys.stdin.readline()))
^^^^^^^^^^^^^
NameError: name '_ioprocessors' is not defined
DEBUG statemachine.engines.base:base.py:386 States to enter: {S0}
DEBUG statemachine.engines.sync:sync.py:64 Processing loop started: s0
DEBUG statemachine.io.scxml.actions:actions.py:170 Cond Var1 -> None
DEBUG statemachine.io.scxml.actions:actions.py:170 Cond True -> True
DEBUG statemachine.engines.sync:sync.py:89 Eventless/internal queue: {transition from S0 to Fail}
DEBUG statemachine.engines.base:base.py:283 States to exit: {S0}
DEBUG statemachine.engines.base:base.py:374 States to enter: {Fail}
DEBUG statemachine.io.scxml.actions:actions.py:179 Cond Var1 -> <statemachine.io.scxml.processor.IOProcessor object at 0x7f0f23f91190>
DEBUG statemachine.engines.sync:sync.py:89 Eventless/internal queue: {transition from S0 to S1}
DEBUG statemachine.engines.base:base.py:276 States to exit: {S0}
DEBUG statemachine.engines.base:base.py:386 States to enter: {S1}
DEBUG statemachine.io.scxml.actions:actions.py:476 Error executing actions
Traceback (most recent call last):
File "/home/macedo/projects/python-statemachine/statemachine/io/scxml/actions.py", line 472, in __call__
action(*args, **kwargs)
~~~~~~^^^^^^^^^^^^^^^^^
File "/home/macedo/projects/python-statemachine/statemachine/io/scxml/actions.py", line 253, in __call__
raise ValueError(
...<2 lines>...
)
ValueError: <assign> 'location' cannot assign to a protected attribute: _ioprocessors
DEBUG statemachine.engines.sync:sync.py:89 Eventless/internal queue: {transition error.execution from S1 to S2}
DEBUG statemachine.engines.base:base.py:276 States to exit: {S1}
DEBUG statemachine.engines.base:base.py:386 States to enter: {S2}
DEBUG statemachine.io.scxml.actions:actions.py:258 Assign: Var2 = <statemachine.io.scxml.processor.IOProcessor object at 0x7f0f23f915b0>
DEBUG statemachine.io.scxml.actions:actions.py:179 Cond Var1==Var2 -> False
DEBUG statemachine.engines.sync:sync.py:89 Eventless/internal queue: {transition from S2 to Fail}
DEBUG statemachine.engines.base:base.py:276 States to exit: {S2}
DEBUG statemachine.engines.base:base.py:386 States to enter: {Fail}

```

## "On transition" events
```py
DebugEvent(source='s0', event='None', data='{}', target='fail')
DebugEvent(source='s0', event='None', data='{}', target='s1')
DebugEvent(source='s1', event='error.execution', data='{\'event_id\': None, \'error\': ValueError("<assign> \'location\' cannot assign to a protected attribute: _ioprocessors")}', target='s2')
DebugEvent(source='s2', event='None', data='{}', target='fail')
```

## Traceback
Expand Down
50 changes: 0 additions & 50 deletions tests/scxml/w3c/mandatory/test416.fail.md

This file was deleted.

0 comments on commit 1c1018d

Please sign in to comment.