ó
úR‹_c           @` s°   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 d	 e f d
 „  ƒ  YZ e ƒ  Z d e f d „  ƒ  YZ d „  Z d S(   sã  
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.
i    (   t   absolute_importt   print_functiont   division(   t   string_types(   t   _NONE(   t
   getcurrent(   t   get_hub_noargst   Timeoutt   with_timeoutt
   _FakeTimerc           B` sp   e  Z d Z e d  „  ƒ Z e Z e d „  ƒ Z e Z Z d „  Z	 d „  Z
 e
 Z e Z
 Z d „  Z d „  Z RS(   c         C` s   t  S(   N(   t   False(   t   self(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   pending(   s    c         C` s   d S(   s   Always returns NoneN(    (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   seconds.   t    c         O` s   t  d ƒ ‚ d  S(   Ns$   non-expiring timer cannot be started(   t   AssertionError(   R   t   argst   kwargs(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   start4   s    c         C` s   d  S(   N(    (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   stop8   s    c         C` s   |  S(   N(    (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt	   __enter__?   s    c         C` s   d  S(   N(    (   R   t   _tt   _vt   _tb(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   __exit__B   s    (    (   t   __name__t
   __module__t	   __slots__t   propertyR   t   activeR   t   timert	   exceptionR   R   t   cancelt   closeR   R   (    (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR	      s   
		
	c           B` s¤   e  Z d  Z d d e d e d „ Z d „  Z e d d e e d „ ƒ Z	 e
 d e d „ ƒ Z e d „  ƒ Z d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z RS(   sS  
    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()

    .. note::

        If the code that the timeout was protecting finishes
        executing before the timeout elapses, be sure to ``close`` the
        timeout so it is not unexpectedly raised in the future. Even if it
        is raised, it is a best practice to close it. This ``try/finally``
        construct or a ``with`` statement is a recommended pattern. (If
        the timeout object will be started again, use ``cancel`` instead
        of ``close``; this is rare.)

    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 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.

    iÿÿÿÿc         C` sn   t  j |  ƒ | |  _ | |  _ | |  _ | d  k r@ t |  _ n* t ƒ  j	 j | pU d d | d | ƒ|  _ d  S(   Ng        t   reft   priority(
   t   BaseExceptiont   __init__R   R   t	   _one_shott   NoneR	   R   t   get_hubt   loop(   R   R   R   R"   R#   R&   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR%   Ç   s    			c         C` s”   |  j  r t d |  ƒ ‚ n  |  j d k r/ d S|  j d k s_ |  j t k s_ t |  j t ƒ rh |  } n	 |  j } |  j j	 t
 ƒ  j | d t ƒd S(   s   Schedule the timeout.s5   %r is already started; to restart it, cancel it firstNt   update(   R   R   R   R'   R   R
   t
   isinstanceR   R   R   R   t   throwt   True(   R   t   throws(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR   Û   s    	0		c         C` sR   t  | t ƒ r) | j s% | j ƒ  n  | S|  | | d | d | ƒ} | j ƒ  | S(   s·  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.
        R"   R&   (   R+   R   R   R   (   t   clst   timeoutR   R"   R&   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt	   start_newï   s    	
c         C` s)   |  d  k r t St j |  | | d t ƒS(   NR&   (   R'   R	   R   R1   R-   (   R0   R   R"   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   _start_new_or_dummy  s    c         C` s   |  j  j p |  j  j S(   s.   True if the timeout is scheduled to be raised.(   R   R   R   (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR     s    c         C` s'   |  j  j ƒ  |  j r# |  j ƒ  n  d S(   sï   
        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   R&   R!   (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR      s    	c         C` s'   |  j  j ƒ  |  j  j ƒ  t |  _  d S(   s‚   
        Close the timeout and free resources. The timer cannot be started again
        after this method has been used.
        N(   R   R   R!   R	   (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR!   &  s    c         C` sr   t  |  ƒ j } |  j r! d } n d } |  j d  k r? d } n d |  j } d | t t |  ƒ ƒ |  j | | f S(   Ns    pendingR   s    exception=%rs   <%s at %s seconds=%s%s%s>(   t   typeR   R   R   R'   t   hext   idR   (   R   t	   classnameR   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   __repr__/  s    			c         C` s…   |  j  d k r d S|  j  d k r( d n d } |  j d k rN d |  j  | f S|  j t k rn d |  j  | f Sd |  j  | |  j f S(   s‘   
        >>> raise Timeout #doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
            ...
        Timeout
        R   i   t   ss   %s second%ss   %s second%s (silent)s   %s second%s: %sN(   R   R'   R   R
   (   R   t   suffix(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   __str__;  s    c         C` s   |  j  s |  j ƒ  n  |  S(   s^   
        Start and return the timer. If the timer is already started, just return it.
        (   R   R   (   R   (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR   M  s    	c         C` s-   |  j  ƒ  | |  k r) |  j t k r) t Sd S(   s©   
        Stop the timer.

        .. versionchanged:: 1.3a1
           The underlying native timer is also stopped. This object cannot be
           used again.
        N(   R!   R   R
   R-   (   R   t   typt   valuet   tb(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR   U  s    
N(   R   R   t   __doc__R'   R-   R
   R%   R   t   classmethodR1   t   staticmethodR2   R   R   R    R!   R7   R:   R   R   (    (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR   H   s   z							c         O` sƒ   | j  d t ƒ } t j |  d t ƒ} zJ y | | | Ž  SWn2 t k
 ro } | | k ri | t k	 ri | S‚  n XWd | j ƒ  Xd S(   sZ  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*.
    t   timeout_valueR&   N(   t   popR   R   R1   R-   R    (   R   t   functionR   t   kwdsRA   R0   t   ex(    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyR   b  s    	N(   R>   t
   __future__R    R   R   t   gevent._compatR   t   gevent._utilR   t   greenletR   t   gevent._hub_localR   R(   t   __all__t   objectR	   R$   R   R   (    (    (    sG   /var/www/syncserver/local/lib/python2.7/site-packages/gevent/timeout.pyt   <module>   s   	'	ÿ 