11# coding: utf-8
22import sys
33import warnings
4+ from collections import OrderedDict
45from typing import Any
56from typing import Dict
67from typing import List
@@ -30,7 +31,9 @@ def __init__(self, model=None, state_field="state", start_value=None):
3031 self .state_field = state_field
3132 self .start_value = start_value
3233
33- initial_transition = Transition (None , None , event = "__initial__" )
34+ initial_transition = Transition (
35+ None , self ._get_initial_state (), event = "__initial__"
36+ )
3437 self ._setup (initial_transition )
3538 self ._activate_initial_state (initial_transition )
3639
@@ -42,21 +45,19 @@ def __repr__(self):
4245 self .current_state .id if self .current_state else None ,
4346 )
4447
45- def _activate_initial_state (self , initial_transition ):
46-
48+ def _get_initial_state (self ):
4749 current_state_value = (
4850 self .start_value if self .start_value else self .initial_state .value
4951 )
50- if self .current_state_value is None :
51-
52- try :
53- initial_state = self .states_map [current_state_value ]
54- except KeyError :
55- raise InvalidStateValue (current_state_value )
52+ try :
53+ return self .states_map [current_state_value ]
54+ except KeyError :
55+ raise InvalidStateValue (current_state_value )
5656
57+ def _activate_initial_state (self , initial_transition ):
58+ if self .current_state_value is None :
5759 # send an one-time event `__initial__` to enter the current state.
5860 # current_state = self.current_state
59- initial_transition .target = initial_state
6061 initial_transition .before .clear ()
6162 initial_transition .on .clear ()
6263 initial_transition .after .clear ()
@@ -96,8 +97,22 @@ def _setup(self, initial_transition):
9697 model = ObjectConfig (self .model , skip_attrs = {self .state_field })
9798 default_resolver = resolver_factory (machine , model )
9899
99- initial_transition ._setup (default_resolver )
100- self ._visit_states_and_transitions (lambda x : x ._setup (default_resolver ))
100+ # clone states and transitions to avoid sharing callbacks references between instances
101+ states = []
102+ self .states_map = OrderedDict ()
103+ for state in self .states :
104+ new_state = state .clone ()
105+ new_state ._setup (self , default_resolver )
106+ states .append (new_state )
107+ self .states_map [new_state .value ] = new_state
108+
109+ self .states = states
110+
111+ for state in self .states :
112+ for transition in state .transitions :
113+ transition ._setup (self , default_resolver )
114+
115+ initial_transition ._setup (self , default_resolver )
101116 self .add_observer (machine , model )
102117
103118 def add_observer (self , * observers ):
0 commit comments