
    RPf=                       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jX                  dk\  r	d dlm-Z-m.Z. nd dl/m-Z-m.Z.  ed      Z0 edd      Z1 e-d      Z2	 	 	 	 	 	 d!dZ3	 	 	 	 	 	 d"dZ4 G d dee1   e      Z5 G d de+      Z6 G d d      Z7e	 d#	 	 	 	 	 d$d       Z8d%d Z9y)&    )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PosArgsTc                    	 t         j                  }t         j                  }|j                  | ||      S # t        $ r t	        d      dw xY w)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funcargsasync_backendr,   s       K/var/www/fastapitest/venv/lib/python3.12/site-packages/anyio/from_thread.pyrunr7   &   s[    $::** ..tT.GG  G
		    6 Ac                    	 t         j                  }t         j                  }|j                  | ||      S # t        $ r t	        d      dw xY w)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   r-   r.   r/   r0   run_sync_from_threadr2   s       r6   run_syncr;   <   s[    $::** --dD-FF  G
	r8   c                  j    e Zd ZU ded<   ded<   ded<   dZded	<   dd
ZddZddZ	 	 	 	 	 	 	 	 ddZy)_BlockingAsyncContextManagerzFuture[T_co]_enter_futurezFuture[bool | None]_exit_futurer   _exit_event)NNNzMtuple[type[BaseException] | None, BaseException | None, TracebackType | None]_exit_exc_infoc                     || _         || _        y N)	_async_cm_portal)selfasync_cmportals      r6   __init__z%_BlockingAsyncContextManager.__init__Z   s    !    c                  K   	 t               | _        | j                  j                          d {   }| j                  j                  |       	 | j                  j                          d {     | j                  j                  | j                    d {   }|S 7 o# t        $ r!}| j                  j                  |        d }~ww xY w7 `7 7#  | j                  j                  | j                    d {  7  }|c cY S xY wwrC   )r   r@   rD   
__aenter__r>   
set_resultBaseExceptionset_exceptionr
   	__aexit__rA   )rF   valueexcresults       r6   run_async_cmz)_BlockingAsyncContextManager.run_async_cm^   s     	1$wD..3355E
 ))%0	
 ""'')))
 44>>33T5H5HIIFM% 6 	,,S1	 *
 J34>>33T5H5HIIIFMs   D	,B" B B" D	C .C/C 3&D	CD	 B" "	C+CCD	C D	'D:C=;	DD	c                    t               | _        | j                  j                  | j                        | _        | j                  j                         S rC   )r   r>   rE   start_task_soonrT   r?   rS   rF   s    r6   	__enter__z&_BlockingAsyncContextManager.__enter__u   s>    #X LL889J9JK!!((**rJ   c                    |||f| _         | j                  j                  | j                  j                         | j
                  j                         S rC   )rA   rE   callr@   setr?   rS   )rF   &_BlockingAsyncContextManager__exc_type'_BlockingAsyncContextManager__exc_value'_BlockingAsyncContextManager__tracebacks       r6   __exit__z%_BlockingAsyncContextManager.__exit__z   sF     )+{B$**../  ''))rJ   N)rG   AsyncContextManager[T_co]rH   BlockingPortal)returnbool | None)rb   r&   )r\   type[BaseException] | Noner]   BaseException | Noner^   TracebackType | Nonerb   rc   )	__name__
__module____qualname____annotations__rA   rI   rT   rX   r_    rJ   r6   r=   r=   R   sb    %% 	   .+
*.* ** *	*
 
*rJ   r=   c                      e Zd ZddZdddZy)_BlockingPortalTaskStatusc                    || _         y rC   )_future)rF   futures     r6   rI   z"_BlockingPortalTaskStatus.__init__   s	    rJ   Nc                :    | j                   j                  |       y rC   )ro   rM   )rF   rQ   s     r6   startedz!_BlockingPortalTaskStatus.started   s    &rJ   )rp   r   rC   )rQ   objectrb   None)rg   rh   ri   rI   rr   rk   rJ   r6   rm   rm      s    'rJ   rm   c                  z   e Zd ZdZddZddZddZ	 	 	 	 	 	 	 	 ddZddZddZ	dddZ
	 	 	 	 	 	 	 	 	 	 dd	Z	 	 	 	 	 	 	 	 	 	 	 	 dd
