XjAKjddlmZdZddlZddlmZmZmZmZddl m Z ddl m Z m Z mZddlmZmZddlmZdd lmZdd lmZmZmZmZdd lmZdd lmZmZm Z m!Z!m"Z"d dl#m$Z$m%Z%d dl#m&Z'd dl(m)Z)d dl*m+Z+d dl,m-Z-m.Z.d dl/m0Z0d dl1m2Z2m3Z3ejhdk\r ddlm5Z5m6Z6nddl7m5Z5m6Z6e dZ8e ddZ9e5dZ:d+dZ;dd d,dZ&dd d-dZ<Gd d!ee9e Z=Gd"d#e0Z>Gd$d%Z?eGd&d'Z@e d.dd( d/d)ZAd0d*ZBy)1) annotations)BlockingPortalBlockingPortalProvidercheck_cancelledrunrun_syncstart_blocking_portalN) AwaitableCallable Coroutine Generator)Future)AbstractAsyncContextManagerAbstractContextManagercontextmanager) dataclassfield)partial) isawaitable)LockThreadcurrent_thread get_ident) TracebackType)AnyGenericTypeVarcastoverload)get_cancelled_exc_class threadlocals)r)NoEventLoopError)Event) CancelScopecreate_task_group) TaskStatus)EventLoopToken current_token) ) TypeVarTupleUnpackT_RetvalT_coT) covariantPosArgsTc^||S tjS#t$r tddwxYw)NzONot running inside an AnyIO worker thread, and no event loop token was provided)r"r)AttributeErrorr#tokens e/mnt/ssd/data/Dropbox/adrian/vault-secondbrain/venv/lib/python3.12/site-packages/anyio/from_thread.py_token_or_errorr76sD  )))    s,r4c|du}t|}|jj|||r|jSdS)a Call a coroutine function from a worker thread. :param func: a coroutine function :param args: positional arguments for the callable :param token: an event loop token to use to get back to the event loop thread (required if calling this function from outside an AnyIO worker thread) :return: the return value of the coroutine function :raises MissingTokenError: if no token was provided and called from outside an AnyIO worker thread :raises RunFinishedError: if the event loop tied to ``token`` is no longer running .. versionchanged:: 4.11.0 Added the ``token`` parameter. Nr4)r7 backend_classrun_async_from_thread native_tokenfuncr5argsexplicit_tokens r6rrCsW*$&N E "E    4 4 d%,, 5 DH 5 c|du}t|}|jj|||r|jSdS)az Call a function in the event loop thread from a worker thread. :param func: a callable :param args: positional arguments for the callable :param token: an event loop token to use to get back to the event loop thread (required if calling this function from outside an AnyIO worker thread) :return: the return value of the callable :raises MissingTokenError: if no token was provided and called from outside an AnyIO worker thread :raises RunFinishedError: if the event loop tied to ``token`` is no longer running .. versionchanged:: 4.11.0 Added the ``token`` parameter. Nr4)r7r9run_sync_from_threadr;r<s r6rr_sW*$&N E "E    3 3 d%,, 4 DH 4 r@creZdZUded<ded<ded<dZded < dd Zdd Zdd Z dd Zy)_BlockingAsyncContextManagerz Future[T_co] _enter_futurezFuture[bool | None] _exit_futurer$ _exit_event)NNNzMtuple[type[BaseException] | None, BaseException | None, TracebackType | None]_exit_exc_infoc ||_||_yN) _async_cm_portal)selfasync_cmportals r6__init__z%_BlockingAsyncContextManager.__init__s" r@c K t|_|jjd{}|jj | |jjd{|jj|jd{}|S7o#t $r!}|jj|d}~wwxYw7`77#|jj|jd{7}wxYwwrJ) r$rGrK __aenter__rE set_result BaseException set_exceptionwait __aexit__rH)rMvalueexcresults r6 run_async_cmz)_BlockingAsyncContextManager.run_async_cms 1$wD ..3355E    ) )% 0 J ""'') ) ) 44>>33T5H5HIIF '6     , ,S 1   * J34>>33T5H5HIIIFsD,B"B B"DC.C/C3&DCD B"" C +CC  DCD'D:C=;DDct|_|jj|j|_|jj SrJ)rrErLstart_task_soonr[rFrZrMs r6 __enter__z&_BlockingAsyncContextManager.__enter__s>#X LL889J9JK!!((**r@c|||f|_|jj|jj|j j SrJ)rHrLcallrGsetrFrZ)rM&_BlockingAsyncContextManager__exc_type'_BlockingAsyncContextManager__exc_value'_BlockingAsyncContextManager__tracebacks r6__exit__z%_BlockingAsyncContextManager.__exit__sF )+{B $**../  ''))r@N)rN!AbstractAsyncContextManager[T_co]rOr)return bool | None)rhr/)rctype[BaseException] | NonerdBaseException | NonereTracebackType | Nonerhri) __name__ __module__ __qualname____annotations__rHrPr[r_rfr@r6rDrD{sr%% 9CQ 0+ *.**** *  *r@rDceZdZddZdddZy)_BlockingPortalTaskStatusc||_yrJ)_future)rMfutures r6rPz"_BlockingPortalTaskStatus.__init__s  r@Nc:|jj|yrJ)rurS)rMrXs r6startedz!_BlockingPortalTaskStatus.starteds &r@)rvrrJ)rXobjectrhNone)rmrnrorPrxrqr@r6rsrss 'r@rscreZdZdZddZddZ ddZddZddZdddZ ddZ dd Z e dd Z e dd Z dd Z e d d ddZe d d ddZd d d dZd d d!dZ d"dZy )#rz An object that lets external threads run code in an asynchronous event loop. :raises NoEventLoopError: if no supported asynchronous event loop is running in the current thread c|t|_t|_t |_t |_yrJ)r)_tokenr_event_loop_thread_idr$ _stop_eventr& _task_groupr^s r6rPzBlockingPortal.__init__s*#o 1:" 7,.r@cVK|jjd{|S7wrJ)rrRr^s r6rRzBlockingPortal.__aenter__s())+++  ,s )')cK|jd{|jj|||d{S7)7wrJ)stoprrW)rMexc_typeexc_valexc_tbs r6rWzBlockingPortal.__aexit__s> iik%%//'6JJJ JsAA$AAAAcv|j td|jtk(r tdy)NzThis portal is not runningz7This method cannot be called from the event loop thread)r~ RuntimeErrorrr^s r6_check_runningzBlockingPortal._check_runnings?  % % -;< <  % % 4I  5r@cTK|jjd{y7w)z#Sleep until :meth:`stop` is called.N)rrVr^s r6sleep_until_stoppedz"BlockingPortal.sleep_until_stoppeds##%%%s (&(cKd|_|jj|r&|jjj dyyw)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 Nz$the blocking portal is shutting down)r~rrbr cancel_scopecancel)rMcancel_remainings r6rzBlockingPortal.stopsE&*"      ) ) 0 01W X sA A c2 Kj d fd } ||i|}t|r/t5 |j||d{}dddn|}|j s|j  d y d y78#1swY4xYw#t $r%|j|jYd yt$r>}|j s|j|t|tsYd}~d yd}~wwxYw#d wxYww)Nc|jrEtk(rjdy#tjdjyyy)Nzthe future was cancelledr4) cancelledrrrr})fevent_loop_thread_idscoperMs r6callbackz+BlockingPortal._call_func..callbacksK{{}'9;6LL!;<)5 &@ 6r@)rFuture[T_Retval]rhrz) r~rr%add_done_callbackrrSr!rset_running_or_notify_cancelrTrU isinstance Exception) rMr=r>kwargsrvrretval_or_awaitableretvalrYrrs ` @@r6 _call_funczBlockingPortal._call_funcs $99  "&"7"7 ./ ]7e,,X6#66F77-##%!!&)E&E#777 '( 2 MMO  / / 1E ##%$$S)c9-. E EsDBB BB  B!DDDB  BB-D DDD 2DDDD  DDDc tt|jj||j|||||j y)a Spawn a new task using the given callable. :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 namer4N)rrr start_soonrr})rMr=r>rrrvs r6_spawn_task_from_threadz&BlockingPortal._spawn_task_from_threads<&  D$$//d ; OO    ++ r@cyrJrqrMr=r>s r6razBlockingPortal.call7s r@cyrJrqrs r6razBlockingPortal.call>sr@c`tt|j|g|jS)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 )rr.r]rZrs r6razBlockingPortal.callCs-H2d224?$?FFHIIr@NrcyrJrqrMr=rr>s r6r]zBlockingPortal.start_task_soonT r@cyrJrqrs r6r]zBlockingPortal.start_task_soon\rr@cd|jt}|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 )rrr)rMr=rr>rs r6r]zBlockingPortal.start_task_soonds20 $h $$T4T1=r@cdfd }|jtt}t}|j||j ||d|i|||j fS)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 cjsn|jrjy|jr j |jyt d}j |yy)Nz1Task exited without calling task_status.started())donerr exceptionrUr)rvrYtask_status_futures r6 task_donez,BlockingPortal.start_task..task_donesl%**,##%&--/%%'&44V5E5E5GH&KC'44S9-r@ task_status)rvrrhrz)rrrsrrrZ)rMr=rr>rrrrs @r6 start_taskzBlockingPortal.start_taskso. : %+X/0BC H I& $$T4-1MtUVW$++---r@ct||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 )rD)rMcms r6wrap_async_context_managerz)BlockingPortal.wrap_async_context_managers,B55r@rhrzrhr)rrjrrkrrlrhbool)F)rrrhrz) r=tuple[Unpack[PosArgsT]]rdict[str, Any]rvrrhrz) r=rr>rrrrryrvrrhrz)r=1Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]]r>Unpack[PosArgsT]rhr.)r=&Callable[[Unpack[PosArgsT]], T_Retval]r>rrhr.)r=rr>rrhr.)r=rr>rrryrhr)r=rr>rrryrhr)r=rr>rrryrhr)r=z"Callable[..., Awaitable[T_Retval]]r>ryrryrhztuple[Future[T_Retval], Any])rrgrhzAbstractContextManager[T_co])rmrnro__doc__rPrRrWrrrrrrrar]rrrqr@r6rrs</ K,K&K% K  K&Y (J(&( ( ! (  (T J &     !    :?    :CS JJJ J  J"  ?      4     J    B ).0).). ). & ).V636 %6r@rceZdZUdZdZded<dZded<ede Z d ed <edd Z ded<edZ ded<edd Z ded<ddZ ddZy)ra= A manager for a blocking portal. Used as a context manager. The first thread to enter this context manager causes a blocking portal to be started with the specific parameters, and the last thread to exit causes the portal to be shut down. Thus, there will be exactly one blocking portal running in this context as long as at least one thread has entered this context manager. The parameters are the same as for :func:`~anyio.run`. :param backend: name of the backend :param backend_options: backend options .. versionadded:: 4.4 asynciostrbackendNdict[str, Any] | Nonebackend_optionsF)initdefault_factoryr_lockr)rdefaultint_leases)rrrLz-AbstractContextManager[BlockingPortal] | None _portal_cmc(|j5|jDt|j|j|_|jj |_|xjdz c_|j cdddS#1swYyxYw)Nr )rrr rrr_rLrr^s r6r_z BlockingPortalProvider.__enter__sn ZZ &"7LL$"6"6# $88: LLA L<<   s A1BBc d}|j5|jsJ|jdkDsJ|xjdzc_|js|j}d|_|`ddd|r|j dddyy#1swY xYw)Nrr )rrrrLrf)rMrrr portal_cms r6rfzBlockingPortalProvider.__exit__s DH ZZ !?? "?<.run_portal s!# 0 0w|+2)8BwK?(K %   g &--/ / /  0 0 0 0  0 0 0 0sWB A1B AA7A3A7 B +A5,B 3A75B 7B =B >B B cjr tyy#t$r0}jsj |Yd}~yYd}~yd}~wwxYw)N)rr)r run_eventlooprTrrU)rYrrrvrs r6run_blocking_portalz2start_blocking_portal..run_blocking_portalsY  . . 0 . 1 ! .{{}((--% .s# A!AAT)targetdaemonrFNr) rrstartrZrTrarrjoin) rrrrthreadcancel_remaining_tasksrOrvrs ``` @@r6r r s,0..&,XF .t$ GF LLN!& L   FKK)?@   %) "        FKK)?@    s}:C-CBB7C- BB' B$!C#B$$C'C)CC CCCCCC**C-c tj}|jj y#t$r tddwxYw)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` z>This function can only be called inside an AnyIO worker threadN)r"r)r3r#r9rr4s r6rr3sJ , : :  '')  L  s -A)r5EventLoopToken | Nonerhr()r=z7Callable[[Unpack[PosArgsT]], Coroutine[Any, Any, T_co]]r>rr5rrhr/)r=rr>rr5rrhr.)rN)rrrrrz str | Nonerhz$Generator[BlockingPortal, Any, None]r)C __future__r__all__syscollections.abcr r r r concurrent.futuresr contextlibrrr dataclassesrr functoolsrinspectr threadingrrrrtypesrtypingrrrrr_core._eventloopr!r"rr_core._exceptionsr#_core._synchronizationr$ _core._tasksr%r& abc._tasksr'lowlevelr(r) version_infor,r-typing_extensionsr.r/r1r7rrDrsrrr rrqr@r6rs"  EE% )==3/)8"3w++6 : v&  #  $( A  ! >$( 0  ! 83*74=2H3*l' 'B6B6J 5151 51p-18 8 8*8  8 * 88v*r@