
    ir5                         d Z ddlmZmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddgZ G d	 d
e          Z e            Z G d de          Zd ZdS )a  
Timeouts.

Many functions in :mod:`gevent` have a *timeout* argument that allows
limiting the time the function will block. When that is not available,
the :class:`Timeout` class and :func:`with_timeout` function in this
module add timeouts to arbitrary code.

.. warning::

    Timeouts can only work when the greenlet switches to the hub.
    If a blocking function is called or an intense calculation is ongoing during
    which no switches occur, :class:`Timeout` is powerless.
    )absolute_importprint_functiondivision)string_types)_NONE)
getcurrent)get_hub_noargsTimeoutwith_timeoutc                   n    e Zd ZdZed             ZeZed             ZexZZ	d Z
d ZeZexZZd Zd ZdS )	
_FakeTimer c                     dS )NFr   selfs    9/usr/local/lib/python3.11/dist-packages/gevent/timeout.pypendingz_FakeTimer.pending(   s    u    c                     dS )zAlways returns NoneNr   r   s    r   secondsz_FakeTimer.seconds.   s      r   c                      t          d          )Nz$non-expiring timer cannot be started)AssertionError)r   argskwargss      r   startz_FakeTimer.start4   s    CDDDr   c                     d S Nr   r   s    r   stopz_FakeTimer.stop8       r   c                     | S r   r   r   s    r   	__enter__z_FakeTimer.__enter__?   s    r   c                     d S r   r   )r   _t_v_tbs       r   __exit__z_FakeTimer.__exit__B   r   r   N)__name__
__module____qualname__	__slots__propertyr   activer   timer	exceptionr   r   cancelcloser!   r&   r   r   r   r   r      s         I  X F  X  EIE E E   FD5      r   r   c                       e Zd ZdZ	 	 ddZd Zd Zedd	            Ze	dd
            Z