Ze	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 dd       Z	 	 	 	 	 	 ddZedd	 	 	 	 	 	 	 dd       Zedd	 	 	 	 	 	 	 d d       Zdd	 	 	 	 	 	 	 d!dZdd	 	 	 	 	 	 	 d"dZ	 	 	 	 d#dZy)$ra   zLAn object that lets external threads run code in an asynchronous event loop.c                2    t               j                         S rC   )r   create_blocking_portal)clss    r6   __new__zBlockingPortal.__new__   s     "99;;rJ   c                    t        j                         | _        t               | _        t               | _        t               | _        y rC   )		threading	get_ident_event_loop_thread_idr   _stop_eventr   _task_groupr   _cancelled_exc_classrW   s    r6   rI   zBlockingPortal.__init__   s3    1:1D1D1F" 7,.$;$=!rJ   c                V   K   | j                   j                          d {    | S 7 wrC   )r   rL   rW   s    r6   rL   zBlockingPortal.__aenter__   s(     ))+++ 	,s   )')c                   K   | j                          d {    | j                  j                  |||       d {   S 7 )7 wrC   )stopr   rP   )rF   exc_typeexc_valexc_tbs       r6   rP   zBlockingPortal.__aexit__   s>      iik%%//'6JJJ 	Js   AA $AAAAc                    | j                   t        d      | j                   t        j                         k(  rt        d      y )NzThis portal is not runningz7This method cannot be called from the event loop thread)r}   r0   r{   r|   rW   s    r6   _check_runningzBlockingPortal._check_running   sF    %%-;<<%%)<)<)>>I  ?rJ   c                T   K   | j                   j                          d{    y7 w)z#Sleep until :meth:`stop` is called.N)r~   r
   rW   s    r6   sleep_until_stoppedz"BlockingPortal.sleep_until_stopped   s     ##%%%s   (&(c                   K   d| _         | j                  j                          |r%| j                  j                  j                          yyw)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)r}   r~   r[   r   cancel_scopecancel)rF   cancel_remainings     r6   r   zBlockingPortal.stop   sB      &*"))002 s   A
Ac                \   	K   d	 fd}	  ||i |}t        |      rPt               5 	|j                         r	j                          n|j	                  |       | d {   }d d d        n|}|j                         s|j                         	 d 	y 	 d 	y 7 8# 1 sw Y   4xY w#  j                  $ r% |j                          |j                          Y d 	y t        $ r>}|j                         s|j                  |       t        |t              s Y d }~d 	y d }~ww xY w# d 	w xY ww)Nc                    | j                         r?j                  d t        j                         fvrj	                  j
                         y y y rC   )	cancelledr}   r{   r|   rZ   r   )fscoperF   s    r6   callbackz+BlockingPortal._call_func.<locals>.callback   sG    {{}!;!;##%D " 		%,,'	"}rJ   )r   Future[T_Retval]rb   rt   )r   r   r   r   add_done_callbackrM   r   set_running_or_notify_cancelrN   rO   
isinstance	Exception)
rF   r3   r4   kwargsrp   r   retval_or_awaitableretvalrR   r   s
   `        @r6   
_call_funczBlockingPortal._call_func   s)    	(	"&"7"7./ ] 7e'')00:#66F7 7 - ##%!!&)E & E# 77 7 (( 	2MMO//1 E  	##%$$S) c9- . E	 Es   D,B) 8B"B#B'B) 2!D% D,D,BB&"B) )/D"D% D,D"$2DD% D,D""D% %D))D,c                    t         )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

        )NotImplementedError)rF   r3   r4   r   namerp   s         r6   _spawn_task_from_threadz&BlockingPortal._spawn_task_from_thread   s
    * "!rJ   c                     y rC   rk   rF   r3   r4   s      r6   rZ   zBlockingPortal.call  s     	rJ   c                     y rC   rk   r   s      r6   rZ   zBlockingPortal.call  s     	rJ   c                `    t        t         | j                  |g| j                               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%   rV   rS   r   s      r6   rZ   zBlockingPortal.call  s-     H2d224?$?FFHIIrJ   N)r   c                    y rC   rk   rF   r3   r   r4   s       r6   rV   zBlockingPortal.start_task_soon"       	rJ   c                    y rC   rk   r   s       r6   rV   zBlockingPortal.start_task_soon+  r   rJ   c               d    | j                          t               }| j                  ||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   )rF   r3   r   r4   r   s        r6   rV   zBlockingPortal.start_task_soon4  s2    0 	$h$$T4T1=rJ   c                   dfd}| j                          t               t              }t               }|j                  |       | j	                  ||d|i||       |j                         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

        c                   j                         sn| j                         rj                          y | j                         r j	                  | j                                y t        d      }j	                  |       y y )Nz1Task exited without calling task_status.started())doner   r   	exceptionrO   r0   )rp   rR   task_status_futures     r6   	task_donez,BlockingPortal.start_task.<locals>.task_doneh  sl    %**,##%&--/%%'&44V5E5E5GH&KC '44S9 -rJ   task_status)rp   r   rb   rt   )r   r   rm   r   r   rS   )rF   r3   r   r4   r   r   r   r   s          @r6   
