U
    	f=                     @  s  d dl mZ d dlZd dlZd dlmZmZmZ d dlm	Z	m
Z
mZmZ d dlmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZ d	d
lmZ d	dlm Z m!Z!m"Z" d	dl#m$Z$ d	dl%m&Z&m'Z' d	dl(m)Z) d	dl*m+Z+ ej,dkr
d dlm-Z-m.Z. nd dl/m-Z-m.Z. edZ0edddZ1e-dZ2ddddddZ3ddddddZ4G dd  d ee1 eZ5G d!d" d"e+Z6G d#d$ d$Z7ed0d&d'd(d)d*d+Z8d,d-d.d/Z9dS )1    )annotationsN)	AwaitableCallable	Generator)FIRST_COMPLETEDFutureThreadPoolExecutorwait)AbstractContextManagercontextmanager)isawaitable)TracebackType)AnyAsyncContextManagerContextManagerGenericIterableTypeVarcastoverload   )
_eventloop)get_async_backendget_cancelled_exc_classthreadlocals)Event)CancelScopecreate_task_group)AsyncBackend)
TaskStatus)      )TypeVarTupleUnpackT_RetvalT_coT)	covariantPosArgsT1Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]]Unpack[PosArgsT]funcargsreturnc                 G  s@   zt j}t j}W n tk
r.   tddY nX |j| ||dS )z
    Call a coroutine function from a worker thread.

    :param func: a coroutine function
    :param args: positional arguments for the callable
    :return: the return value of the coroutine function

    9This function can only be run from an AnyIO worker threadNtoken)r   current_async_backendcurrent_tokenAttributeErrorRuntimeErrorrun_async_from_threadr+   r,   async_backendr0    r8   T/var/www/html/apigroqsegura/apigroq/lib/python3.8/site-packages/anyio/from_thread.pyrun&   s    
r:   &Callable[[Unpack[PosArgsT]], T_Retval]c                 G  s@   zt j}t j}W n tk
r.   tddY nX |j| ||dS )z
    Call a function in the event loop thread from a worker thread.

    :param func: a callable
    :param args: positional arguments for the callable
    :return: the return value of the callable

    r.   Nr/   )r   r1   r2   r3   r4   run_sync_from_threadr6   r8   r8   r9   run_sync<   s    
r=   c                   @  sr   e Zd ZU ded< ded< ded< dZded	< d
ddddZddddZddddZdddddddZdS )_BlockingAsyncContextManagerzFuture[T_co]_enter_futurezFuture[bool | None]_exit_futurer   _exit_event)NNNzMtuple[type[BaseException] | None, BaseException | None, TracebackType | None]_exit_exc_infoAsyncContextManager[T_co]BlockingPortal)async_cmportalc                 C  s   || _ || _d S N)	_async_cm_portal)selfrE   rF   r8   r8   r9   __init__Z   s    z%_BlockingAsyncContextManager.__init__bool | Noner-   c              
     s   zt  | _| j I d H }W n0 tk
rL } z| j|  W 5 d }~X Y nX | j| d z| j
 I d H  W 5 | jj| j	 I d H }|  S X  rG   )r   rA   rH   
__aenter__BaseExceptionr?   set_exception
set_result	__aexit__rB   r	   )rJ   valueexcresultr8   r8   r9   run_async_cm^   s    z)_BlockingAsyncContextManager.run_async_cmr%   c                 C  s"   t  | _| j| j| _| j S rG   )r   r?   rI   start_task_soonrV   r@   rU   rJ   r8   r8   r9   	__enter__u   s    z&_BlockingAsyncContextManager.__enter__type[BaseException] | NoneBaseException | NoneTracebackType | None)&_BlockingAsyncContextManager__exc_type'_BlockingAsyncContextManager__exc_value'_BlockingAsyncContextManager__tracebackr-   c                 C  s&   |||f| _ | j| jj | j S rG   )rB   rI   callrA   setr@   rU   )rJ   r]   r^   r_   r8   r8   r9   __exit__z   s    z%_BlockingAsyncContextManager.__exit__N)	__name__
__module____qualname____annotations__rB   rK   rV   rY   rb   r8   r8   r8   r9   r>   R   s   

r>   c                   @  s,   e Zd ZddddZddddd	d
ZdS )_BlockingPortalTaskStatusr   futurec                 C  s
   || _ d S rG   )_future)rJ   ri   r8   r8   r9   rK      s    z"_BlockingPortalTaskStatus.__init__NobjectNone)rS   r-   c                 C  s   | j | d S rG   )rj   rQ   )rJ   rS   r8   r8   r9   started   s    z!_BlockingPortalTaskStatus.started)N)rc   rd   re   rK   rm   r8   r8   r8   r9   rg      s   rg   c                   @  sh  e Zd ZdZd dddZddddZd ddd	Zd
