o
    ;i                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZmZ d dlmZmZmZmZmZ d dlmZ d dlmZ e jdkrIejZnejjZer]dd	lmZ dd
lmZmZ G dd ded ZG dd deZ ddde!fddZ"ddded ddfddZ#d'ddZ$de%ded dee& ddfddZ'edej(ej)fdded d eej* d!ee% ded fd"d#Z+d$eg ef deg ef fd%d&Z,dS )(    N)TracebackType)TYPE_CHECKINGOptionalSetTypeContextManagerList)Iterator
CollectionCallableAnycast)wraps)contextmanager)         )Deadline)	IServable	IClosablec                   @   s   e Zd ZU dZdZee ed< dZee	 ed< dZ
ee	 ed< dddZdd	d
Zdeee  dee dee ddfddZdeddfddZdS )WrapperaD  Special wrapper for coroutines to wake them up in case of some error.

    Example:

    .. code-block:: python3

        w = Wrapper()

        async def blocking_call():
            with w:
                await asyncio.sleep(10)

        # and somewhere else:
        w.cancel(NoNeedToWaitError('With explanation'))

    N_error	cancelledcancel_failedreturnc                 C   s   t  | _d S N)set_tasksself r    A/home/ubuntu/.local/lib/python3.10/site-packages/grpclib/utils.py__init__.      zWrapper.__init__c                 C   s6   | j d ur| j t }|d u rtd| j| d S )NzCalled not inside a task)r   _current_taskRuntimeErrorr   add)r   taskr    r    r!   	__enter__1   s   
zWrapper.__enter__exc_typeexc_valexc_tbc                 C   s:   t  }|sJ | j| | jd ur|tju| _| jd S r   )r$   r   discardr   asyncioCancelledErrorr   )r   r)   r*   r+   r'   r    r    r!   __exit__;   s   
zWrapper.__exit__errorc                 C   s$   || _ | jD ]}|  qd| _d S )NT)r   r   cancelr   )r   r0   r'   r    r    r!   r1   H   s   


zWrapper.cancelr   N)__name__
__module____qualname____doc__r   r   	Exception__annotations__r   boolr   r"   r(   r   BaseExceptionr   r/   r1   r    r    r    r!   r      s"   
 




r   c                   @   s*   e Zd ZdZeddded fddZdS )DeadlineWrappera{  Deadline wrapper to specify deadline once for any number of awaiting
    method calls.

    Example:

    .. code-block:: python3

        dw = DeadlineWrapper()

        with dw.start(deadline):
            await handle_request()

        # somewhere during request handling:

        async def blocking_call():
            with dw:
                await asyncio.sleep(10)

    deadliner   r   Nc                 #   sZ    |  }|stdd fdd}t }|||}z
d V  W |  d S |  w )NDeadline exceededr   c                      s     td d S )Nr=   )r1   r-   TimeoutErrorr    r   r    r!   callbacki   s   z'DeadlineWrapper.start.<locals>.callbackr2   )time_remainingr-   r>   get_event_loop
call_laterr1   )r   r<   timeoutr?   looptimerr    r   r!   startc   s   
zDeadlineWrapper.start)r3   r4   r5   r6   r   r	   rF   r    r    r    r!   r;   O   s    r;   servicer   r   c                 C   s6   |   }tt|d }|d usJ |d\}}}|S )N/)__mapping__nextitersplit)rG   methodsmethod_name_service_namer    r    r!   _service_namet   s
   rQ   sig_numsignal.Signalsserversr   c              	   C   sD   d}|D ]}z|   W q ty   d}Y qw |r t|  d S d S )NFT)closer%   _second_stage)rR   rT   failserverr    r    r!   _first_stage|   s   rY   c                 C   s   t d|  )N   )
SystemExit)rR   r    r    r!   rV      r#   rV   flagc                 C   s4   |rt td|  d S ttd| | |d d S )NrS   T)rV   r   rY   append)rR   rT   r\   r    r    r!   _exit_handler   s   r^   )rD   signalsrD   r_   c             
   c   s    |rt jdtdd |pt }t|}g }|D ]}||t|| | qzdV  W |D ]}|| q,dS |D ]}|| q8w )a  Utility context-manager to help properly shutdown server in response to
    the OS signals

    By default this context-manager handles ``SIGINT`` and ``SIGTERM`` signals.

    There are two stages:

      1. first received signal closes servers
      2. subsequent signals raise ``SystemExit`` exception

    Example:

    .. code-block:: python3

        async def main(...):
            ...
            with graceful_exit([server]):
                await server.start(host, port)
                print('Serving on {}:{}'.format(host, port))
                await server.wait_closed()
                print('Server closed')

    First stage calls ``server.close()`` and ``await server.wait_closed()``
    should complete successfully without errors. If server wasn't started yet,
    second stage runs to prevent server start.

    Second stage raises ``SystemExit`` exception, but you will receive
    ``asyncio.CancelledError`` in your ``async def main()`` coroutine. You
    can use ``try..finally`` constructs and context-managers to properly handle
    this error.

    This context-manager is designed to work in cooperation with
    :py:func:`python:asyncio.run` function:

    .. code-block:: python3

        if __name__ == '__main__':
            asyncio.run(main())

    :param servers: list of servers
    :param loop: (deprecated) asyncio-compatible event loop
    :param signals: set of the OS signals to handle

    .. note:: Not supported in Windows
    zHThe loop argument is deprecated and scheduled for removal in grpclib 0.5   )
stacklevelN)	warningswarnDeprecationWarningr-   rA   r   add_signal_handlerr^   remove_signal_handler)rT   rD   r_   r\   rR   r    r    r!   graceful_exit   s"   4rg   funcc                    s   t  dtf fdd}|S )Nr   c                      s*   z j W S  ty      _  j  Y S w r   )
__result__AttributeErrorr    rh   r    r!   wrapper   s   
z_cached.<locals>.wrapper)r   r   )rh   rl   r    rk   r!   _cached   s   rm   )rR   rS   r   N)-syssignalr-   rb   typesr   typingr   r   r   r   r   r   r	   r
   r   r   r   	functoolsr   
contextlibr   version_infocurrent_taskr$   Taskmetadatar   _typingr   r   r   r;   strrQ   rY   rV   intr9   r^   SIGINTSIGTERMAbstractEventLooprg   rm   r    r    r    r!   <module>   s`     
7%



&D