Skip to content

Event(delay=..., internal=...) are dropped when the event is declared on a class body #647

Description

@fgmacedo

Event(..., delay=...) and Event(..., internal=...) are accepted at declaration time and then
discarded, so the resulting event has delay=0 and internal=False.

Reproduction

from statemachine import Event, State, StateChart

class Beacon(StateChart):
    dark = State(initial=True)
    lit = State(final=True)

    light = Event(dark.to(lit), delay=500, internal=True)

print(Beacon.light.delay)     # 0     , expected 500
print(Beacon.light.internal)  # False , expected True

sm.light() fires immediately instead of after 500 ms, and goes to the external queue instead of
the internal one.

Cause

StateMachineMetaclass.add_from_attributes rebuilds the declared event to give it the real id,
and the new instance is constructed without the two fields:

new_event = Event(
    transitions=value._transitions,
    id=event_id,
    name=value.name,
)

delay and internal are declared on Event and honored everywhere downstream
(Event.put reads self.internal, the delayed-event machinery reads delay); they are simply
lost in this one rebuild.

Why the existing test does not catch it

tests/test_statechart_delayed.py::TestDelayedEvents::test_delayed_event_on_event_definition
declares light = Event(dark.to(lit), delay=50) but then triggers the machine with an event
object it builds itself:

BoundEvent(id="light", delay=50, _sm=sm)

so it never reads the declared BeaconsOfGondor.light and passes regardless of what the
metaclass did with delay. A regression test for this issue should assert on the declared
event (SM.light.delay) and drive the machine through it.

Scope

Reproduced on the current develop. Affects the top-level declaration form; the nested
(State.Compound) form drops the two fields as well, for the same reason.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions