a
    `*j"G                     @   s@  d 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
 ddlmZmZ ddlmZmZmZ ddlmZ G d	d
 d
eZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZd(ddddZd)ddddZdd Zd d! Zd"d# Z d$d% Z!d&d' Z"e e"_#dS )*aI  Synchronization decorators and calling-convention markers/bridges.

Provides ``synchronized`` for thread and async locking, ``mark_as_sync``
and ``mark_as_async`` for declaring the effective calling convention of a
wrapped callable (without converting it), and ``async_to_sync`` /
``sync_to_async`` for bridging between the two.
    N)partial)CO_ASYNC_GENERATORCO_COROUTINECO_GENERATORCO_ITERABLE_COROUTINEiscoroutinefunction)LockRLock   )BoundFunctionWrapperCallableObjectProxyFunctionWrapper)	decoratorc                       s*   e Zd Zd fdd	Zedd Z  ZS )_SyncCodeProxyNc                    s   t  | || _d S Nsuper__init___self_generatorselfwrapped	generator	__class__ Q/var/www/html/assistant/venv/lib/python3.9/site-packages/wrapt/synchronization.pyr   "   s    z_SyncCodeProxy.__init__c                 C   sX   | j j}|ttB tB  @ }| jdu r.|tO }n&| jdu rD|t M }n|t@ rT|tO }|S NTF)__wrapped__co_flagsr   r   r   r   r   r   originalflagsr   r   r   r   &   s    


z_SyncCodeProxy.co_flags)N__name__
__module____qualname__r   propertyr   __classcell__r   r   r   r   r       s   r   c                       s*   e Zd Zd fdd	Zedd Z  ZS )_SyncFunctionSurrogateNc                    s   t  | || _d S r   r   r   r   r   r   r   ;   s    z_SyncFunctionSurrogate.__init__c                 C   s   t | jj| jS r   r   r   __code__r   r   r   r   r   r+   ?   s    z_SyncFunctionSurrogate.__code__)Nr$   r%   r&   r   r'   r+   r(   r   r   r   r   r)   9   s   r)   c                       s(   e Zd Z fddZedd Z  ZS )_BoundSyncFunctionWrapperc                    s   t  j|i | d| _d S NT)r   r   _self_is_not_coroutine)r   argskwargsr   r   r   r   F   s    z"_BoundSyncFunctionWrapper.__init__c                 C   s   t | jj| jjS r   )r)   r   __func___self_parentr   r,   r   r   r   r3   J   s    z"_BoundSyncFunctionWrapper.__func__)r$   r%   r&   r   r'   r3   r(   r   r   r   r   r.   D   s   r.   c                       s.   e Zd ZeZd fdd	Zedd Z  ZS )_SyncFunctionWrapperNc                    s   t  || d| _|| _d S r/   )r   r   r0   r   r   r   wrapperr   r   r   r   r   U   s    z_SyncFunctionWrapper.__init__c                 C   s   t | jj| jS r   r*   r,   r   r   r   r+   Z   s    z_SyncFunctionWrapper.__code__)N)	r$   r%   r&   r.   __bound_function_wrapper__r   r'   r+   r(   r   r   r   r   r5   Q   s   r5   c                       s*   e Zd Zd fdd	Zedd Z  ZS )_AsyncCodeProxyNc                    s   t  | || _d S r   r   r   r   r   r   r   a   s    z_AsyncCodeProxy.__init__c                 C   sh   | j j}|ttB tB tB  @ }| jdu r2|tO }n2| jdu rF|tO }n|ttB @ r\|tO }n|tO }|S r   )r   r   r   r   r   r   r   r    r   r   r   r   e   s    




z_AsyncCodeProxy.co_flags)Nr#   r   r   r   r   r9   _   s   r9   c                       s*   e Zd Zd fdd	Zedd Z  ZS )_AsyncFunctionSurrogateNc                    s   t  | || _d S r   r   r   r   r   r   r   |   s    z _AsyncFunctionSurrogate.__init__c                 C   s   t | jj| jS r   r9   r   r+   r   r,   r   r   r   r+      s    z _AsyncFunctionSurrogate.__code__)Nr-   r   r   r   r   r:   z   s   r:   c                   @   s   e Zd Zedd ZdS )_BoundAsyncFunctionWrapperc                 C   s   t | jj| jjS r   )r:   r   r3   r4   r   r,   r   r   r   r3      s    z#_BoundAsyncFunctionWrapper.__func__N)r$   r%   r&   r'   r3   r   r   r   r   r<      s   r<   c                       s.   e Zd ZeZd fdd	Zedd Z  ZS )_AsyncFunctionWrapperNc                    s   t  || || _d S r   r   r6   r   r   r   r      s    z_AsyncFunctionWrapper.__init__c                 C   s   t | jj| jS r   r;   r,   r   r   r   r+      s    z_AsyncFunctionWrapper.__code__)N)	r$   r%   r&   r<   r8   r   r'   r+   r(   r   r   r   r   r=      s   r=   r   c                  s     fdd}| du r|S || S )a9  Mark a callable as synchronous from the perspective of calling
    convention detection. The returned wrapper is a pass-through that
    reports `inspect.iscoroutinefunction()` as False regardless of
    whether the underlying callable is declared `async def`. Useful
    when a stacked decorator has already collapsed an async function
    into a synchronous one (for example by using `asyncio.run()`).

    The `generator` keyword toggles the sync generator bit
    (`CO_GENERATOR`) on the resulting wrapper. Tri-state:

    - `None` (default): auto. Preserve generator-ness from the input --
      if the input was an async generator, the wrapper reports as a sync
      generator; otherwise CO_GENERATOR is copied through unchanged.
    - `True`: force CO_GENERATOR on. Wrapper reports as a sync generator.
    - `False`: force CO_GENERATOR off. Wrapper reports as a plain sync
      function even if the input had CO_GENERATOR set.

    Regardless of `generator`, CO_COROUTINE, CO_ASYNC_GENERATOR, and
    CO_ITERABLE_COROUTINE are all cleared (sync means none of those).
    c                    s   dd }t | | dS )Nc                 S   s   | |i |S r   r   r   instancer1   r2   r   r   r   _wrapper   s    z2mark_as_sync.<locals>._decorator.<locals>._wrapperr>   r5   )r   rA   r>   r   r   
_decorator   s    z mark_as_sync.<locals>._decoratorNr   r   r   rC   r   r>   r   mark_as_sync   s    rE   c                  s*   dd   fdd}| du r"|S || S )a  Mark a callable as asynchronous from the perspective of calling
    convention detection. The returned wrapper reports
    `inspect.iscoroutinefunction()` as True regardless of whether the
    underlying callable is declared `async def`. Useful when a stacked
    decorator returns a coroutine from a plain `def` wrapper.

    The `generator` keyword chooses between coroutine function and
    async generator reporting. Tri-state:

    - `None` (default): auto. If the input was a sync or async
      generator, the wrapper reports as an async generator
      (`CO_ASYNC_GENERATOR`); otherwise it reports as a coroutine
      function (`CO_COROUTINE`).
    - `True`: force async generator reporting (`CO_ASYNC_GENERATOR` set,
      `CO_COROUTINE` cleared). These two flags are mutually exclusive at
      the CPython code-object level.
    - `False`: force coroutine function reporting (`CO_COROUTINE` set,
      `CO_ASYNC_GENERATOR` cleared).

    CO_GENERATOR and CO_ITERABLE_COROUTINE are always cleared (the
    async path does not use either).
    c                    s   | |i |S r   r   r?   r   r   r   rA      s    zmark_as_async.<locals>._wrapperc                    s   t |  dS )Nr>   r=   r   rA   r   r   r   rC      s    z!mark_as_async.<locals>._decoratorNr   rD   r   rH   r   mark_as_async   s
    rI   c                 C   s   dd }t | |S )a  Adapt an async callable so it can be called synchronously. Each
    call runs the coroutine to completion via `asyncio.run()`. The
    returned wrapper reports as synchronous under
    `inspect.iscoroutinefunction()`. Naming follows the asgiref
    convention.c                 S   s   t | |i |S r   )asynciorunr?   r   r   r   r7      s    zasync_to_sync.<locals>.wrapperrB   r   r7   r   r   r   async_to_sync   s    rM   c                 C   s   dd }t | |S )a  Adapt a sync callable so it can be awaited. Each call dispatches
    the synchronous work to the default executor via
    `loop.run_in_executor()`. The returned wrapper reports as
    asynchronous under `inspect.iscoroutinefunction()`. Naming follows
    the asgiref convention.c                    s,   t  }|d t| g|R i |I d H S r   )rJ   Zget_running_loopZrun_in_executorr   )r   r@   r1   r2   loopr   r   r   r7      s    zsync_to_async.<locals>.wrapperrF   rL   r   r   r   sync_to_async   s    rO   c                 C   s   t t| dd S )Nacquire)r   getattr)objr   r   r   _synchronized_is_async_lock   s    rS   c                 C   s   t | | i}t }| }t|ttfrxt|dd }|d u r@|j}|}t |}||v s`t||krnt	d
| |||< qt|ddrdS t|rdS t|dd }|d u s||u rdS |}t |}||v st||krt	d
| |||< qd S )Nr   z!wrapper loop when unwrapping {!r}r0   FT)idsysgetrecursionlimit
isinstanceclassmethodstaticmethodrQ   r3   len
ValueErrorformatr   )rR   memorecursion_limittargetinnerZ	id_targetZnext_targetr   r   r   _synchronized_is_async_callable   s2    ra   c                    s   t | dr|t | dr|| trNtfdd}G fdddt}||dS tfdd}G fd	d
d
t}||dS dd dd  fdd} fdd}G  fdddt}t| r|| |dS || |dS )a  Depending on the nature of the `wrapped` object, will either return a
    decorator which can be used to wrap a function or method, or a context
    manager, both of which will act accordingly depending on how used, to
    synchronize access to calling of the wrapped function, or the block of
    code within the context manager. If it is an object which is a
    synchronization primitive, such as a threading Lock, RLock, Semaphore,
    Condition, or Event, then it is assumed that the object is to be used
    directly as the synchronization primitive, otherwise a lock is created
    automatically and attached to the wrapped object and used as the
    synchronization primitive.

    Async functions are supported: if the wrapped callable is an async
    function, an `asyncio.Lock` is created for the context and the wrapper
    awaits the lock. The returned object also exposes `__aenter__` and
    `__aexit__` so it can be used with `async with` to synchronise a block
    of code using an independent per-context `asyncio.Lock`. If an object
    with coroutine `acquire`/`release` methods (such as an `asyncio.Lock`)
    is supplied directly, the returned decorator and context manager will
    use it via the async protocol.
    rP   releasec              	      sP    4 I d H * | |i |I d H W  d   I d H  S 1 I d H sB0    Y  d S r   r   r?   lockr   r   _synchronizedX  s    z#synchronized.<locals>._synchronizedc                       s$   e Zd Z fddZ fddZdS )z1synchronized.<locals>._AsyncSynchronizedLockProxyc                    s      I d H   S r   rP   r,   rc   r   r   
