o
    NK&h9                     @  s  d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZmZmZmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ d dlmZ G dd deZej j!ej"j!ej#j!ej$j!ej%j!fej&j!ej'j!ej(j!ej)j!ej*j!ej+j!ej,j!ej-j!ej.j!ej/j!ej0j!ej1j!ej2j!ej3j!ej4j!fej5j!ej6j!ej7j!hdZ8dZ9dd Z:G dd deZ;eG dd dZ<G dd deZ=G dd deZ>dS )    )annotationsN)deque)	dataclass)Enum)isawaitable)AnyOptionalUnioncast)
BaseRouterRoute
RouteGroup)NotFound)path_to_parts)InvalidSignal)error_loggerlogger)SignalHandlerc                   @  sl   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdS )Eventz Event names for the SignalRouterzserver.exception.reportzserver.init.afterzserver.init.beforezserver.shutdown.afterzserver.shutdown.beforezhttp.lifecycle.beginzhttp.lifecycle.completezhttp.lifecycle.exceptionzhttp.lifecycle.handlezhttp.lifecycle.read_bodyzhttp.lifecycle.read_headzhttp.lifecycle.requestzhttp.lifecycle.responsezhttp.routing.afterzhttp.routing.beforezhttp.handler.afterzhttp.handler.beforezhttp.lifecycle.sendzhttp.middleware.afterzhttp.middleware.beforezwebsocket.handler.afterzwebsocket.handler.beforezwebsocket.handler.exceptionN)__name__
__module____qualname____doc__SERVER_EXCEPTION_REPORTSERVER_INIT_AFTERSERVER_INIT_BEFORESERVER_SHUTDOWN_AFTERSERVER_SHUTDOWN_BEFOREHTTP_LIFECYCLE_BEGINHTTP_LIFECYCLE_COMPLETEHTTP_LIFECYCLE_EXCEPTIONHTTP_LIFECYCLE_HANDLEHTTP_LIFECYCLE_READ_BODYHTTP_LIFECYCLE_READ_HEADHTTP_LIFECYCLE_REQUESTHTTP_LIFECYCLE_RESPONSEHTTP_ROUTING_AFTERHTTP_ROUTING_BEFOREHTTP_HANDLER_AFTERHTTP_HANDLER_BEFOREHTTP_LIFECYCLE_SENDHTTP_MIDDLEWARE_AFTERHTTP_MIDDLEWARE_BEFOREWEBSOCKET_HANDLER_AFTERWEBSOCKET_HANDLER_BEFOREWEBSOCKET_HANDLER_EXCEPTION r0   r0   @/var/www/html/venv/lib/python3.10/site-packages/sanic/signals.pyr      s2    r   )serverhttp	websocketz__generic__.__signal__.%sc                   C  s   d S Nr0   r0   r0   r0   r1   _blankS   s    r6   c                   @     e Zd ZdZdS )Signalz6A `Route` that is used to dispatch signals to handlersNr   r   r   r   r0   r0   r0   r1   r8   V       r8   c                   @  sb   e Zd ZU dZded< ded< dZded< dZd	ed
< dZded< dZded< dd Z	dd Z
dS )SignalWaiterz3A record representing a future waiting for a signalr8   signalstrevent_definition triggerNOptional[dict[str, str]]requirementsTbool	exclusivezOptional[asyncio.Future]futurec              	     sV   t  }| | _| jjj|  z| jI dH W | jjj|  S | jjj|  w )zoBlock until the signal is next dispatched.

        Return the context of the signal dispatch, if any.
        N)	asyncioget_running_loopcreate_futurerE   r<   ctxwaitersappendremove)selfloopr0   r0   r1   waitf   s   
$zSignalWaiter.waitc                 C  s:   |d u r| j  p|d u o| j p|| jko| jp|| jkS r5   )rD   rB   r@   r>   )rM   event	conditionr0   r0   r1   matchess   s   zSignalWaiter.matches)r   r   r   r   __annotations__r@   rB   rD   rE   rO   rR   r0   r0   r0   r1   r;   Z   s   
 r;   c                   @  r7   )SignalGroupz;A `RouteGroup` that is used to dispatch signals to handlersNr9   r0   r0   r0   r1   rT   {   r:   rT   c                      s   e Zd ZdZd8 fddZed9d	d
Z	d:d;ddZ				d<d=ddZddddddd>ddZ			d?d@d!d"Z
dAd$d%Z		d?d&d'dB fd-d.ZdCdD fd1d2ZdAd3d4ZdEd6d7Z  ZS )FSignalRouterz;A `BaseRouter` that is used to dispatch signals to handlersreturnNonec                   s&   t  jdttdd d| _d | j_d S )N.T)	delimiterroute_classgroup_classstacking)super__init__r8   rT   allow_fail_builtinrI   rN   )rM   	__class__r0   r1   r^      s   zSignalRouter.__init__rP   Union[str, Enum]r=   c                 C  s(   t | tr
t| j} d| vrt|  } | S )zEnsure event strings in proper format

        Args:
            event (str): event string

        Returns:
            str: formatted event string
        rX   )
isinstancer   r=   valueGENERIC_SIGNAL_FORMAT)rP   r0   r0   r1   format_event   s
   


zSignalRouter.format_eventNrQ   rA   c                   s   |  |}|pi }z| jd| | j| i i d|d\} W n ty=   d}|g}|r5|d7 }|| t|t| w  d }|sP fdd|j D }|d	d
 |D |fS )a  Get the handlers for a signal

        Args:
            event (str): The event to get the handlers for
            condition (Optional[Dict[str, str]], optional): A dictionary of conditions to match against the handlers. Defaults to `None`.

        Returns:
            Tuple[SignalGroup, List[SignalHandler], Dict[str, Any]]: A tuple of the `SignalGroup` that matched, a list of the handlers that matched, and a dictionary of the params that matched

        Raises:
            NotFound: If no handlers are found
        rX   )
__params____matches__extrazCould not find signal %sz with %srg   c                   s    i | ]\}}|j  d  | qS )rh   )name).0idxparamparam_basketr0   r1   
<dictcomp>   s    z$SignalRouter.get.<locals>.<dictcomp>c                 S  s   g | ]}|j qS r0   )handler)rl   router0   r0   r1   
<listcomp>   s    z$SignalRouter.get.<locals>.<listcomp>)rf   
find_routeDEFAULT_METHODr   rK   tupleparamsitems)rM   rP   rQ   rj   groupmessagetermsrx   r0   ro   r1   get   s0   



zSignalRouter.getTFcontextOptional[dict[str, Any]]fail_not_foundrC   reverser   c              
     s  |  |}z| j||d\}}}W n: tyL }	 z.|ddd tv }
|r-|
r+| jr-|	| jjjrA| jjj	j
dkrAtt|	 W Y d }	~	d S d }	~	ww |rT|| |dd  |j}|sf|d d d }zd|D ]}|jjD ]}|||r|jt| qoqi|D ]D}|jj}|d u r|jjdu s|d u r|r||kr|jjs||jjkr|jdi |}t|r|I d H }|r|  W S q|r|  W S qW d S  ty }	 z.| jjjr| jjj	j
dkrt|	 |tj j!kr| j"tj j!d|	id	I d H  t#|	d
d |	d }	~	ww )N)rQ   rX      r   __trigger__F	exception)r~   __dispatched__Tr0   )$rf   r}   r   splitRESERVED_NAMESPACESr_   rI   appdebugstate	verbosityr   warningr=   updatepoproutesrJ   rR   rE   
set_resultdictrj   rB   rD   r@   
definitionrr   r   	Exceptionr   r   r   rd   dispatchsetattr)rM   rP   r~   rQ   r   r   rz   handlersrx   eis_reservedsignalsr<   waiterrB   maybe_coroutineretvalr0   r0   r1   	_dispatch   sp   
	




zSignalRouter._dispatch)r~   rQ   r   inliner   r   Union[asyncio.Task, Any]c          	        sl   |  |}| j||||o||d}tjd| ddid |r%|I dH S t |}tdI dH  |S )a  Dispatch a signal to all handlers that match the event

        Args:
            event (str): The event to dispatch
            context (Optional[Dict[str, Any]], optional): A dictionary of context to pass to the handlers. Defaults to `None`.
            condition (Optional[Dict[str, str]], optional): A dictionary of conditions to match against the handlers. Defaults to `None`.
            fail_not_found (bool, optional): Whether to raise an exception if no handlers are found. Defaults to `True`.
            inline (bool, optional): Whether to run the handlers inline. An inline run means it will return the value of the signal handler. When `False` (which is the default) the signal handler will run in a background task. Defaults to `False`.
            reverse (bool, optional): Whether to run the handlers in reverse order. Defaults to `False`.

        Returns:
            Union[asyncio.Task, Any]: If `inline` is `True` then the return value of the signal handler will be returned. If `inline` is `False` then an `asyncio.Task` will be returned.

        Raises:
            RuntimeError: If the signal is dispatched outside of an event loop
        )r~   rQ   r   r   zDispatching signal: r   r   ri   Nr   )rf   r   r   r   rF   rG   create_tasksleep)	rM   rP   r~   rQ   r   r   r   r   taskr0   r0   r1   r   	  s   

zSignalRouter.dispatchrD   Optional[SignalWaiter]c           	      C  s\   |  |}| |\}}}tt| j|}|sd S |dr#|s#d}t||||t|dS )Nz.**)r<   r>   r@   rB   rD   )	rf   _get_event_partsr
   r8   
name_indexr}   endswithr;   rC   )	rM   rP   rQ   rD   r>   rk   r@   _r<   r0   r0   r1   
get_waiter5  s   
zSignalRouter.get_waitertuple[str, str, str]c                 C  sr   |  |}|d dr!dg |d d d}| |d }n|}d}|s4dg |d d d}|||fS )N   <rX   r   r   r?   z<__trigger__>)_build_event_parts
startswithjoin_clean_trigger)rM   rP   partsrk   r@   r0   r0   r1   r   K  s   

zSignalRouter._get_event_partsr   )priorityrr   r   r   intr8   c                  sZ   |  |}| |\}}}	t j|	||d|d}
||
j_||
j_||
j_||
j_	t
t|
S )NT)rk   rK   r   )rf   r   r]   addrI   rD   r@   r   rj   rB   r
   r8   )rM   rr   rP   rQ   rD   r   r>   rk   r@   event_stringr<   r`   r0   r1   r   Y  s   
	
zSignalRouter.add
do_compiledo_optimizec                   sZ   |  td zt | j_W n ty   tdw | jD ]}t |j_	qt
 j||dS )a  Finalize the router and compile the routes

        Args:
            do_compile (bool, optional): Whether to compile the routes. Defaults to `True`.
            do_optimize (bool, optional): Whether to optimize the routes. Defaults to `False`.

        Returns:
            SignalRouter: The router

        Raises:
            RuntimeError: If the router is finalized outside of an event loop
        zsanic.__signal__.__init__z-Cannot finalize signals outside of event loop)r   r   )r   r6   rF   rG   rI   rN   RuntimeErrorr   r   rJ   r]   finalize)rM   r   r   r<   r`   r0   r1   r   t  s   
zSignalRouter.finalizec                 C  s   t || j}t|dks|d ds|d dr td| |d tv rB|t|d  vrB|d dr<|d dsBtd| |S )	N   r   r   r   zInvalid signal event: %sr   >z(Cannot declare reserved signal event: %s)r   rY   lenr   r   r   r   )rM   rP   r   r0   r0   r1   r     s"   zSignalRouter._build_event_partsr@   c                 C  s&   |dd }d|v r| d\}}|S )Nr   r   :)r   )rM   r@   r   r0   r0   r1   r     s   zSignalRouter._clean_trigger)rV   rW   )rP   rb   rV   r=   r5   )rP   rb   rQ   rA   )NNTF)rP   r=   r~   r   rQ   rA   r   rC   r   rC   rV   r   )rP   rb   r~   r   rQ   rA   r   rC   r   rC   r   rC   rV   r   )NT)rP   rb   rQ   r   rD   rC   rV   r   )rP   r=   rV   r   )rr   r   rP   rb   rQ   r   rD   rC   r   r   rV   r8   )TF)r   rC   r   rC   )r@   r=   rV   r=   )r   r   r   r   r^   staticmethodrf   r}   r   r   r   r   r   r   r   r   __classcell__r0   r0   r`   r1   rU      s<    
4@/

rU   )?
__future__r   rF   collectionsr   dataclassesr   enumr   inspectr   typingr   r   r	   r
   sanic_routingr   r   r   sanic_routing.exceptionsr   sanic_routing.utilsr   sanic.exceptionsr   	sanic.logr   r   sanic.models.handler_typesr   r   r   rd   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r   re   r6   r8   r;   rT   rU   r0   r0   r0   r1   <module>   s`      