Skip to content

The Event class is not fully supported in State.Compound #643

Description

@Dolecor

The documentation section Declaring events states that event can be declared with the Event class "for better IDE support (autocompletion, type checking) or to set a human-readable display name". It seems these advantages can not be used when the Event class is used inside the State.Compound class. When the event = Event(<transition>) form is used inside this class, the event is ignored, and <transition> becomes eventless.

I didn’t find any example in the documentation where events or transitions would be declared using the Event(<transition>) or event = Event(<transition>) forms inside the State.Compound class. However, I also didn’t find any restrictions regarding this.

Let's look at example from the Compound states section with and without Event(...) declaration.

  • The original example:

    from statemachine import State, StateChart
    
    class Journey(StateChart):
        class shire(State.Compound):
            bag_end = State(initial=True)
            green_dragon = State()
            visit_pub = bag_end.to(green_dragon)
        road = State(final=True)
        depart = shire.to(road)
    
  • And the same example, but with events visit_pub and depart declared using Event(...):

    class QuirkyJourney(StateChart):
        class shire(State.Compound):
            bag_end = State(initial=True)
            green_dragon = State()
            visit_pub = Event(bag_end.to(green_dragon))
        road = State(final=True)
        depart = Event(shire.to(road))
    

The following snippet shows that these machines are not identical:

j = Journey()
qj = QuirkyJourney()

print("Journey SM:")
print(f"  Configuration:  {j.configuration}")
print(f"  Enabled events: {j.enabled_events()}")
j._graph().write_png("j.png")

print("QuirkyJourney SM:")
print(f"  Configuration:  {qj.configuration}")
print(f"  Enabled events: {qj.enabled_events()}")
qj._graph().write_png("qj.png")

Output:

Journey SM:
  Configuration:  {Shire, Bag end}
  Enabled events: [BoundEvent('depart', delay=0, internal=False), BoundEvent('visit_pub', delay=0, internal=False)]
QuirkyJourney SM:
  Configuration:  {Shire, Green dragon}
  Enabled events: [BoundEvent('depart', delay=0, internal=False)]

Images:

  • Journey SM:
    Image

  • QuirkyJourney SM:
    Image

As you can see, the qj transitions to the green_dragon state without receiving the visit_pub event.

I checked the given example with python-statemachine 3.0.0, 3.1.0, 3.2.0 and 3.2.1. All have the same behavior.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions