B
    h/                 @   s&  d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	 ddl
mZ ddlmZmZmZmZ ddlZejrddlmZmZmZmZ edZd	d
dddgZG dd deZG dd deZeedeejf ddddZG dd dee ZG dd	 d	ee ZG dd
 d
eZ G dd deZ!dS )a  Asynchronous queues for coroutines. These classes are very similar
to those provided in the standard library's `asyncio package
<https://docs.python.org/3/library/asyncio-queue.html>`_.

.. warning::

   Unlike the standard library's `queue` module, the classes defined here
   are *not* thread-safe. To use these queues from another thread,
   use `.IOLoop.add_callback` to transfer control to the `.IOLoop` thread
   before calling any queue methods.

    N)genioloop)Future"future_set_result_unless_cancelled)Event)UnionTypeVarGeneric	Awaitable)DequeTupleListAny_TQueuePriorityQueue	LifoQueue	QueueFull
QueueEmptyc               @   s   e Zd ZdZdS )r   z:Raised by `.Queue.get_nowait` when the queue has no items.N)__name__
__module____qualname____doc__ r   r   KC:\Users\sanjo\AppData\Local\Qlobot\Launcher\ext_packages\tornado\queues.pyr   /   s   c               @   s   e Zd ZdZdS )r   zBRaised by `.Queue.put_nowait` when a queue is at its maximum size.N)r   r   r   r   r   r   r   r   r   5   s   )futuretimeoutreturnc                sD   |r@d d fdd}t j || fdd d S )N)r   c                  s      s t  d S )N)doneset_exceptionr   TimeoutErrorr   )r   r   r   
on_timeout@   s    z _set_timeout.<locals>.on_timeoutc                s
     S )N)remove_timeout)_)io_looptimeout_handler   r   <lambda>F       z_set_timeout.<locals>.<lambda>)r   IOLoopcurrentadd_timeoutadd_done_callback)r   r   r!   r   )r   r$   r%   r   _set_timeout;   s
    
r,   c               @   s.   e Zd ZdddddZee dddZdS )	_QueueIteratorz	Queue[_T]N)qr   c             C   s
   || _ d S )N)r.   )selfr.   r   r   r   __init__J   s    z_QueueIterator.__init__)r   c             C   s
   | j  S )N)r.   get)r/   r   r   r   	__anext__M   s    z_QueueIterator.__anext__)r   r   r   r0   r
   r   r2   r   r   r   r   r-   I   s   r-   c               @   sr  e Zd ZdZdZd2eddddZeeddd	Zedd
dZ	e
dddZe
dddZd3eeeejf ddddZeddddZd4eeejf ee dddZedddZddddZd5eeejf ed dddZee dd d!Zddd"d#Zedd$d%Zeddd&d'Zeddd(d)Zddd*d+Ze dd,d-Z!e dd.d/Z"e dd0d1Z#dS )6r   a  Coordinate producer and consumer coroutines.

    If maxsize is 0 (the default) the queue size is unbounded.

    .. testcode::

        from tornado import gen
        from tornado.ioloop import IOLoop
        from tornado.queues import Queue

        q = Queue(maxsize=2)

        async def consumer():
            async for item in q:
                try:
                    print('Doing work on %s' % item)
                    await gen.sleep(0.01)
                finally:
                    q.task_done()

        async def producer():
            for item in range(5):
                await q.put(item)
                print('Put %s' % item)

        async def main():
            # Start consumer without waiting (since it never finishes).
            IOLoop.current().spawn_callback(consumer)
            await producer()     # Wait for producer to put all tasks.
            await q.join()       # Wait for consumer to finish all tasks.
            print('Done')

        IOLoop.current().run_sync(main)

    .. testoutput::

        Put 0
        Put 1
        Doing work on 0
        Put 2
        Doing work on 1
        Put 3
        Doing work on 2
        Put 4
        Doing work on 3
        Doing work on 4
        Done


    In versions of Python without native coroutines (before 3.5),
    ``consumer()`` could be written as::

        @gen.coroutine
        def consumer():
            while True:
                item = yield q.get()
                try:
                    print('Doing work on %s' % item)
                    yield gen.sleep(0.01)
                finally:
                    q.task_done()

    .. versionchanged:: 4.3
       Added ``async for`` support in Python 3.5.

    Nr   )maxsizer   c             C   sb   |d krt d|dk r td|| _|   tg | _tg | _d| _t	 | _
