o
    z,h                     @   sT   d dl Z d dlZd dlZd dlZd dlmZmZmZ G dd dZG dd dZ	dS )    N)AnyDictUnionc                       sR   e Zd ZdZdddZdd Zded	eddf fd
dZdeddfddZ	  Z
S )_CVarzStorage utility for Local.returnNc                 C   s   t d| _d S )Nzasgiref.local)contextvars
ContextVar_dataself r   C/var/www/html/rh/venv/lib/python3.10/site-packages/asgiref/local.py__init__   s   
z_CVar.__init__c                 C   s8   | j i }z|| W S  ty   t| d|w Nz object has no attribute )r	   getKeyErrorAttributeErrorr   keystorage_objectr   r   r   __getattr__   s   
z_CVar.__getattr__r   valuec                    s:   |dkrt  ||S | ji }|||< | j| d S )Nr	   )super__setattr__r	   r   set)r   r   r   r   	__class__r   r   r      s
   z_CVar.__setattr__c                 C   s<   | j i }||v r||= | j | d S t| d|r   )r	   r   r   r   r   r   r   r   __delattr__   s
   z_CVar.__delattr__)r   N)__name__
__module____qualname____doc__r   r   strr   r   r   __classcell__r   r   r   r   r      s    
r   c                       sR   e Zd ZdZddeddfddZejdd	 Zd
d Z	 fddZ
dd Z  ZS )Locala  Local storage for async tasks.

    This is a namespace object (similar to `threading.local`) where data is
    also local to the current async task (if there is one).

    In async threads, local means in the same sense as the `contextvars`
    module - i.e. a value set in an async frame will be visible:

    - to other async code `await`-ed from this frame.
    - to tasks spawned using `asyncio` utilities (`create_task`, `wait_for`,
      `gather` and probably others).
    - to code scheduled in a sync thread using `sync_to_async`

    In "sync" threads (a thread with no async event loop running), the
    data is thread-local, but additionally shared with async code executed
    via the `async_to_sync` utility, which schedules async code in a new thread
    and copies context across to that thread.

    If `thread_critical` is True, then the local will only be visible per-thread,
    behaving exactly like `threading.local` if the thread is sync, and as
    `contextvars` if the thread is async. This allows genuinely thread-sensitive
    code (such as DB handles) to be kept stricly to their initial thread and
    disable the sharing across `sync_to_async` and `async_to_sync` wrapped calls.

    Unlike plain `contextvars` objects, this utility is threadsafe.
    Fthread_criticalr   Nc                 C   s2   || _ t | _|  |rt | _d S t | _d S N)_thread_critical	threadingRLock_thread_locklocal_storager   )r   r%   r   r   r   r   D   s   
zLocal.__init__c                 c   s    | j r+zt  W n ty   | jV  Y d S w t| jds$t | j_| jjV  d S | j | jV  W d    d S 1 s>w   Y  d S )Ncvar)	r'   asyncioget_running_loopRuntimeErrorr,   hasattrr   r-   r*   r
   r   r   r   _lock_storageQ   s   

"zLocal._lock_storagec                 C   s6   |   }t||W  d    S 1 sw   Y  d S r&   )r2   getattrr   r   storager   r   r   r   t   s   
$zLocal.__getattr__c                    sP   |dv rt  ||S |  }t||| W d    d S 1 s!w   Y  d S )N)_localr,   r'   r*   )r   r   r2   setattr)r   r   r   r5   r   r   r   r   x   s
   
"zLocal.__setattr__c                 C   s8   |   }t|| W d    d S 1 sw   Y  d S r&   )r2   delattrr4   r   r   r   r   ~   s   
"zLocal.__delattr__)F)r   r   r    r!   boolr   
contextlibcontextmanagerr2   r   r   r   r#   r   r   r   r   r$   (   s    
"r$   )
r.   r:   r   r(   typingr   r   r   r   r$   r   r   r   r   <module>   s     