pytransitions / transitions

A lightweight, object-oriented finite state machine implementation in Python with many extensions
MIT License
5.49k stars 524 forks source link

Misleading behavior on get_triggers with enums #527

Closed luup2k closed 3 years ago

luup2k commented 3 years ago

From readme.md example to use enums, i don't know if this behavior is intentional...


import enum  # Python 2.7 users need to have 'enum34' installed
from transitions import Machine

class States(enum.Enum):
    ERROR = 0
    RED = 1
    YELLOW = 2
    GREEN = 3

transitions = [['proceed', States.RED, States.YELLOW],
               ['proceed', States.YELLOW, States.GREEN],
               ['error', '*', States.ERROR]]

m = Machine(states=States, transitions=transitions, initial=States.RED)
assert m.state is States.RED
m.get_triggers(m.state) # response -> []
m.get_triggers(m.state.name) # response -> ['to_ERROR', 'to_RED', 'to_YELLOW', 'to_GREEN', 'proceed', 'error']

As you can see we need to send enum.name to get_triggers to get the transitions due nature of comparision:

states = set(args)
return [t for (t, ev) in self.events.items() if any(state in ev.transitions for state in states)]
aleneum commented 3 years ago

Hello @luup2k,

currently get_triggers only support strings (state names). But you are right, the documentation mentions 'states' and not state names. In 6c202d6, I added a check to convert states and enums (both share the same behaviour in that regard) to state_names. This should be enough to allow get_triggers to also handle enums and states correctly.