o
    NK&h                     @  s   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 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dZdS )    )annotations)	Coroutine)Enum)AnyCallableOptionalUnion)	SanicMeta)FutureSignal)SignalHandler)EventSignal)HashableDictc                   @  sZ   e Zd Zd%ddZd&dd	Zd
dd
ddd'ddZ		
d(d)ddZd*d d!Zd+d#d$ZdS ),SignalMixinreturnNonec                 O  s   t  | _d S N)set_future_signals)selfargskwargs r   G/var/www/html/venv/lib/python3.10/site-packages/sanic/mixins/signals.py__init__   s   zSignalMixin.__init__signalr
   r   c                 C     t r   NotImplementedError)r   r   r   r   r   _apply_signal      zSignalMixin._apply_signalTNr   )apply	condition	exclusivepriorityeventUnion[str, Enum]r!   boolr"   Optional[dict[str, Any]]r#   r$   int(Callable[[SignalHandler], SignalHandler]c                  s4   t |tr
t|jn|d fdd}|S )a  
        For creating a signal handler, used similar to a route handler:

        .. code-block:: python

            @app.signal("foo.bar.<thing>")
            async def signal_handler(thing, **kwargs):
                print(f"[signal_handler] {thing=}", kwargs)

        :param event: Representation of the event in ``one.two.three`` form
        :type event: str
        :param apply: For lazy evaluation, defaults to ``True``
        :type apply: bool, optional
        :param condition: For use with the ``condition`` argument in dispatch
            filtering, defaults to ``None``
        :param exclusive: When ``True``, the signal can only be dispatched
            when the condition has been met. When ``False``, the signal can
            be dispatched either with or without it. *THIS IS INAPPLICABLE TO
            BLUEPRINT SIGNALS. THEY ARE ALWAYS NON-EXCLUSIVE*, defaults
            to ``True``
        :type condition: Dict[str, Any], optional
        handlerr   c                   s6   t | tpi }j|  r| | S r   )r
   r   r   addr   )r+   future_signalr!   r"   event_valuer#   r$   r   r   r   	decorator6   s   

z%SignalMixin.signal.<locals>.decoratorN)r+   r   )
isinstancer   strvalue)r   r%   r!   r"   r#   r$   r0   r   r.   r   r      s   zSignalMixin.signalr+   Optional[Callable[..., Any]]Callable[..., Any]c                 C  s(   |sdd }|}| j |||d| |S )a9  Registers a signal handler for a specific event.

        Args:
            handler (Optional[Callable[..., Any]]): The function to be called
                when the event occurs. Defaults to a noop if not provided.
            event (str): The name of the event to listen for.
            condition (Optional[Dict[str, Any]]): Optional condition to filter
                the event triggering. Defaults to `None`.
            exclusive (bool): Whether or not the handler is exclusive. When
                `True`, the signal can only be dispatched when the
                `condition` has been met. *This is inapplicable to blueprint
                signals, which are **ALWAYS** non-exclusive.* Defaults
                to `True`.

        Returns:
            Callable[..., Any]: The handler that was registered.
        c                    s   d S r   r   )contextr   r   r   noopa   s    z$SignalMixin.add_signal.<locals>.noop)r%   r"   r#   )r   )r   r+   r%   r"   r#   r7   r   r   r   
add_signalG   s   zSignalMixin.add_signalr2   c                 C  r   r   r   )r   r%   r   r   r   r%   i   r    zSignalMixin.event=Callable[[SignalMixin, Exception], Coroutine[Any, Any, None]]c                   s$   d fdd} tj| dS )a  Register an exception handler for logging or processing.

        This method allows the registration of a custom exception handler to
        catch and process exceptions that occur in the application. Unlike a
        typical exception handler that might modify the response to the client,
        this is intended to capture exceptions for logging or other internal
        processing, such as sending them to an error reporting utility.

        Args:
            handler (Callable): A coroutine function that takes the application
                instance and the exception as arguments. It will be called when
                an exception occurs within the application's lifecycle.

        Example:
            ```python
            app = Sanic("TestApp")

            @app.catch_exception
            async def report_exception(app: Sanic, exception: Exception):
                logging.error(f"An exception occurred: {exception}")

                # Send to an error reporting service
                await error_service.report(exception)

            # Any unhandled exceptions within the application will now be
            # logged and reported to the error service.
            ```
        	exception	Exceptionc                   s    | I d H  d S r   r   )r:   r+   r   r   r   signal_handler   s   z3SignalMixin.catch_exception.<locals>.signal_handlerN)r:   r;   )r   r   SERVER_EXCEPTION_REPORT)r   r+   r=   r   r<   r   catch_exceptionl   s   !zSignalMixin.catch_exception)r   r   )r   r
   r   r   )r%   r&   r!   r'   r"   r(   r#   r'   r$   r)   r   r*   )NT)
r+   r4   r%   r&   r"   r(   r#   r'   r   r5   )r%   r2   )r+   r9   r   r   )	__name__
__module____qualname__r   r   r   r8   r%   r?   r   r   r   r   r      s    

6
"r   )	metaclassN)
__future__r   collections.abcr   enumr   typingr   r   r   r   sanic.base.metar	   sanic.models.futuresr
   sanic.models.handler_typesr   sanic.signalsr   r   sanic.typesr   r   r   r   r   r   <module>   s    