3
'h`J                 @   s^   d dl Z d dlZd dlmZ d dlmZmZmZ ejdkZ	G dd dZ
e jdd	d
dZdS )    N)TracebackType)AnyOptionalType      c               @   s   e Zd ZdZddee eej ddddZd ddd	Z	e
e eeee d
ddZd dddZe
e eedd
ddZeedddZeee dddZd dddZe
e ddddZddddZdS )timeouta  timeout context manager.

    Useful in cases when you want to apply timeout logic around block
    of code or in cases when asyncio.wait_for is not suitable. For example:

    >>> with timeout(0.001):
    ...     async with aiohttp.get('https://github.com') as r:
    ...         await r.text()


    timeout - value in seconds or None to disable timeout logic
    loop - asyncio compatible event loop
    N)loop)r   r	   returnc            C   s8   || _ |d krtj }|| _d | _d| _d | _d | _d S )NF)_timeoutasyncioZget_event_loop_loop_task
_cancelled_cancel_handler
_cancel_at)selfr   r	    r   2/tmp/pip-build-wz6naw8h/asgiref/asgiref/timeout.py__init__    s    ztimeout.__init__)r
   c             C   s   | j  S )N)	_do_enter)r   r   r   r   	__enter__/   s    ztimeout.__enter__)exc_typeexc_valexc_tbr
   c             C   s   | j | d S )N)_do_exit)r   r   r   r   r   r   r   __exit__2   s    
ztimeout.__exit__c                s   | j  S )N)r   )r   r   r   r   
__aenter__;   s    ztimeout.__aenter__c                s   | j | d S )N)r   )r   r   r   r   r   r   r   	__aexit__>   s    ztimeout.__aexit__c             C   s   | j S )N)r   )r   r   r   r   expiredF   s    ztimeout.expiredc             C   s(   | j d k	r t| j | jj  dS d S d S )Ng        )r   maxr   time)r   r   r   r   	remainingJ   s    
ztimeout.remainingc             C   sr   | j d kr| S t| j| _| jd kr,td| j dkrH| jj| j | S | jj | j  | _| jj	| j| j| _
| S )Nz4Timeout context manager should be used inside a taskr   )r   current_taskr   r   RuntimeErrorZ	call_soon_cancel_taskr!   r   Zcall_atr   )r   r   r   r   r   Q   s    


ztimeout._do_enter)r   r
   c             C   sP   |t jkr"| jr"d | _d | _t j| jd k	rF| jd k	rF| jj  d | _d | _d S )N)r   ZCancelledErrorr   r   r   TimeoutErrorr   cancel)r   r   r   r   r   r   e   s    
ztimeout._do_exitc             C   s   | j d k	r| j j  d| _d S )NT)r   r'   r   )r   r   r   r   r%   p   s    

ztimeout._cancel_task)__name__
__module____qualname____doc__r   floatr   AbstractEventLoopr   r   r   BaseExceptionr   boolr   r   r   propertyr   r"   r   r   r%   r   r   r   r   r      s(   
r   zasyncio.Task[Any])r	   r
   c             C   s>   t rtj| d}ntjj| d}|d kr:t| dr:| j }|S )N)r	   r#   )PY_37r   r#   ZTaskhasattr)r	   Ztaskr   r   r   r#   v   s    
r#   )r   r   )r   systypesr   Ztypingr   r   r   version_infor1   r   r-   r#   r   r   r   r   <module>	   s   
e