| j
  d S )Nzmaxsize can't be Noner   zmaxsize can't be negative)	TypeError
ValueError_maxsize_initcollectionsdeque_getters_putters_unfinished_tasksr   	_finishedset)r/   r3   r   r   r   r0      s    zQueue.__init__)r   c             C   s   | j S )z%Number of items allowed in the queue.)r6   )r/   r   r   r   r3      s    zQueue.maxsizec             C   s
   t | jS )zNumber of items in the queue.)len_queue)r/   r   r   r   qsize   s    zQueue.qsizec             C   s   | j  S )N)r@   )r/   r   r   r   empty   s    zQueue.emptyc             C   s    | j dkrdS |  | j kS d S )Nr   F)r3   rA   )r/   r   r   r   full   s    
z
Queue.fullzFuture[None])itemr   r   c             C   sR   t  }y| | W n. tk
rB   | j||f t|| Y nX |d |S )a  Put an item into the queue, perhaps waiting until there is room.

        Returns a Future, which raises `tornado.util.TimeoutError` after a
        timeout.

        ``timeout`` may be a number denoting a time (on the same
        scale as `tornado.ioloop.IOLoop.time`, normally `time.time`), or a
        `datetime.timedelta` object for a deadline relative to the
        current time.
        N)r   
put_nowaitr   r;   appendr,   
set_result)r/   rD   r   r   r   r   r   put   s    
z	Queue.put)rD   r   c             C   s^   |    | jrB|  std| j }| | t||   n|  rPt	n
| | dS )z{Put an item into the queue without blocking.

        If no free slot is immediately available, raise `QueueFull`.
        z)queue non-empty, why are getters waiting?N)
_consume_expiredr:   rB   AssertionErrorpopleft_Queue__put_internalr   _getrC   r   )r/   rD   getterr   r   r   rE      s    

zQueue.put_nowait)r   r   c             C   sH   t  }y||   W n* tk
rB   | j| t|| Y nX |S )a.  Remove and return an item from the queue.

        Returns an awaitable which resolves once an item is available, or raises
        `tornado.util.TimeoutError` after a timeout.

        ``timeout`` may be a number denoting a time (on the same
        scale as `tornado.ioloop.IOLoop.time`, normally `time.time`), or a
        `datetime.timedelta` object for a deadline relative to the
        current time.

        .. note::

           The ``timeout`` argument of this method differs from that
           of the standard library's `queue.Queue.get`. That method
           interprets numeric values as relative timeouts; this one
           interprets them as absolute deadlines and requires
           ``timedelta`` objects for relative timeouts (consistent
           with other timeouts in Tornado).

        )r   rG   
