
    Vi                         S r SSKJrJr  SSKJr  SSKr SSKJr  \" SS9r	 SSKJr  / S	Qr " S
 S\5      r " S S\5      r " S S\5      r\rg! \
 a
    \" 5       r	 N>f = f! \
 a    \r NEf = f)a  Python comes with a many great data structures, from :class:`dict`
to :class:`collections.deque`, and no shortage of serviceable
algorithm implementations, from :func:`sorted` to :mod:`bisect`. But
priority queues are curiously relegated to an example documented in
:mod:`heapq`. Even there, the approach presented is not full-featured
and object-oriented. There is a built-in priority queue,
:class:`Queue.PriorityQueue`, but in addition to its austere API, it
carries the double-edged sword of threadsafety, making it fine for
multi-threaded, multi-consumer applications, but high-overhead for
cooperative/single-threaded use cases.

The ``queueutils`` module currently provides two Queue
implementations: :class:`HeapPriorityQueue`, based on a heap, and
:class:`SortedPriorityQueue`, based on a sorted list. Both use a
unified API based on :class:`BasePriorityQueue` to facilitate testing
the slightly different performance characteristics on various
application use cases.

>>> pq = PriorityQueue()
>>> pq.add('low priority task', 0)
>>> pq.add('high priority task', 2)
>>> pq.add('medium priority task 1', 1)
>>> pq.add('medium priority task 2', 1)
>>> len(pq)
4
>>> pq.pop()
'high priority task'
>>> pq.peek()
'medium priority task 1'
>>> len(pq)
3

    )heappushheappopinsortN)make_sentinel_REMOVED)var_name)BList)PriorityQueueBasePriorityQueueHeapPriorityQueueSortedPriorityQueuec                       \ rS rSrSr\" S 5      r\rS r	\S 5       r
\S 5       rSS jrS	 rSS
 jr\4S jr\4S jrS rSrg)r   ]   a  The abstract base class for the other PriorityQueues in this
module. Override the ``_backend_type`` class attribute, as well as
the :meth:`_push_entry` and :meth:`_pop_entry` staticmethods for
custom subclass behavior. (Don't forget to use
:func:`staticmethod`).

Args:
    priority_key (callable): A function that takes *priority* as
        passed in by :meth:`add` and returns a real number
        representing the effective priority.

c                 ,    [        U =(       d    S5      * $ Nr   )float)ps    e/home/james-whalen/.local/share/pipx/venvs/semgrep/lib/python3.13/site-packages/boltons/queueutils.py<lambda>BasePriorityQueue.<lambda>k   s    E!&qM>    c                     U R                  5       U l        0 U l        [        R                  " 5       U l        UR                  SU R                  5      U l        U(       a  [        SUR                  5       -  5      eg )Npriority_keyz unexpected keyword arguments: %r)_backend_type_pq
_entry_map	itertoolscount_counterpop_default_priority_key_get_priority	TypeErrorkeys)selfkws     r   __init__BasePriorityQueue.__init__n   s_    %%'!)VVND4N4NO>JKK r   c                     g N backendentrys     r   _push_entryBasePriorityQueue._push_entryv       r   c                     g r+   r,   r.   s    r   
_pop_entryBasePriorityQueue._pop_entryz   r2   r   Nc                     U R                  U5      nXR                  ;   a  U R                  U5        [        U R                  5      nX#U/nX@R                  U'   U R                  U R                  U5        g)a   
Add a task to the queue, or change the *task*'s priority if *task*
is already in the queue. *task* can be any hashable object,
and *priority* defaults to ``0``. Higher values representing
higher priority, but this behavior can be controlled by
setting *priority_key* in the constructor.
N)r#   r   removenextr    r0   r   )r&   taskpriorityr   r/   s        r   addBasePriorityQueue.add~   sb     %%h/??"KKT]]#$' %5)r   c                 L    U R                   R                  U5      n[        US'   g)zWRemove a task from the priority queue. Raises :exc:`KeyError` if
the *task* is absent.
N)r   r!   r   )r&   r:   r/   s      r   r8   BasePriorityQueue.remove   s!     ##D)b	r   c                     U R                   (       a9  U R                   S   u  p#nU[        L a  U R                  U R                   5        MI  gU(       a  [        S5      eg)zBRemove entries marked as removed by previous :meth:`remove` calls.r   Nzempty priority queue)r   r   r5   
IndexError)r&   	raise_excr;   r   r:   s        r   _cullBasePriorityQueue._cull   sM    hh$(HHQK!HTx)344 r   c                      U R                  5         U R                  S   u    p#U$ ! [         a    U[        La  Us $ [        S5      ef = f)zRead the next value in the queue without removing it. Returns
*default* on an empty queue, or raises :exc:`KeyError` if
*default* is not set.
r   zpeek on empty queue)rD   r   rB   r   r&   default_r:   s       r   peekBasePriorityQueue.peek   sR    
	4JJL!JAq
 	  	4h&233	4s   "& A	A	c                      U R                  5         U R                  U R                  5      u    p#U R                  U	 U$ ! [         a    U[
        La  Us $ [	        S5      ef = f)zRemove and return the next value in the queue. Returns *default* on
an empty queue, or raises :exc:`KeyError` if *default* is not
set.
zpop on empty queue)rD   r5   r   r   rB   r   rG   s       r   r!   BasePriorityQueue.pop   sc    
	3JJL2JAq%
 	  	3h&122	3s   ;? A"A"c                 ,    [        U R                  5      $ )z(Return the number of tasks in the queue.)lenr   )r&   s    r   __len__BasePriorityQueue.__len__   s    4??##r   )r    r   r#   r   r+   )T)__name__
__module____qualname____firstlineno____doc__staticmethodr"   listr   r(   r0   r5   r<   r8   rD   r   rJ   r!   rP   __static_attributes__r,   r   r   r   r   ]   sp     ))ABML    * 	5 $  # $r   r   c                   8    \ rS rSrSr\S 5       r\S 5       rSrg)r      zA priority queue inherited from :class:`BasePriorityQueue`,
backed by a list and based on the :func:`heapq.heappop` and
:func:`heapq.heappush` functions in the built-in :mod:`heapq`
module.
c                     [        U 5      $ r+   )r   r4   s    r   r5   HeapPriorityQueue._pop_entry   s    wr   c                     [        X5        g r+   )r   r-   s     r   r0   HeapPriorityQueue._push_entry   s
     r   r,   N)	rR   rS   rT   rU   rV   rW   r5   r0   rY   r,   r   r   r   r      s/    
     ! !r   r   c                   <    \ rS rSrSr\r\S 5       r\S 5       r	Sr
g)r      zA priority queue inherited from :class:`BasePriorityQueue`, based
on the :func:`bisect.insort` approach for in-order insertion into
a sorted list.
c                 $    U R                  S5      $ r   )r!   r4   s    r   r5   SortedPriorityQueue._pop_entry   s    {{1~r   c                     [        X5        g r+   r   r-   s     r   r0   SortedPriorityQueue._push_entry   s
    wr   r,   N)rR   rS   rT   rU   rV   r
   r   rW   r5   r0   rY   r,   r   r   r   r      s4     M   r   r   )rV   heapqr   r   bisectr   r   	typeutilsr   r   ImportErrorobject	listutilsr
   rX   __all__r   r   r   r   r,   r   r   <module>rm      s   B F $  'j1H7b$ b$J!) !+   $m  xH  Es"   A A$ A! A!$A/.A/