I am using the pytransitions library (documented here) to implement a Finite State Machine. One of the features outlined is the ability to get a list of the triggers for a specific state. Here is the example as per the documentation:
transitions = [
{ 'trigger': 'melt', 'source': 'solid', 'dest': 'liquid' },
{ 'trigger': 'evaporate', 'source': 'liquid', 'dest': 'gas' },
{ 'trigger': 'sublimate', 'source': 'solid', 'dest': 'gas' },
{ 'trigger': 'ionize', 'source': 'gas', 'dest': 'plasma' }
]
machine = Machine(model=Matter(), states=states, tansitions=transitions)
m.get_triggers('solid')
>>> ['melt', 'sublimate']
Here is a sample of my code that I am trying to run:
from transitions import Machine
states = ['changes ongoing', 'changes complete', 'changes pushed', 'code reviewed', 'merged']
triggers = ['git commit', 'git push', 'got plus2', 'merged']
# Initialize the state machine
git_user = Machine(states=states, initial=states[0], ignore_invalid_triggers=True, ordered_transitions=True)
# Create the FSM using the data provided
for i in range(len(triggers)):
git_user.add_transition(trigger=triggers[i], source=states[i], dest=states[i+1])
print(git_user.get_triggers(states[0]))
Expected Output:
['git commit']
Obtained output:
['to_code reviewed', 'to_changes ongoing', 'git commit', 'to_changes pushed', 'to_merged', 'to_changes complete', 'next_state']
Looking at the given example in the documentation, I should only get back 'git commit'. And that is the functionality I am looking for.
Thanks in advance for the help!
Machine.get_triggers
returns all possible transitions. This also includes auto transitions which are added by default. Additionally, the constructor keyword ordered_transitions=True
(which is equivalent to calling Machine.add_ordered_transitions()
) will add transitions from each state to the next one passed in your states
array with the trigger name next_state
.
So you end up with a) all auto transitions plus b) one next_state
and c) one of your added transitions.
To get your desired result you should disable auto_transitions
and also omit the ordered_transitions
keyword:
from transitions import Machine
states = ['changes ongoing', 'changes complete', 'changes pushed',
'code reviewed', 'merged']
triggers = ['git commit', 'git push', 'got plus2', 'merged']
# Initialise the state machine
git_user = Machine(states=states, initial=states[0],
ignore_invalid_triggers=True, auto_transitions=False)
# Create the FSM using the data provided
for i in range(len(triggers)):
git_user.add_transition(trigger=triggers[i], source=states[i],
dest=states[i+1])
print(git_user.get_triggers(states[0])) # >>> ['git commit']
You might also want to rethink your trigger and state names if you want to make use of transitions' convenience functions which do not work with names with spaces.
For instance, 'changes_ongoing'
would allow you to use git_user.is_changes_ongoing()
to check the current state where a trigger named 'git_commit'
could also be called directly on the model with git_user.git_commit()
.