get_nowaitr   r:   rF   r,   )r/   r   r   r   r   r   r1      s    z	Queue.getc             C   s`   |    | jrH|  std| j \}}| | t|d |  S |  rX|  S t	dS )zRemove and return an item from the queue without blocking.

        Return an item if one is immediately available, else raise
        `QueueEmpty`.
        z(queue not full, why are putters waiting?N)
rI   r;   rC   rJ   rK   rL   r   rM   rA   r   )r/   rD   putterr   r   r   rO      s    

zQueue.get_nowaitc             C   s8   | j dkrtd|  j d8  _ | j dkr4| j  dS )a  Indicate that a formerly enqueued task is complete.

        Used by queue consumers. For each `.get` used to fetch a task, a
        subsequent call to `.task_done` tells the queue that the processing
        on the task is complete.

        If a `.join` is blocking, it resumes when all items have been
        processed; that is, when every `.put` is matched by a `.task_done`.

        Raises `ValueError` if called more times than `.put`.
        r   z!task_done() called too many times   N)r<   r5   r=   r>   )r/   r   r   r   	task_done  s
    

zQueue.task_donec             C   s   | j |S )zBlock until all items in the queue are processed.

        Returns an awaitable, which raises `tornado.util.TimeoutError` after a
        timeout.
        )r=   wait)r/   r   r   r   r   join"  s    z
Queue.joinc             C   s   t | S )N)r-   )r/   r   r   r   	__aiter__*  s    zQueue.__aiter__c             C   s   t  | _d S )N)r8   r9   r@   )r/   r   r   r   r7   .  s    zQueue._initc             C   s
   | j  S )N)r@   rK   )r/   r   r   r   rM   1  s    z
Queue._getc             C   s   | j | d S )N)r@   rF   )r/   rD   r   r   r   _put4  s    z
Queue._putc             C   s&   |  j d7  _ | j  | | d S )NrQ   )r<   r=   clearrV   )r/   rD   r   r   r   Z__put_internal9  s    
zQueue.__put_internalc             C   sP   x&| j r&| j d d  r&| j   qW x"| jrJ| jd  rJ| j  q*W d S )Nr   rQ   )r;   r   rK   r:   )r/   r   r   r   rI   >  s    zQueue._consume_expiredc             C   s    dt | jtt| |  f S )Nz<%s at %s %s>)typer   hexid_format)r/   r   r   r   __repr__F  s    zQueue.__repr__c             C   s   dt | j|  f S )Nz<%s %s>)rX   r   r[   )r/   r   r   r   __str__I  s    zQueue.__str__c             C   sn   d| j f }t| dd r&|d| j 7 }| jr>|dt| j 7 }| jrV|dt| j 7 }| jrj|d| j 7 }|S )Nz
maxsize=%rr@   z	 queue=%rz getters[%s]z putters[%s]z	 tasks=%s)r3   getattrr@   r:   r?   r;   r<   )r/   resultr   r   r   r[   L  s    zQueue._format)r   )N)N)N)$r   r   r   r   r@   intr0   propertyr3   rA   boolrB   rC   r   r   floatdatetime	timedeltarH   rE   r
   r1   rO   rR   rT   r-   rU   r7   rM   rV   rL   rI   strr\   r]   r[   r   r   r   r   r   Q   s0   B  c               @   s<   e Zd ZdZddddZeddddZedd	d
ZdS )r   aC  A `.Queue` that retrieves entries in priority order, lowest first.

    Entries are typically tuples like ``(priority number, data)``.

    .. testcode::

        from tornado.queues import PriorityQueue

        q = PriorityQueue()
        q.put((1, 'medium-priority item'))
        q.put((0, 'high-priority item'))
        q.put((10, 'low-priority item'))

        print(q.get_nowait())
        print(q.get_nowait())
        print(q.get_nowait())

    .. testoutput::

        (0, 'high-priority item')
        (1, 'medium-priority item')
        (10, 'low-priority item')
    N)r   c             C   s
   g | _ d S )N)r@   )r/   r   r   r   r7   r  s    zPriorityQueue._init)rD   r   c             C   s   t | j| d S )N)heapqheappushr@   )r/   rD   r   r   r   rV   u  s    zPriorityQueue._putc             C   s   t | jS )N)rg   heappopr@   )r/   r   r   r   rM   x  s    zPriorityQueue._get)r   r   r   r   r7   r   rV   rM   r   r   r   r   r   Y  s   c               @   s<   e Zd ZdZddddZeddddZedd	d
ZdS )r   a]  A `.Queue` that retrieves the most recently put items first.

    .. testcode::

        from tornado.queues import LifoQueue

        q = LifoQueue()
        q.put(3)
        q.put(2)
        q.put(1)

        print(q.get_nowait())
        print(q.get_nowait())
        print(q.get_nowait())

    .. testoutput::

        1
        2
        3
    N)r   c             C   s
   g | _ d S )N)r@   )r/   r   r   r   r7     s    zLifoQueue._init)rD   r   c             C   s   | j | d S )N)r@   rF   )r/   rD   r   r   r   rV     s    zLifoQueue._putc             C   s
   | j  S )N)r@   pop)r/   r   r   r   rM     s    zLifoQueue._get)r   r   r   r   r7   r   rV   rM   r   r   r   r   r   |  s   )"r   r8   rd   rg   tornador   r   tornado.concurrentr   r   Ztornado.locksr   typingr   r   r	   r
   TYPE_CHECKINGr   r   r   r   r   __all__	Exceptionr   r   rc   re   r,   r-   r   r   r   r   r   r   r   <module>   s,     
#