ddddddZddddZddddZ	d>dddddZ
dddddddd Zdddd!ddd"d#d$Zed%d&d'd(d)d*Zed+d&d'd(d,d*Zdd&d'd(d-d*Zed.d/d%d&d!dd0d1d2Zed.d/d+d&d!dd0d3d2Zd.d/dd&d!dd0d4d2Zd.d/d5d!d!d6d0d7d8Zd9d:d;d<d=Zd.S )?rD   zLAn object that lets external threads run code in an asynchronous event loop.rM   c                 C  s
   t   S rG   )r   create_blocking_portal)clsr8   r8   r9   __new__   s    zBlockingPortal.__new__rl   c                 C  s&   t  | _t | _t | _t | _d S rG   )		threading	get_ident_event_loop_thread_idr   _stop_eventr   _task_groupr   _cancelled_exc_classrX   r8   r8   r9   rK      s    
zBlockingPortal.__init__c                   s   | j  I d H  | S rG   )ru   rN   rX   r8   r8   r9   rN      s    zBlockingPortal.__aenter__rZ   r[   r\   rL   )exc_typeexc_valexc_tbr-   c                   s$   |   I d H  | j|||I d H S rG   )stopru   rR   )rJ   rw   rx   ry   r8   r8   r9   rR      s    zBlockingPortal.__aexit__c                 C  s,   | j d krtd| j t kr(tdd S )NzThis portal is not runningz7This method cannot be called from the event loop thread)rs   r4   rq   rr   rX   r8   r8   r9   _check_running   s    
zBlockingPortal._check_runningc                   s   | j  I dH  dS )z#Sleep until :meth:`stop` is called.N)rt   r	   rX   r8   r8   r9   sleep_until_stopped   s    z"BlockingPortal.sleep_until_stoppedFbool)cancel_remainingr-   c                   s$   d| _ | j  |r | jj  dS )a.  
        Signal the portal to shut down.

        This marks the portal as no longer accepting new calls and exits from
        :meth:`sleep_until_stopped`.

        :param cancel_remaining: ``True`` to cancel all the remaining tasks, ``False``
            to let them finish before returning

        N)rs   rt   ra   ru   cancel_scopecancel)rJ   r~   r8   r8   r9   rz      s    
zBlockingPortal.stopz<Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval]ztuple[Unpack[PosArgsT]]zdict[str, Any]Future[T_Retval])r+   r,   kwargsri   r-   c           	   
     s   ddd fdd}zzT|||}t |rft , | rF   n
|| |I d H }W 5 Q R X n|}W nd jk
r   |  |  Y nR tk
r } z"| s|| t	|t
s W 5 d }~X Y nX | s|| W 5 d  X d S )Nr   rl   )fr-   c                   s*   |   r&jd t fkr& j d S rG   )	cancelledrs   rq   rr   r`   r   )r   scoperJ   r8   r9   callback   s
    z+BlockingPortal._call_func.<locals>.callback)r   r   r   r   add_done_callbackrv   set_running_or_notify_cancelrO   rP   
isinstance	ExceptionrQ   )	rJ   r+   r,   r   ri   r   Zretval_or_awaitableZretvalrT   r8   r   r9   
_call_func   s*    




zBlockingPortal._call_funcrk   )r+   r,   r   nameri   r-   c                 C  s   t dS )a%  
        Spawn a new task using the given callable.

        Implementors must ensure that the future is resolved when the task finishes.

        :param func: a callable
        :param args: positional arguments to be passed to the callable
        :param kwargs: keyword arguments to be passed to the callable
        :param name: name of the task (will be coerced to a string if not ``None``)
        :param future: a future that will resolve to the return value of the callable,
            or the exception raised during its execution

        N)NotImplementedError)rJ   r+   r,   r   r   ri   r8   r8   r9   _spawn_task_from_thread   s    z&BlockingPortal._spawn_task_from_threadr(   r)   r$   r*   c                 G  s   d S rG   r8   rJ   r+   r,   r8   r8   r9   r`     s    zBlockingPortal.callr;   c                 G  s   d S rG   r8   r   r8   r8   r9   r`     s    c                 G  s   t t| j|f|  S )a3  
        Call the given function in the event loop thread.

        If the callable returns a coroutine object, it is awaited on.

        :param func: any callable
        :raises RuntimeError: if the portal is not running or if this method is called
            from within the event loop thread

        )r   r$   rW   rU   r   r8   r8   r9   r`     s    N)r   )r+   r,   r   r-   c                G  s   d S rG   r8   rJ   r+   r   r,   r8   r8   r9   rW   "  s    zBlockingPortal.start_task_soonc                G  s   d S rG   r8   r   r8   r8   r9   rW   +  s    c                G  s$   |    t }| ||i || |S )a  
        Start a task in the portal's task group.

        The task will be run inside a cancel scope which can be cancelled by cancelling
        the returned future.

        :param func: the target function
        :param args: positional arguments passed to ``func``
        :param name: name of the task (will be coerced to a string if not ``None``)
        :return: a future that resolves with the return value of the callable if the
            task completes successfully, or with the exception raised in the task
        :raises RuntimeError: if the portal is not running or if this method is called
            from within the event loop thread
        :rtype: concurrent.futures.Future[T_Retval]

        .. versionadded:: 3.0

        )r{   r   r   )rJ   r+   r   r,   r   r8   r8   r9   rW   4  s    z"Callable[..., Awaitable[T_Retval]]ztuple[Future[T_Retval], Any]c                  s\   ddd fdd}|    t  t }t }|| | ||d|i|| |  fS )a  
        Start a task in the portal's task group and wait until it signals for readiness.

        This method works the same way as :meth:`.abc.TaskGroup.start`.

        :param func: the target function
        :param args: positional arguments passed to ``func``
        :param name: name of the task (will be coerced to a string if not ``None``)
        :return: a tuple of (future, task_status_value) where the ``task_status_value``
            is the value passed to ``task_status.started()`` from within the target
            function
        :rtype: tuple[concurrent.futures.Future[T_Retval], Any]

        .. versionadded:: 3.0

        r   rl   )ri   r-   c                   sH      sD|  r   n*|  r2 |   ntd} | d S )Nz1Task exited without calling task_status.started())doner   r   	exceptionrP   r4   )ri   rT   Ztask_status_futurer8   r9   	task_doneh  s    
