Skip to content

Commit

Permalink
prevent parents from overriding children's (falsy) results (#456)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleneum committed Aug 10, 2020
1 parent c2afc02 commit 6ad4a4d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 5 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Feature: Nested enums can now be passed in a dict as `children` with `initial` parameter
- Bugfix #449: get_triggers/get_transitions did not return nested triggers correctly (thanks @alexandretanem)
- Feature #452: Improve handling of label attributes in custom diagram states and `TransitionGraphSupport` (thanks @badiku)
- Bugfix #456: Prevent parents from overriding (falsy) results of their children's events (thanks @alexandretanem)

## 0.8.2 (June 2020)

Expand Down
9 changes: 9 additions & 0 deletions tests/test_nesting.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,15 @@ def on_enter_A_2(self):
self.assertTrue(enter_mock.called)
self.assertFalse(parent_mock.called)

def test_child_condition_persistence(self):
# even though the transition is invalid for the parent it is valid for the nested child state
# no invalid transition exception should be thrown
machine = self.machine_cls(states=[{'name': 'A', 'children': ['1', '2'], 'initial': '1',
'transitions': [{'trigger': 'go', 'source': '1', 'dest': '2',
'conditions': self.stuff.this_fails}]}, 'B'],
transitions=[['go', 'B', 'A']], initial='A')
self.assertFalse(False, machine.go())


class TestSeparatorsBase(TestCase):

Expand Down
5 changes: 4 additions & 1 deletion tests/test_nesting_legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ def test_transitioning(self):
self.assertEqual(s.state, 'C')

def test_nested_definitions(self):
pass
pass # not supported by legacy machine

def test_add_nested_state(self):
pass # not supported by legacy machine

def test_child_condition_persistence(self):
pass # not supported by legacy machine


class TestReuseLegacySeparatorDefault(TestReuseSeparatorBase):

Expand Down
8 changes: 6 additions & 2 deletions transitions/extensions/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,13 @@ async def _trigger_event(self, _model, _trigger, _state_tree, *args, **kwargs):
for key, value in _state_tree.items():
if value:
with self(key):
res[key] = await self._trigger_event(_model, _trigger, value, *args, **kwargs)
tmp = await self._trigger_event(_model, _trigger, value, *args, **kwargs)
if tmp is not None:
res[key] = tmp
if not res.get(key, None) and _trigger in self.events:
res[key] = await self.events[_trigger].trigger(_model, self, *args, **kwargs)
tmp = await self.events[_trigger].trigger(_model, self, *args, **kwargs)
if tmp is not None:
res[key] = tmp
return None if not res or all([v is None for v in res.values()]) else any(res.values())


Expand Down
8 changes: 6 additions & 2 deletions transitions/extensions/nesting.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,11 @@ def _trigger_event(self, _model, _trigger, _state_tree, *args, **kwargs):
for key, value in _state_tree.items():
if value:
with self(key):
res[key] = self._trigger_event(_model, _trigger, value, *args, **kwargs)
tmp = self._trigger_event(_model, _trigger, value, *args, **kwargs)
if tmp is not None:
res[key] = tmp
if not res.get(key, None) and _trigger in self.events:
res[key] = self.events[_trigger].trigger(_model, self, *args, **kwargs)
tmp = self.events[_trigger].trigger(_model, self, *args, **kwargs)
if tmp is not None:
res[key] = tmp
return None if not res or all(v is None for v in res.values()) else any(res.values())

0 comments on commit 6ad4a4d

Please sign in to comment.