ed             Zd Zd Zd Zd Zd Zd Zd ZdS )r
   a  
    Timeout(seconds=None, exception=None, ref=True, priority=-1)

    Raise *exception* in the current greenlet after *seconds*
    have elapsed::

        timeout = Timeout(seconds, exception)
        timeout.start()
        try:
            ...  # exception will be raised here, after *seconds* passed since start() call
        finally:
            timeout.close()

    .. warning::

        You must **always** call `close` on a ``Timeout`` object you have created,
        whether or not the code that the timeout was protecting finishes
        executing before the timeout elapses (whether or not the
        ``Timeout`` exception is raised)  This ``try/finally``
        construct or a ``with`` statement is a good pattern. (If
        the timeout object will be started again, use `cancel` instead
        of `close`; this is rare. You must still `close` it when you are
        done.)

    When *exception* is omitted or ``None``, the ``Timeout`` instance
    itself is raised::

        >>> import gevent
        >>> gevent.Timeout(0.1).start()
        >>> gevent.sleep(0.2)  #doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
         ...
        Timeout: 0.1 seconds

    If the *seconds* argument is not given or is ``None`` (e.g.,
    ``Timeout()``), then the timeout will never expire and never raise
    *exception*. This is convenient for creating functions which take
    an optional timeout parameter of their own. (Note that this is **not**
    the same thing as a *seconds* value of ``0``.)

    ::

       def function(args, timeout=None):
          "A function with an optional timeout."
          timer = Timeout(timeout)
          with timer:
             ...

    .. caution::

        A *seconds* value less than ``0.0`` (e.g., ``-1``) is poorly defined. In the future,
        support for negative values is likely to do the same thing as a value
        of ``None`` or ``0``

    A *seconds* value of ``0`` requests that the event loop spin and poll for I/O;
    it will immediately expire as soon as control returns to the event loop.

    .. rubric:: Use As A Context Manager

    To simplify starting and canceling timeouts, the ``with``
    statement can be used::

        with gevent.Timeout(seconds, exception) as timeout:
            pass  # ... code block ...

    This is equivalent to the try/finally block above with one
    additional feature: if *exception* is the literal ``False``, the
    timeout is still raised, but the context manager suppresses it, so
    the code outside the with-block won't see it.

    This is handy for adding a timeout to the functions that don't
    support a *timeout* parameter themselves::

        data = None
        with gevent.Timeout(5, False):
            data = mysock.makefile().readline()
        if data is None:
            ...  # 5 seconds passed without reading a line
        else:
            ...  # a line was read within 5 seconds

    .. caution::

        If ``readline()`` above catches and doesn't re-raise
        :exc:`BaseException` (for example, with a bare ``except:``), then
        your timeout will fail to function and control won't be returned
        to you when you expect.

    .. rubric:: Catching Timeouts

    When catching timeouts, keep in mind that the one you catch may
    not be the one you have set (a calling function may have set its
    own timeout); if you are going to silence a timeout, always check that
    it's the instance you need::

        timeout = Timeout(1)
        timeout.start()
        try:
            ...
        except Timeout as t:
            if t is not timeout:
                raise # not my timeout
        finally:
            timeout.close()


    .. versionchanged:: 1.1b2

        If *seconds* is not given or is ``None``, no longer allocate a
        native timer object that will never be started.

    .. versionchanged:: 1.1

        Add warning about negative *seconds* values.

    .. versionchanged:: 1.3a1

        Timeout objects now have a :meth:`close`
        method that *must* be called when the timeout will no longer be
        used to properly clean up native resources.
        The ``with`` statement does this automatically.

    .. versionchanged:: 24.10.1

          Timeout values can be compared to be less than an integer value,
          or to be less than other timeouts, e.g., ``Timeout(0) < 1`` is true.
          Timeouts are not absolutely ordered and support no other comparisons; this
          is purely for convenience and may be removed or altered in the future.

    NTFc                     t                               |            || _        || _        || _        |t
          | _        d S t                      j                            |pd||          | _        d S )Ng        )refpriority)	BaseException__init__r   r.   	_one_shotr   r-   get_hubloop)r   r   r.   r4   r5   r8   s         r   r7   zTimeout.__init__   sj    t$$$""? $DJJJ !--gn#PX-YYDJJJr   c                    | j         rt          d| z            | j        dS | j        #| j        du st	          | j        t
                    r| }n| j        }| j                            | j        t                      |d           dS )zSchedule the timeout.z5%r is already started; to restart it, cancel it firstNFT)update)
