Closed artofhuman closed 2 years ago
Hello again, @artofhuman 👋 !
For example one of the popular ruby libs AASM has a similar API for check transitions
getting this functionality for transitions can be achieved by a) extending _add_model_to_trigger
and optionally b) evaluating conditions to only return True
when condition checks pass:
from transitions import Machine, EventData
class MayMachine(Machine):
def _can_trigger(self, model, *args, **kwargs):
e = EventData(None, None, self, model, args, kwargs)
return [trigger_name for trigger_name in self.get_triggers(model.state)
if any(all(c.check(e) for c in t.conditions)
for t in self.events[trigger_name].transitions[model.state])]
def _add_trigger_to_model(self, trigger, model):
super()._add_trigger_to_model(trigger, model)
self._checked_assignment(model, f"may_{trigger}", lambda: trigger in self._can_trigger(model))
m = MayMachine(states=["A", "B", "C"],
transitions=[["go", "A", "B"],
dict(trigger='do', source='A', dest='C', conditions=lambda: False),
["do", "B", "C"]],
initial="A")
assert m.state == 'A'
assert m.may_go()
assert not m.may_do()
But you request this for destination states, right? This is not supported by AASM, is it?
AASM is just an example lib API.
My point is it will be good to have this feature in core without overriding methods. I think overriding private methods is not good practice because they may be changed in future versions.
So these are only options for how it may look. More realistic example:
class States(Enum):
PENDING = "pending"
PRINTED = "printed"
MARKED = "marked"
order = Order()
machine = Machine(
states= States,
initial=instance.state,
auto_transitions=False,
model=order,
)
machine.add_transition(
"print", States.PENDING, States.PRINTED,
)
machine.add_transition(
"mark", [States.PENDING, States.PRINTED], States.MARKED,
)
Option1.
order.may_print()
Option2
order.may_to_state(State.PRINTED)
I think overriding private methods is not good practice because they may be changed in future versions.
fair enough
Option A is something that is occasionally requested. Would that be sufficient for your use case?
Yes 😄
may
has been introduced in 0.9.0 and was recently pushed to master
Add method to check may model to be transited to target state.
Currently, we have a method to check the current state ex:
is_STOPPED()
but don't have a method to check if a model may be reached new state ex:may_STOPPED()
Example api:
Additional context For example one of the popular ruby libs AASM has a similar API for check transitions
Example how we've implemented it in our code, but I think it should be in core lib to make client code more clear and useful