StateMachineMetaclass._unpack_builders_callbacks flattens state._callbacks from every state
into a single dict and setattrs the result on the class. The dict is keyed by the callback
name alone, with no reference to the owning state, so two sibling regions that declare the same
callback name collide and the last one silently wins.
Measured on develop:
log = []
class P(StateChart):
class par(State.Parallel):
class r1(State.Compound):
a1 = State(initial=True)
b1 = State(final=True)
@a1.to(b1)
def go(self):
log.append("r1")
class r2(State.Compound):
a2 = State(initial=True)
b2 = State(final=True)
@a2.to(b2)
def go(self):
log.append("r2")
sm = P()
sm.send("go")
log # ['r2'] -- r1's body never runs
Both regions do transition; only r1.go's body is discarded. The same collision already happens
with plain callbacks of the same name in sibling regions, so this is not new, but #645 makes the
decorator form reachable inside a nested body and therefore much easier to hit.
The mangled name needs to be namespaced by the owning state, or the collision detected and
raised as InvalidDefinition. Namespacing falls out naturally from #657,
where the metaclass reads each body with the owning state in hand.
When fixing: revisit docs/actions.md / docs/statecharts.md for anything that implies
sibling regions are independent namespaces, and add an entry to the open release notes.
StateMachineMetaclass._unpack_builders_callbacksflattensstate._callbacksfrom every stateinto a single dict and
setattrs the result on the class. The dict is keyed by the callbackname alone, with no reference to the owning state, so two sibling regions that declare the same
callback name collide and the last one silently wins.
Measured on
develop:Both regions do transition; only
r1.go's body is discarded. The same collision already happenswith plain callbacks of the same name in sibling regions, so this is not new, but #645 makes the
decorator form reachable inside a nested body and therefore much easier to hit.
The mangled name needs to be namespaced by the owning state, or the collision detected and
raised as
InvalidDefinition. Namespacing falls out naturally from #657,where the metaclass reads each body with the owning state in hand.
When fixing: revisit
docs/actions.md/docs/statecharts.mdfor anything that impliessibling regions are independent namespaces, and add an entry to the open release notes.