o
    µ„j¨  ã                   @   sh   d dl Z d dlZd dlZd dlZd dlmZmZ G dd„ dƒZddd„ZG d	d
„ d
ƒZ	G dd„ dƒZ
dS )é    N)ÚAnyÚUnionc                   @   s2   e Zd ZdZdZdedeeef ddfdd„Z	dS )	Ú_Storagean  Thread-tagged storage for a non-thread-critical ``Local``.

    The data is tagged with the identity of the thread that owns it. This lets
    ``_CVar`` ignore data that leaked into an unrelated thread.

    Python 3.14 added ``sys.flags.thread_inherit_context``, which is enabled by
    default on free-threaded builds. When set, a new thread starts with a copy
    of the spawning thread's context instead of an empty one, so the contextvar
    backing a ``Local`` would otherwise be visible in any thread spawned from
    one that had set it -- breaking the documented "thread-local in sync
    threads" behaviour. asgiref re-homes the storage to the current thread at
    the points where it *intentionally* moves work between threads (see
    ``asgiref.sync._restore_context``); data merely inherited by an unrelated
    thread is never re-homed and so stays isolated.
    ©Ú	thread_idÚdatar   r   ÚreturnNc                 C   s   || _ || _d S ©Nr   )Úselfr   r   © r   úK/var/www/html/django_cbt/venv/lib/python3.10/site-packages/asgiref/local.pyÚ__init__   s   
z_Storage.__init__)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__ÚintÚdictÚstrr   r   r   r   r   r   r      s    "r   Ústorager   c                 C   s   t t ¡ | jƒS )z7Return a copy of *storage* owned by the current thread.)r   Ú	threadingÚ	get_identr   )r   r   r   r   Ú_rehome    s   r   c                       s\   e Zd ZdZdd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.r   Nc                 C   s   t  d¡| _d S )Nzasgiref.local)ÚcontextvarsÚ
ContextVarÚ_data)r
   r   r   r   r   (   s   
ÿz_CVar.__init__r   c                 C   s4   | j  d ¡}|d u s|jt ¡ krtt ¡ i ƒS |S r	   )r   Úgetr   r   r   r   )r
   r   r   r   r   Ú_storage-   s   z_CVar._storagec                 C   s2   z|   ¡ j| W S  ty   t| ›d|›�ƒ‚w ©Nz object has no attribute )r   r   ÚKeyErrorÚAttributeError)r
   Úkeyr   r   r   Ú__getattr__6   s
   ÿz_CVar.__getattr__r#   Úvaluec                    sF   |dkrt ƒ  ||¡S |  ¡ j ¡ }|||< | j tt 	¡ |ƒ¡ d S )Nr   )
ÚsuperÚ__setattr__r   r   Úcopyr   Úsetr   r   r   )r
   r#   r%   r   ©Ú	__class__r   r   r'   <   s
   z_CVar.__setattr__c                 C   sH   |   ¡ j ¡ }||v r||= | j tt ¡ |ƒ¡ d S t| ›d|›�ƒ‚r    )	r   r   r(   r   r)   r   r   r   r"   )r
   r#   r   r   r   r   Ú__delattr__D   s
   z_CVar.__delattr__)r   N)r   r   )r   r   r   r   r   r   r$   r   r   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 strictly 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 r	   )Ú_thread_criticalr   ÚRLockÚ_thread_lockÚlocalr   r   )r
   r/   r   r   r   r   i   s   
zLocal.__init__c                 c   s˜   � | j r2d}zt ¡  W n ty   d}Y nw |s | jV  d S t| jdƒs+tƒ | j_| jjV  d S | j� | jV  W d   ƒ d S 1 sEw   Y  d S )NTFÚcvar)	r0   ÚasyncioÚget_running_loopÚRuntimeErrorr   Úhasattrr   r4   r2   )r
   Úis_asyncr   r   r   Ú_lock_storagev   s    €ÿ

"ÿzLocal._lock_storagec                 C   s6   |   ¡ �}t||ƒW  d   ƒ S 1 sw   Y  d S r	   )r:   Úgetattr©r
   r#   r   r   r   r   r$   œ   s   
$ÿzLocal.__getattr__c                    sP   |dv rt ƒ  ||¡S |  ¡ �}t|||ƒ W d   ƒ d S 1 s!w   Y  d S )N)Ú_localr   r0   r2   )r&   r'   r:   Úsetattr)r
   r#   r%   r   r*   r   r   r'       s
   
"ÿzLocal.__setattr__c                 C   s8   |   ¡ �}t||ƒ W d   ƒ d S 1 sw   Y  d S r	   )r:   Údelattrr<   r   r   r   r,   ¦   s   
"ÿzLocal.__delattr__)F)r   r   r   r   Úboolr   Ú
contextlibÚcontextmanagerr:   r$   r'   r,   r-   r   r   r*   r   r.   M   s    
%r.   )r   r   r   r   )r5   rA   r   r   Útypingr   r   r   r   r   r.   r   r   r   r   Ú<module>   s    
(