r   r   r   r.   
isinstancer   r-   r   _on_expirationr   )r   throwss     r   r   zTimeout.start   s    < 	a !X[_!_```<F>!T^u%<%<
4>[g@h@h%<FF ^F 	
,jllF4PPPPPr   c                 0    |                     |           d S r   )throw)r   prev_greenletexs      r   r>   zTimeout._on_expiration   s    Br   c                     t          |t                    r|j        s|                                 |S  | ||||          }|                                 |S )a  Create a started :class:`Timeout`.

        This is a shortcut, the exact action depends on *timeout*'s type:

        * If *timeout* is a :class:`Timeout`, then call its :meth:`start` method
          if it's not already begun.
        * Otherwise, create a new :class:`Timeout` instance, passing (*timeout*, *exception*) as
          arguments, then call its :meth:`start` method.

        Returns the :class:`Timeout` instance.
        )r4   r8   )r=   r
   r   r   )clstimeoutr.   r4   r8   s        r   	start_newzTimeout.start_new   s\     gw'' 	?  N#gycYGGGr   c                 P    | t           S t                              | ||d          S )NTr8   )r   r
   rG   )rF   r.   r4   s      r   _start_new_or_dummyzTimeout._start_new_or_dummy  s,    " ?  )SD IIIr   c                 2    | j         j        p| j         j        S )z.True if the timeout is scheduled to be raised.)r-   r   r,   r   s    r   r   zTimeout.pending%  s     z!6TZ%66r   c                 r    | j                                          | j        r|                                  dS dS )z
        If the timeout is pending, cancel it. Otherwise, do nothing.

        The timeout object can be :meth:`started <start>` again. If
        you will not start the timeout again, you should use
        :meth:`close` instead.
        N)r-   r   r8   r0   r   s    r   r/   zTimeout.cancel*  s;     	
> 	JJLLLLL	 	r   c                     | j                                          | j                                          t          | _         dS )z
        Close the timeout and free resources. The timer cannot be started again
        after this method has been used.
        N)r-   r   r0   r   r   s    r   r0   zTimeout.close6  s5    
 	




r   c           	          t          |           j        }| j        rd}nd}| j        d}n
d| j        z  }d|dt	          t          |                     d| j        ||d	S )Nz pending z exception=%r<z at z	 seconds=>)typer'   r   r.   hexidr   )r   	classnamer   r.   s       r   __repr__zTimeout.__repr__?  sv    JJ'	< 	 GGG>!II'$.8I.7iiRXXV_V_ahahahiir   c                     | j         dS | j         dk    rdnd}| j        | j         d|S | j        du r| j         d|dS | j         d|d| j        S )	z
        >>> raise Timeout #doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
            ...
        Timeout
        NrO      sz secondFz	 (silent)z: )r   r.   )r   suffixs     r   __str__zTimeout.__str__K  s~     <2|q((c>!$(LLL&&99>U""-1\\\666BB$(LLL&&&$..IIr   c                 <    | j         s|                                  | S )z^
        Start and return the timer. If the timer is already started, just return it.
        )r   r   r   s    r   r!   zTimeout.__enter__]  s      | 	JJLLLr   c                 P    |                                   || u r| j        du rdS dS dS )z
        Stop the timer.

        .. versionchanged:: 1.3a1
           The underlying native timer is also stopped. This object cannot be
           used again.
        FTN)r0   r.   )r   typvaluetbs       r   r&   zTimeout.__exit__e  s8     	

D==T^u444 =44r   c                     	 | j         |j         k     S # t          $ r( 	 | j         |k     cY S # t          $ r t          cY cY S w xY ww xY w)zw
        For convenience, timeouts can be compared to integers (numbers)
        based on their seconds value.
        )r   AttributeError	TypeErrorNotImplemented)r   others     r   __lt__zTimeout.__lt__q  sv    
	&<%-// 	& 	& 	&&|e++++ & & &%%%%%%&	&s'    
A
*AA AA  A)NNTr2   F)NNTF)NT)r'   r(   r)   __doc__r7   r   r>   classmethodrG   staticmethodrJ   r+   r   r/   r0   rV   r[   r!   r&   rf   r   r   r   r
   r
   H   s2       A AL IK Z Z Z Z(Q Q Q(         [( J J J \J( 7 7 X7
 
 
     
j 
j 
jJ J J$  
 
 
& & & & &r   c                 T   |                     dt                    }t                              | d          }	 	  ||i ||                                 S # t          $ r.}||u r$|t          ur|cY d}~|                                 S  d}~ww xY w# |                                 w xY w)aZ  Wrap a call to *function* with a timeout; if the called
    function fails to return before the timeout, cancel it and return a
    flag value, provided by *timeout_value* keyword argument.

    If timeout expires but *timeout_value* is not provided, raise :class:`Timeout`.

    Keyword argument *timeout_value* is not passed to *function*.
    timeout_valueTrI   N)popr   r
   rG   r/   )r   functionr   kwdsrk   rF   rC   s          r   r   r   ~  s     HH_e44M488G	8T*T** 	  	 	 	W}}e!;!;$$$$$$ 	 	
 	s5   A 
B B	.B/B B		BB B'N)rg   
__future__r   r   r   gevent._compatr   gevent._utilr   greenletr   gevent._hub_localr	   r9   __all__objectr   r6   r
   r   r   r   r   <module>rv      s    A @ @ @ @ @ @ @ @ @ ' ' ' ' ' '             7 7 7 7 7 7 % % % % % % % %N Z\\
t& t& t& t& t&m t& t& t&l	    r   