@@ -247,9 +247,7 @@ def _resolve_transition(self, event_data):
247
247
else :
248
248
new_states , enter_partials = {}, []
249
249
250
- for key in scoped_tree :
251
- del scoped_tree [key ]
252
-
250
+ scoped_tree .clear ()
253
251
for new_key , value in new_states .items ():
254
252
scoped_tree [new_key ] = value
255
253
break
@@ -370,7 +368,12 @@ def add_model(self, model, initial=None):
370
368
initial_name = getattr (models [0 ], self .model_attribute )
371
369
if hasattr (initial_name , 'name' ):
372
370
initial_name = initial_name .name
373
- initial_states = self ._resolve_initial (models , initial_name .split (self .state_cls .separator ))
371
+ # initial states set by add_model or machine might contain initial states themselves.
372
+ if isinstance (initial_name , string_types ):
373
+ initial_states = self ._resolve_initial (models , initial_name .split (self .state_cls .separator ))
374
+ # when initial is set to a (parallel) state, we accept it as it is
375
+ else :
376
+ initial_states = initial_name
374
377
for mod in models :
375
378
self .set_state (initial_states , mod )
376
379
if hasattr (mod , 'to' ):
@@ -380,6 +383,15 @@ def add_model(self, model, initial=None):
380
383
to_func = partial (self .to_state , mod )
381
384
setattr (mod , 'to' , to_func )
382
385
386
+ @property
387
+ def initial (self ):
388
+ """ Return the initial state. """
389
+ return self ._initial
390
+
391
+ @initial .setter
392
+ def initial (self , value ):
393
+ self ._initial = self ._recursive_initial (value )
394
+
383
395
def add_ordered_transitions (self , states = None , trigger = 'next_state' ,
384
396
loop = True , loop_includes_initial = True ,
385
397
conditions = None , unless = None , before = None ,
@@ -876,6 +888,24 @@ def _init_state(self, state):
876
888
for substate in self .states .values ():
877
889
self ._init_state (substate )
878
890
891
+ def _recursive_initial (self , value ):
892
+ if isinstance (value , string_types ):
893
+ path = value .split (self .state_cls .separator , 1 )
894
+ if len (path ) > 1 :
895
+ state_name , suffix = path
896
+ # make sure the passed state has been created already
897
+ _super (HierarchicalMachine , self .__class__ ).initial .fset (self , state_name )
898
+ with self (state_name ):
899
+ self .initial = suffix
900
+ self ._initial = state_name + self .state_cls .separator + self ._initial
901
+ else :
902
+ _super (HierarchicalMachine , self .__class__ ).initial .fset (self , value )
903
+ elif isinstance (value , (list , tuple )):
904
+ return [self ._recursive_initial (v ) for v in value ]
905
+ else :
906
+ _super (HierarchicalMachine , self .__class__ ).initial .fset (self , value )
907
+ return self ._initial [0 ] if isinstance (self ._initial , list ) and len (self ._initial ) == 1 else self ._initial
908
+
879
909
def _resolve_initial (self , models , state_name_path , prefix = []):
880
910
if state_name_path :
881
911
state_name = state_name_path .pop (0 )
0 commit comments