
    Mh0                        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mZ ddlZej        r
ddlmZmZmZ  ed          Zg d	Z G d
 de          Z G d de          Zdededeej        f         ddfdZ G d dee                   Z G d dee                   Z G d de          Z  G 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Optional)DequeTupleAny_T)QueuePriorityQueue	LifoQueue	QueueFull
QueueEmptyc                       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__     N/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/tornado/queues.pyr   r   /   s        DDDr   r   c                       e Zd ZdZdS )r   zBRaised by `.Queue.put_nowait` when a queue is at its maximum size.Nr   r   r   r   r   r   5   s        LLDr   r   futuretimeoutreturnc                      |rUd fd}t           j                                                            ||                               fd           d S d S )Nr"   c                                                        s(                     t          j                               d S d S N)doneset_exceptionr   TimeoutError)r    s   r   
on_timeoutz _set_timeout.<locals>.on_timeout@   s@    ;;== 9$$S%5%7%7888889 9r   c                 .                                   S r%   )remove_timeout)_io_looptimeout_handles    r   <lambda>z_set_timeout.<locals>.<lambda>F   s    7+A+A.+Q+Q r   r"   N)r   IOLoopcurrentadd_timeoutadd_done_callback)r    r!   r)   r-   r.   s   `  @@r   _set_timeoutr5   ;   s      S	9 	9 	9 	9 	9 	9 -'')) ,,WjAA  !Q!Q!Q!Q!QRRRRRS Sr   c                   .    e Zd ZddZdee         fdZdS )_QueueIteratorq	Queue[_T]r"   Nc                     || _         d S r%   )r8   )selfr8   s     r   __init__z_QueueIterator.__init__J   s    r   c                 4    | j                                         S r%   )r8   getr;   s    r   	__anext__z_QueueIterator.__anext__M   s    vzz||r   )r8   r9   r"   N)r   r   r   r<   r   r   r@   r   r   r   r7   r7   I   sG           9R=      r   r7   c                      e Zd ZdZdZddeddfdZedefd            ZdefdZ	de
fd	Zde
fd
Z	 ddedeeeej        f                  ddfdZdeddfdZ	 ddeeeej        f                  dee         fdZdefdZddZ	 ddeeeej        f                  ded         fdZdee         fdZddZdefdZdeddfdZdeddfdZddZ de!fdZ"de!fdZ#de!fdZ$dS ) r   a  Coordinate producer and consumer coroutines.

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

    .. testcode::

        import asyncio
        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 asyncio.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')

        asyncio.run(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                 R   |t          d          |dk     rt          d          || _        |                                  t	          j        g           | _        t	          j        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;   rB   s     r   r<   zQueue.__init__   s    ?3444Q;;8999

#)"--#)"--!"r   c                     | j         S )z%Number of items allowed in the queue.)rF   r?   s    r   rB   zQueue.maxsize   s     }r   c                 *    t          | j                  S )zNumber of items in the queue.)len_queuer?   s    r   qsizezQueue.qsize   s    4;r   c                     | j          S r%   rR   r?   s    r   emptyzQueue.empty   s    ;r   c                 V    | j         dk    rdS |                                 | j         k    S )Nr   F)rB   rS   r?   s    r   fullz
Queue.full   s)    <15::<<4<//r   itemr!   zFuture[None]c                     t                      }	 |                     |           |                    d           n<# t          $ r/ | j                            ||f           t          ||           Y nw xY w|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_nowait
set_resultr   rK   appendr5   )r;   rY   r!   r    s       r   putz	Queue.put   s     	$OOD!!!
 d####	  	* 	* 	*M  $000)))))	*
 s   ; 6A43A4c                 |   |                                   | j        rp|                                 s