z,BlockingPortal.start_task.<locals>.task_donetask_status)r{   r   rg   r   r   rU   )rJ   r+   r   r,   r   r   r   r8   r   r9   
start_taskQ  s    
zBlockingPortal.start_taskrC   zContextManager[T_co])cmr-   c                 C  s
   t || S )a  
        Wrap an async context manager as a synchronous context manager via this portal.

        Spawns a task that will call both ``__aenter__()`` and ``__aexit__()``, stopping
        in the middle until the synchronous context manager exits.

        :param cm: an asynchronous context manager
        :return: a synchronous context manager

        .. versionadded:: 2.1

        )r>   )rJ   r   r8   r8   r9   wrap_async_context_manager|  s    z)BlockingPortal.wrap_async_context_manager)F)rc   rd   re   __doc__rp   rK   rN   rR   r{   r|   rz   r   r   r   r`   rW   r   r   r8   r8   r8   r9   rD      s4   	*!+rD   asynciostrzdict[str, Any] | Nonez$Generator[BlockingPortal, Any, None])backendbackend_optionsr-   c                 #  s   dd fdd}t   td}|jtj|| |d}ztttt  | gtd W n& t	k
rz    
  |
   Y nX   r  }d}z*z
|V  W n t	k
r   d	} Y nX W 5 z||j| W n tk
r   Y nX X |  W 5 Q R X d
S )a|  
    Start a new event loop in a new thread and run a blocking portal in its main task.

    The parameters are the same as for :func:`~anyio.run`.

    :param backend: name of the backend
    :param backend_options: backend options
    :return: a context manager that yields a blocking portal

    .. versionchanged:: 3.0
        Usage as a context manager is now required.

    rl   rM   c               
     sD   t  4 I d H &}   r0 |  |  I d H  W 5 Q I d H R X d S rG   )rD   r   rQ   r|   )Zportal_rh   r8   r9   
run_portal  s    
z)start_blocking_portal.<locals>.run_portalr   )r   r   )return_whenFTN)r   r   submitr   r:   r	   r   r   r   rO   r   r   rU   r`   rz   r4   )r   r   r   executorZ
run_futurerF   Zcancel_remaining_tasksr8   rh   r9   start_blocking_portal  s>    


r   rl   rM   c                  C  s6   z
t j} W n tk
r(   tddY nX |   dS )aa  
    Check if the cancel scope of the host task's running the current worker thread has
    been cancelled.

    If the host task's current cancel scope has indeed been cancelled, the
    backend-specific cancellation exception will be raised.

    :raises RuntimeError: if the current thread was not spawned by
        :func:`.to_thread.run_sync`

    r.   N)r   r1   r3   r4   check_cancelled)r7   r8   r8   r9   r     s    
r   )r   N):
__future__r   sysrq   collections.abcr   r   r   concurrent.futuresr   r   r   r	   
contextlibr
   r   inspectr   typesr   typingr   r   r   r   r   r   r   r   _corer   _core._eventloopr   r   r   _core._synchronizationr   _core._tasksr   r   abcr   Z
abc._tasksr   version_infor"   r#   typing_extensionsr$   r%   r'   r:   r=   r>   rg   rD   r   r   r8   r8   r8   r9   <module>   s@   (3     :