__aenter___  s    z<synchronized.<locals>._AsyncSynchronizedLockProxy.__aenter__c                    s       d S r   rb   r   r1   rc   r   r   	__aexit__c  s    z;synchronized.<locals>._AsyncSynchronizedLockProxy.__aexit__N)r$   r%   r&   rg   rj   r   rc   r   r   _AsyncSynchronizedLockProxy]  s   rk   rG   c                    s6     | |i |W  d    S 1 s(0    Y  d S r   r   r?   rc   r   r   re   h  s    c                       s$   e Zd Z fddZ fddZdS )z,synchronized.<locals>._SynchronizedLockProxyc                    s        S r   rf   r,   rc   r   r   	__enter__r  s    z6synchronized.<locals>._SynchronizedLockProxy.__enter__c                    s       d S r   rh   ri   rc   r   r   __exit__v  s    z5synchronized.<locals>._SynchronizedLockProxy.__exit__N)r$   r%   r&   rl   rm   r   rc   r   r   _SynchronizedLockProxyp  s   rn   c                 S   sl   t | dd }|d u rhtj: t | dd }|d u rJt }t| d| W d    n1 s^0    Y  |S )N_synchronized_lock)varsgetsynchronized_synchronized_meta_lockr	   setattrcontextrd   r   r   r   ro     s    *z(synchronized.<locals>._synchronized_lockc                 S   sn   t | dd }|d u rjtj< t | dd }|d u rLt }t| d| W d    n1 s`0    Y  |S )N_synchronized_async_lock)rp   rq   rr   rs   rJ   r   rt   ru   r   r   r   rw     s    *z.synchronized.<locals>._synchronized_async_lockc                    sF    |d ur|n|  | |i |W  d    S 1 s80    Y  d S r   r   r?   ro   r   r   _synchronized_wrapper  s    z+synchronized.<locals>._synchronized_wrapperc              	      s`    |d ur|n| 4 I d H * | |i |I d H W  d   I d H  S 1 I d H sR0    Y  d S r   r   r?   rw   r   r   _synchronized_async_wrapper  s    z1synchronized.<locals>._synchronized_async_wrapperc                       s4   e Zd ZfddZdd Z fddZdd Zd	S )
z2synchronized.<locals>._SynchronizedFunctionWrapperc                    s    | j | _| j  | jS r   )r   
_self_lockrP   r,   rx   r   r   rl     s    
z<synchronized.<locals>._SynchronizedFunctionWrapper.__enter__c                 W   s   | j   d S r   )r|   rb   ri   r   r   r   rm     s    z;synchronized.<locals>._SynchronizedFunctionWrapper.__exit__c                    s"    | j | _| j I d H  | jS r   )r   _self_async_lockrP   r,   rz   r   r   rg     s    z=synchronized.<locals>._SynchronizedFunctionWrapper.__aenter__c                    s   | j   d S r   )r}   rb   ri   r   r   r   rj     s    z<synchronized.<locals>._SynchronizedFunctionWrapper.__aexit__N)r$   r%   r&   rl   rm   rg   rj   r   )rw   ro   r   r   _SynchronizedFunctionWrapper  s   r~   rL   )hasattrrS   r   r   r   ra   )r   re   rk   rn   ry   r{   r~   r   )rw   ro   rd   r   rr   1  s*    	
	
 rr   )N)N)$__doc__rJ   rU   	functoolsr   inspectr   r   r   r   r   	threadingr   r	   Z	__wrapt__r   r   r   Z
decoratorsr   r   r)   r.   r5   r9   r:   r<   r=   rE   rI   rM   rO   rS   ra   rr   rs   r   r   r   r   <module>   s0   
	!#3 +