J d            | j                                        }|                     |           t          ||                                            dS |                                 rt          |                     |           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_expiredrJ   rV   popleft_Queue__put_internalr   _getrX   r   )r;   rY   getters      r   r[   zQueue.put_nowait   s    
 	= 	&::<<LL!LLLL]**,,F%%%.vtyy{{CCCCCYY[[ 	&O%%%%%r   c                     t                      }	 |                    |                                            n:# t          $ r- | j                            |           t          ||           Y nw xY w|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   r\   
get_nowaitr   rJ   r]   r5   )r;   r!   r    s      r   r>   z	Queue.get   s    . 	*doo//0000 	* 	* 	*M  ((()))))	* s   '8 4A/.A/c                 |   |                                   | j        rs|                                 s
J d            | j                                        \  }}|                     |           t          |d           |                                 S |                                 r|                                 S t          )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)	r`   rK   rX   ra   rb   r   rc   rS   r   )r;   rY   putters      r   rf   zQueue.get_nowait   s     	= 		99;;JJ JJJJ=0022LD&%%%.vt<<<99;;ZZ\\ 	99;;r   c                     | j         dk    rt          d          | xj         dz  c_         | j         dk    r| j                                         dS 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)rL   rE   rM   rN   r?   s    r   	task_donezQueue.task_done  se     !Q&&@AAA!#!Q&&N      '&r   c                 6    | j                             |          S )zBlock until all items in the queue are processed.

        Returns an awaitable, which raises `tornado.util.TimeoutError` after a
        timeout.
        )rM   wait)r;   r!   s     r   joinz
Queue.join$  s     ~""7+++r   c                      t          |           S r%   )r7   r?   s    r   	__aiter__zQueue.__aiter__.  s    d###r   c                 6    t          j                    | _        d S r%   )rH   rI   rR   r?   s    r   rG   zQueue._init2  s    !'))r   c                 4    | j                                         S r%   )rR   ra   r?   s    r   rc   z
Queue._get5  s    {""$$$r   c                 :    | j                             |           d S r%   rR   r]   r;   rY   s     r   _putz
Queue._put8      4     r   c                     | xj         dz  c_         | j                                         |                     |           d S )Nrj   )rL   rM   clearrv   ru   s     r   __put_internalzQueue.__put_internal=  s=    !#		$r   c                    | j         rj| j         d         d                                         rE| j                                          | j         r%| j         d         d                                         E| j        r`| j        d                                         rE| j                                         | j        r#| j        d                                         ?d S d S d S d S )Nr   rj   )rK   r&   ra   rJ   r?   s    r   r`   zQueue._consume_expiredB  s    m 	$a 0 3 8 8 : : 	$M!!### m 	$a 0 3 8 8 : : 	$ m 	$a 0 5 5 7 7 	$M!!### m 	$a 0 5 5 7 7 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$r   c                     dt          |           j         dt          t          |                      d|                                  dS )N<z at  >)typer   hexid_formatr?   s    r   __repr__zQueue.__repr__J  s@    M4::&MMC4MMMMDLLNNMMMMr   c                 \    dt          |           j         d|                                  dS )Nr}   r~   r   )r   r   r   r?   s    r   __str__zQueue.__str__M  s,    :4::&::::::r   c                    d| j         }t          | dd           r|d| j        z  z  }| j        r|dt	          | j                  z  z  }| j        r|dt	          | j                  z  z  }| j        r|d| j        z  z  }|S )Nzmaxsize=rR   z	 queue=%rz getters[%s]z putters[%s]z	 tasks=%s)rB   getattrrR   rJ   rQ   rK   rL   )r;   results     r   r   zQueue._formatP  s    ,DL,,44(( 	0kDK//F= 	:ns4='9'999F= 	:ns4='9'999F! 	;kD$:::Fr   )r   r%   r0   )%r   r   r   r   rR   intr<   propertyrB   rS   boolrV   rX   r   r   r   floatdatetime	timedeltar^   r[   r   r>   rf   rk   rn   r7   rp   rG   rc   rv   rb   r`   strr   r   r   r   r   r   r   r   Q   s       A AJ F  D         X s        t    0d 0 0 0 0 OS !)%x7I0I*J!K	   .&r &d & & & &" EI eX-?&? @A	2   >B    $! ! ! !& EI, ,eX-?&? @A,	4, , , ,$>"- $ $ $ $* * * *%b % % % %! ! ! ! ! !
2 $    
$ $ $ $N# N N N N; ; ; ; ;
 
 
 
 
 
 
r   r   c                   6    e Zd ZdZddZdeddfdZdefdZdS )	r   a  A `.Queue` that retrieves entries in priority order, lowest first.

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

    .. testcode::

        import asyncio
        from tornado.queues import PriorityQueue

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

            print(await q.get())
            print(await q.get())
            print(await q.get())

        asyncio.run(main())

    .. testoutput::

        (0, 'high-priority item')
        (1, 'medium-priority item')
        (10, 'low-priority item')
    r"   Nc                     g | _         d S r%   rU   r?   s    r   rG   zPriorityQueue._initz      r   rY   c                 :    t          j        | j        |           d S r%   )heapqheappushrR   ru   s     r   rv   zPriorityQueue._put}  s    t{D)))))r   c                 4    t          j        | j                  S r%   )r   heappoprR   r?   s    r   rc   zPriorityQueue._get  s    }T[)))r   r0   r   r   r   r   rG   r   rv   rc   r   r   r   r   r   ]  so         8   * * * * * **b * * * * * *r   r   c                   6    e Zd ZdZddZdeddfdZdefdZdS )	r   a  A `.Queue` that retrieves the most recently put items first.

    .. testcode::

        import asyncio
        from tornado.queues import LifoQueue

        async def main():
            q = LifoQueue()
            q.put(3)
            q.put(2)
            q.put(1)

            print(await q.get())
            print(await q.get())
            print(await q.get())

        asyncio.run(main())

    .. testoutput::

        1
        2
        3
    r"   Nc                     g | _         d S r%   rU   r?   s    r   rG   zLifoQueue._init  r   r   rY   c                 :    | j                             |           d S r%   rt   ru   s     r   rv   zLifoQueue._put  rw   r   c                 4    | j                                         S r%   )rR   popr?   s    r   rc   zLifoQueue._get  s    {   r   r0   r   r   r   r   r   r     so         4   ! ! ! ! ! !!b ! ! ! ! ! !r   r   )"r   rH   r   r   tornador   r   tornado.concurrentr   r   tornado.locksr   typingr   r	   r
   r   r   TYPE_CHECKINGr   r   r   r   __all__	Exceptionr   r   r   r   r5   r7   r   r   r   r   r   r   <module>r      s?                  I I I I I I I I       ? ? ? ? ? ? ? ? ? ? ? ? ? ? 	 )((((((((((WT]]
L
L
L	 	 	 	 	 	 	 		 	 	 	 		 	 	 	SS"40B#BCS	S S S S    WR[   I I I I IGBK I I IX$* $* $* $* $*E $* $* $*N"! "! "! "! "! "! "! "! "! "!r   