@@ -287,7 +287,32 @@ def allowed_events(self):
287287 """List of the current allowed events."""
288288 return [getattr (self , event ) for event in self .current_state .transitions .unique_events ]
289289
290- async def _process (self , trigger ):
290+ async def _trigger (self , trigger_data : TriggerData ):
291+ event_data = None
292+ await self ._ensure_is_initialized ()
293+
294+ state = self .current_state
295+ for transition in state .transitions :
296+ if not transition .match (trigger_data .event ):
297+ continue
298+
299+ event_data = EventData (trigger_data = trigger_data , transition = transition )
300+ args , kwargs = event_data .args , event_data .extended_kwargs
301+ await self ._get_callbacks (transition .validators .key ).call (* args , ** kwargs )
302+ if not await self ._get_callbacks (transition .cond .key ).all (* args , ** kwargs ):
303+ continue
304+
305+ result = await self ._activate (event_data )
306+ event_data .result = result
307+ event_data .executed = True
308+ break
309+ else :
310+ if not self .allow_event_without_transition :
311+ raise TransitionNotAllowed (trigger_data .event , state )
312+
313+ return event_data .result if event_data else None
314+
315+ async def _process (self , trigger_data : TriggerData ):
291316 """Process event triggers.
292317
293318 The simplest implementation is the non-RTC (synchronous),
@@ -308,11 +333,11 @@ async def _process(self, trigger):
308333 """
309334 if not self .__rtc :
310335 # The machine is in "synchronous" mode
311- return await trigger ( )
336+ return await self . _trigger ( trigger_data )
312337
313338 # The machine is in "queued" mode
314339 # Add the trigger to queue and start processing in a loop.
315- self ._external_queue .append (trigger )
340+ self ._external_queue .append (trigger_data )
316341
317342 # We make sure that only the first event enters the processing critical section,
318343 # next events will only be put on the queue and processed by the same loop.
@@ -332,9 +357,9 @@ async def _processing_loop(self):
332357 first_result = sentinel
333358 try :
334359 while self ._external_queue :
335- trigger = self ._external_queue .popleft ()
360+ trigger_data = self ._external_queue .popleft ()
336361 try :
337- result = await trigger ( )
362+ result = await self . _trigger ( trigger_data )
338363 if first_result is sentinel :
339364 first_result = result
340365 except Exception :
@@ -347,32 +372,24 @@ async def _processing_loop(self):
347372 return first_result if first_result is not sentinel else None
348373
349374 async def _activate (self , event_data : EventData ):
375+ args , kwargs = event_data .args , event_data .extended_kwargs
350376 transition = event_data .transition
351377 source = event_data .state
352378 target = transition .target
353379
354- result = await self ._get_callbacks (transition .before .key ).call (
355- * event_data .args , ** event_data .extended_kwargs
356- )
380+ result = await self ._get_callbacks (transition .before .key ).call (* args , ** kwargs )
357381 if source is not None and not transition .internal :
358- await self ._get_callbacks (source .exit .key ).call (
359- * event_data .args , ** event_data .extended_kwargs
360- )
382+ await self ._get_callbacks (source .exit .key ).call (* args , ** kwargs )
361383
362- result += await self ._get_callbacks (transition .on .key ).call (
363- * event_data .args , ** event_data .extended_kwargs
364- )
384+ result += await self ._get_callbacks (transition .on .key ).call (* args , ** kwargs )
365385
366386 self .current_state = target
367387 event_data .state = target
388+ kwargs ["state" ] = target
368389
369390 if not transition .internal :
370- await self ._get_callbacks (target .enter .key ).call (
371- * event_data .args , ** event_data .extended_kwargs
372- )
373- await self ._get_callbacks (transition .after .key ).call (
374- * event_data .args , ** event_data .extended_kwargs
375- )
391+ await self ._get_callbacks (target .enter .key ).call (* args , ** kwargs )
392+ await self ._get_callbacks (transition .after .key ).call (* args , ** kwargs )
376393
377394 if len (result ) == 0 :
378395 result = None
@@ -392,7 +409,8 @@ def send(self, event: str, *args, **kwargs):
392409 See: :ref:`triggering events`.
393410
394411 """
395- return run_async_from_sync (self .async_send (event , * args , ** kwargs ))
412+ coro = self .async_send (event , * args , ** kwargs )
413+ return run_async_from_sync (coro )
396414
397415 async def async_send (self , event : str , * args , ** kwargs ):
398416 """Send an :ref:`Event` to the state machine.
0 commit comments