start_taskzBlockingPortal.start_taskQ  so    .
	: 	%+X/0BCH	I&$$T4-1MtUVW$++---rJ   c                    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=   )rF   cms     r6   wrap_async_context_managerz)BlockingPortal.wrap_async_context_manager|  s     ,B55rJ   )rb   ra   rb   rt   )r   rd   r   re   r   rf   rb   rc   )F)r   boolrb   rt   )
r3   <Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval]r4   tuple[Unpack[PosArgsT]]r   dict[str, Any]rp   r   rb   rt   )r3   r   r4   r   r   r   r   rs   rp   r   rb   rt   r3   1Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]]r4   Unpack[PosArgsT]rb   r%   r3   &Callable[[Unpack[PosArgsT]], T_Retval]r4   r   rb   r%   )r3   r   r4   r   rb   r%   )r3   r   r4   r   r   rs   rb   r   )r3   r   r4   r   r   rs   rb   r   )r3   r   r4   r   r   rs   rb   r   )r3   z"Callable[..., Awaitable[T_Retval]]r4   rs   r   rs   rb   ztuple[Future[T_Retval], Any])r   r`   rb   zContextManager[T_co])rg   rh   ri   __doc__ry   rI   rL   rP   r   r   r   r   r   r   rZ   rV   r   r   rk   rJ   r6   ra   ra      s>   V<>K,K &K %	K
 
K&3 (J( &( 	(
 !( 
(T"J" &" 	"
 " !" 
". ?   
	  :CS	 
JJJ  J 
	J" 
 	?   	
 
  
 	4   	
 
  	J   	
 
B 	).0). ). 	).
 
&).V6+6	6rJ   ra   c              #    K   dfd}t               t        d      5 }|j                  t        j                  || |      }	 t        t        t        t            |g      t               j                         r5j                         }d}	 | 	 	 |j                  |j                  |       |j                          ddd       y# t        $ r" j                          |j                           w xY w# t        $ r d} w xY w# t        $ r Y bw xY w# 	 |j                  |j                  |       w # t        $ r Y w w xY wxY w# 1 sw Y   yxY ww)	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.

    c                    K   t               4 d {   } j                         r)j                  |        | j                          d {    d d d       d {    y 7 N7 7 	# 1 d {  7  sw Y   y xY wwrC   )ra   r   rM   r   )portal_rp   s    r6   
run_portalz)start_blocking_portal.<locals>.run_portal  sp     !# 	4 	4w224!!'*11333	4 	4 	4 4	4 	4 	4 	4sV   A<A!A<5A'A#A'A<A%A<#A'%A<'A9-A0.A95A<r   )backendbackend_options)return_whenFTNr   )r   r	   submitr   r7   r
   r   r   r   rN   r   r   rS   rZ   r   r0   )r   r   r   executor
run_futurerH   cancel_remaining_tasksrp   s          @r6   start_blocking_portalr     sJ    $4 &,XF	A	 (__NN+	 % 

	Xf%
F';<+ ;;=]]_F%*"	
KK-CD 	?   	MMO	 ! )-& $ KK-CD# 9 s   E$E(C
,"EC8D1E	E
+C55E8DD	DEDEED65E6	E	?EE	EEEEc                 x    	 t         j                  } | j	                          y# t        $ r t        d      dw xY w)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   r-   r/   r0   check_cancelled)r5   s    r6   r   r     sD    &2&H&H !!#  G
	s   # 9r   r   )asyncioN)r   strr   zdict[str, Any] | Nonerb   z$Generator[BlockingPortal, Any, None]r   ):
__future__r   sysr{   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   
abc._tasksr    version_infor#   r$   typing_extensionsr%   r&   r(   r7   r;   r=   rm   ra   r   r   rk   rJ   r6   <module>r      s$   " 
  : : P P =  	 	 	  V V ) 8  "w++6:v&
#H
;HDTHH,G
0G9IGG,0*74=2H 0*f'
 '~6 ~6B GK77/D7)7 7t$rJ   