
    vKgz                       S SK Jr  S SKrS SKJrJr  S SKrS SKrSSKJ	r	  SSK	J
r
JrJrJrJrJr  SSKJr  \(       a  S SKJr  SS	K	Jr  SS
KJr  \R.                   " S S5      5       r\\R2                  " SSS9 " S S5      5       5       r " S S\5      r " S S5      r\R.                   " S S5      5       r\ " S S\5      5       r\ " S S\5      5       r\R.                   " S S5      5       r \R2                  " SSSS9 " S S\5      5       r!\ " S  S!\!5      5       r"\ " S" S#\!5      5       r#\R.                   " S$ S%5      5       r$\ " S& S'\5      5       r%g)(    )annotationsN)TYPE_CHECKINGProtocol   )_core)Abort
ParkingLotRaiseCancelTadd_parking_lot_breakerenable_ki_protectionremove_parking_lot_breaker)final)TracebackType)Task)ParkingLotStatisticsc                  $    \ rS rSr% SrS\S'   Srg)EventStatistics   zAn object containing debugging information.

Currently the following fields are defined:

* ``tasks_waiting``: The number of tasks blocked on this event's
  :meth:`trio.Event.wait` method.

inttasks_waiting N__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r       J/var/www/highfloat_scraper/venv/lib/python3.13/site-packages/trio/_sync.pyr   r      s     r    r   F)repreqc                      \ rS rSr% Sr\R                  " \SS9rS\	S'   \R                  " SSS9r
S\	S	'   SS
 jr\SS j5       rSS jrSS jrSrg)Event*   a  A waitable boolean value useful for inter-task synchronization,
inspired by :class:`threading.Event`.

An event object has an internal boolean flag, representing whether
the event has happened yet. The flag is initially False, and the
:meth:`wait` method waits until the flag is True. If the flag is
already True, then :meth:`wait` returns immediately. (If the event has
already happened, there's nothing to wait for.) The :meth:`set` method
sets the flag to True, and wakes up any waiters.

This behavior is useful because it helps avoid race conditions and
lost wakeups: it doesn't matter whether :meth:`set` gets called just
before or after :meth:`wait`. If you want a lower-level wakeup
primitive that doesn't have this protection, consider :class:`Condition`
or :class:`trio.lowlevel.ParkingLot`.

.. note:: Unlike `threading.Event`, `trio.Event` has no
   `~threading.Event.clear` method. In Trio, once an `Event` has happened,
   it cannot un-happen. If you need to represent a series of events,
   consider creating a new `Event` object for each one (they're cheap!),
   or other synchronization methods like :ref:`channels <channels>` or
   `trio.lowlevel.ParkingLot`.

Ffactoryinitz	set[Task]_tasksdefaultr)   bool_flagc                    U R                   $ )z.Return the current value of the internal flag.r.   selfs    r!   is_setEvent.is_setI   s    zzr    c                    U R                   (       dK  SU l         U R                   H  n[        R                  " U5        M     U R                  R	                  5         gg)z@Set the internal flag value to True, and wake any waiting tasks.TN)r.   r*   r   
rescheduleclearr2   tasks     r!   set	Event.setM   sC     zzDJ  & $KK	 r    c                6  ^ ^#    T R                   (       a'  [        R                  R                  5       I Sh  vN   g[        R
                  " 5       mT R                  R                  T5        SU U4S jjn[        R                  " U5      I Sh  vN   g N] N7f)zpBlock until the internal flag value becomes True.

If it's already True, then this method returns immediately.

Nc                n   > TR                   R                  T5        [        R                  R                  $ N)r*   remover   r   	SUCCEEDED)_r2   r9   s    r!   abort_fnEvent.wait.<locals>.abort_fnb   s%    ""4({{,,,r    )rA   r
   returnr   )	r.   triolowlevel
checkpointr   current_taskr*   addwait_task_rescheduled)r2   rB   r9   s   ` @r!   wait
Event.waitV   sm      ::--**,,,%%'DKKOOD!- - --h777 - 8s"   3BBABBBBc                :    [        [        U R                  5      S9$ )zReturn an object containing debugging information.

Currently the following fields are defined:

* ``tasks_waiting``: The number of tasks blocked on this event's
  :meth:`wait` method.

)r   )r   lenr*   r1   s    r!   
statisticsEvent.statisticsh   s     S-=>>r    r0   NrD   r-   rD   None)rD   r   )r   r   r   r   r   attrsfieldr:   r*   r   r.   r3   r   rK   rO   r   r   r    r!   r%   r%   *   sV    2 Ce<FI<++e%8E48    8$	?r    r%   c                  ,    \ rS rSrSrSS jrSS jrSrg)_HasAcquireReleaset   zNOnly classes with acquire() and release() can use the mixin's implementations.c                   #    g 7fr>   r   r1   s    r!   acquire_HasAcquireRelease.acquirew   s     ss   c                    g r>   r   r1   s    r!   release_HasAcquireRelease.releasey   s    r    r   N)rD   object)r   r   r   r   r   rZ   r]   r   r   r    r!   rW   rW   t   s    X*$r    rW   c                  P    \ rS rSr\SS j5       r\          SS j5       rSrg)AsyncContextManagerMixin|   c                @   #    U R                  5       I S h  vN   g  N7fr>   )rZ   r1   s    r!   
__aenter__#AsyncContextManagerMixin.__aenter__}   s     llns   c                ,   #    U R                  5         g 7fr>   )r]   )r2   exc_type	exc_value	tracebacks       r!   	__aexit__"AsyncContextManagerMixin.__aexit__   s      	s   r   N)r2   rW   rD   rS   )
r2   rW   rg   ztype[BaseException] | Nonerh   zBaseException | Noneri   zTracebackType | NonerD   rS   )r   r   r   r   r   rd   rj   r   r   r    r!   ra   ra   |   sV       , ( (	
 
 r    ra   c                  B    \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S
rg)CapacityLimiterStatistics   a  An object containing debugging information.

Currently the following fields are defined:

* ``borrowed_tokens``: The number of tokens currently borrowed from
  the sack.
* ``total_tokens``: The total number of tokens in the sack. Usually
  this will be larger than ``borrowed_tokens``, but it's possibly for
  it to be smaller if :attr:`trio.CapacityLimiter.total_tokens` was recently decreased.
* ``borrowers``: A list of all tasks or other entities that currently
  hold a token.
* ``tasks_waiting``: The number of tasks blocked on this
  :class:`CapacityLimiter`'s :meth:`trio.CapacityLimiter.acquire` or
  :meth:`trio.CapacityLimiter.acquire_on_behalf_of` methods.

r   borrowed_tokensint | floattotal_tokenszlist[Task | object]	borrowersr   r   Nr   r   r    r!   rm   rm      s!    " ""r    rm   c                     \ rS rSrSrSS jrSS jr\SS j5       r\R                  SS j5       rSS jr
\SS j5       r\SS	 j5       r\SS
 j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       rSS jrSrg)CapacityLimiter   a  An object for controlling access to a resource with limited capacity.

Sometimes you need to put a limit on how many tasks can do something at
the same time. For example, you might want to use some threads to run
multiple blocking I/O operations in parallel... but if you use too many
threads at once, then your system can become overloaded and it'll actually
make things slower. One popular solution is to impose a policy like "run
up to 40 threads at the same time, but no more". But how do you implement
a policy like this?

That's what :class:`CapacityLimiter` is for. You can think of a
:class:`CapacityLimiter` object as a sack that starts out holding some fixed
number of tokens::

   limit = trio.CapacityLimiter(40)

Then tasks can come along and borrow a token out of the sack::

   # Borrow a token:
   async with limit:
       # We are holding a token!
       await perform_expensive_operation()
   # Exiting the 'async with' block puts the token back into the sack

And crucially, if you try to borrow a token but the sack is empty, then
you have to wait for another task to finish what it's doing and put its
token back first before you can take it and continue.

Another way to think of it: a :class:`CapacityLimiter` is like a sofa with a
fixed number of seats, and if they're all taken then you have to wait for
someone to get up before you can sit down.

By default, :func:`trio.to_thread.run_sync` uses a
:class:`CapacityLimiter` to limit the number of threads running at once;
see `trio.to_thread.current_default_thread_limiter` for details.

If you're familiar with semaphores, then you can think of this as a
restricted semaphore that's specialized for one common use case, with
additional error checking. For a more traditional semaphore, see
:class:`Semaphore`.

.. note::

   Don't confuse this with the `"leaky bucket"
   <https://en.wikipedia.org/wiki/Leaky_bucket>`__ or `"token bucket"
   <https://en.wikipedia.org/wiki/Token_bucket>`__ algorithms used to
   limit bandwidth usage on networks. The basic idea of using tokens to
   track a resource limit is similar, but this is a very simple sack where
   tokens aren't automatically created or destroyed over time; they're
   just borrowed and then put back.

c                ~    [        5       U l        [        5       U l        0 U l        Xl        U R                  U:X  d   eg r>   )r	   _lotr:   
_borrowers_pending_borrowersrq   _total_tokens)r2   rq   s     r!   __init__CapacityLimiter.__init__   s6    L	.1e=?)5!!\111r    c           
         S[        U 5      S S[        U R                  5       SU R                   S[        U R                  5       S3	$ )Nz<trio.CapacityLimiter at #xz, / with z	 waiting>)idrN   rx   rz   rw   r1   s    r!   __repr__CapacityLimiter.__repr__   sU    *2d8B-r#doo:N9OqQUQcQcPddjknosoxoxkyjz  {D  E  	Er    c                    U R                   $ )a  The total capacity available.

You can change :attr:`total_tokens` by assigning to this attribute. If
you make it larger, then the appropriate number of waiting tasks will
be woken immediately to take the new tokens. If you decrease
total_tokens below the number of tasks that are currently using the
resource, then all current tasks will be allowed to finish as normal,
but no new tasks will be allowed in until the total number of tasks
drops below the new total_tokens.

)rz   r1   s    r!   rq   CapacityLimiter.total_tokens   s     !!!r    c                    [        U[        5      (       d  U[        R                  :w  a  [	        S5      eUS:  a  [        S5      eXl        U R                  5         g )Nz'total_tokens must be an int or math.infr   ztotal_tokens must be >= 1)
isinstancer   mathinf	TypeError
ValueErrorrz   _wake_waiters)r2   new_total_tokenss     r!   rq   r      sN    *C005E5QEFFa899-r    c                    U R                   [        U R                  5      -
  nU R                  R	                  US9 H7  nU R                  R                  U R                  R                  U5      5        M9     g )Ncount)rz   rN   rx   rw   unparkrI   ry   pop)r2   	availablewokens      r!   r   CapacityLimiter._wake_waiters  sZ    &&T__)==	YY%%I%6EOO 7 7 ; ;E BC 7r    c                ,    [        U R                  5      $ )z/The amount of capacity that's currently in use.)rN   rx   r1   s    r!   ro   CapacityLimiter.borrowed_tokens  s     4??##r    c                4    U R                   U R                  -
  $ )z/The amount of capacity that's available to use.)rq   ro   r1   s    r!   available_tokens CapacityLimiter.available_tokens  s       4#7#777r    c                ^    U R                  [        R                  R                  5       5        g)zBorrow a token from the sack, without blocking.

Raises:
  WouldBlock: if no tokens are available.
  RuntimeError: if the current task already holds one of this sack's
      tokens.

N)acquire_on_behalf_of_nowaitrE   rF   rH   r1   s    r!   acquire_nowaitCapacityLimiter.acquire_nowait  s     	(()C)C)EFr    c                    XR                   ;   a  [        S5      e[        U R                   5      U R                  :  a-  U R                  (       d  U R                   R                  U5        g[        R                  e)aG  Borrow a token from the sack on behalf of ``borrower``, without
blocking.

Args:
  borrower: A :class:`trio.lowlevel.Task` or arbitrary opaque object
     used to record who is borrowing this token. This is used by
     :func:`trio.to_thread.run_sync` to allow threads to "hold
     tokens", with the intention in the future of using it to `allow
     deadlock detection and other useful things
     <https://github.com/python-trio/trio/issues/182>`__

Raises:
  WouldBlock: if no tokens are available.
  RuntimeError: if ``borrower`` already holds one of this sack's
      tokens.

zEthis borrower is already holding one of this CapacityLimiter's tokensN)rx   RuntimeErrorrN   rz   rw   rI   rE   
WouldBlockr2   borrowers     r!   r   +CapacityLimiter.acquire_on_behalf_of_nowait  sY    & &W  t$"4"44TYYOO)//!r    c                z   #    U R                  [        R                  R                  5       5      I Sh  vN   g N7f)zBorrow a token from the sack, blocking if necessary.

Raises:
  RuntimeError: if the current task already holds one of this sack's
      tokens.

N)acquire_on_behalf_ofrE   rF   rH   r1   s    r!   rZ   CapacityLimiter.acquire:  s(      ''(B(B(DEEEs   1;9;c                  #    [         R                  R                  5       I Sh  vN    U R                  U5        [         R                  R	                  5       I Sh  vN   g N= N! [         R
                   a    [         R                  R                  5       nXR                  U'    U R                  R                  5       I Sh  vN     g! [         R                   a    U R                  R                  U5        e f = ff = f7f)ac  Borrow a token from the sack on behalf of ``borrower``, blocking if
necessary.

Args:
  borrower: A :class:`trio.lowlevel.Task` or arbitrary opaque object
     used to record who is borrowing this token; see
     :meth:`acquire_on_behalf_of_nowait` for details.

Raises:
  RuntimeError: if ``borrower`` task already holds one of this sack's
     tokens.

N)rE   rF   checkpoint_if_cancelledr   cancel_shielded_checkpointr   rH   ry   rw   park	Cancelledr   )r2   r   r9   s      r!   r   $CapacityLimiter.acquire_on_behalf_ofE  s      mm33555	=,,X6 --::<<< 	6 =  	==--/D,4##D)iinn&&&>> ''++D1	s\   "DA"DA& !DA$D$D&A D'CCC
D1C==DDc                ^    U R                  [        R                  R                  5       5        g)zPut a token back into the sack.

Raises:
  RuntimeError: if the current task has not acquired one of this
      sack's tokens.

N)release_on_behalf_ofrE   rF   rH   r1   s    r!   r]   CapacityLimiter.releaseb  s     	!!$--"<"<">?r    c                    XR                   ;  a  [        S5      eU R                   R                  U5        U R                  5         g)zPut a token back into the sack on behalf of ``borrower``.

Raises:
  RuntimeError: if the given borrower has not acquired one of this
      sack's tokens.

z@this borrower isn't holding any of this CapacityLimiter's tokensN)rx   r   r?   r   r   s     r!   r   $CapacityLimiter.release_on_behalf_ofm  s>     ??*R  	x(r    c                    [        [        U R                  5      U R                  [	        U R                  5      [        U R
                  5      S9$ )af  Return an object containing debugging information.

Currently the following fields are defined:

* ``borrowed_tokens``: The number of tokens currently borrowed from
  the sack.
* ``total_tokens``: The total number of tokens in the sack. Usually
  this will be larger than ``borrowed_tokens``, but it's possibly for
  it to be smaller if :attr:`total_tokens` was recently decreased.
* ``borrowers``: A list of all tasks or other entities that currently
  hold a token.
* ``tasks_waiting``: The number of tasks blocked on this
  :class:`CapacityLimiter`'s :meth:`acquire` or
  :meth:`acquire_on_behalf_of` methods.

)ro   rq   rr   r   )rm   rN   rx   rz   listrw   r1   s    r!   rO   CapacityLimiter.statistics}  s?    " )0++ 4??+dii.
 	
r    )rx   rw   ry   rz   rq   N)rq   rp   rD   str)rD   rp   )r   rp   rD   rS   rR   rD   r   )r   zTask | objectrD   rS   )rD   rm   )r   r   r   r   r   r{   r   propertyrq   setterr   ro   r   r   r   r   rZ   r   r]   r   rO   r   r   r    r!   rt   rt      s    3l2E " "  D
 $ $ 8 8 	G 	G " "6 F F = =8 @ @  
r    rt   c                      \ rS rSrSrSS.SS jjrSS jr\SS j5       r\SS j5       r	\
SS	 j5       r\
SS
 j5       r\
SS j5       rSS jrSrg)	Semaphorei  u  A `semaphore <https://en.wikipedia.org/wiki/Semaphore_(programming)>`__.

A semaphore holds an integer value, which can be incremented by
calling :meth:`release` and decremented by calling :meth:`acquire` – but
the value is never allowed to drop below zero. If the value is zero, then
:meth:`acquire` will block until someone calls :meth:`release`.

If you're looking for a :class:`Semaphore` to limit the number of tasks
that can access some resource simultaneously, then consider using a
:class:`CapacityLimiter` instead.

This object's interface is similar to, but different from, that of
:class:`threading.Semaphore`.

A :class:`Semaphore` object can be used as an async context manager; it
blocks on entry but not on exit.

Args:
  initial_value (int): A non-negative integer giving semaphore's initial
    value.
  max_value (int or None): If given, makes this a "bounded" semaphore that
    raises an error if the value is about to exceed the given
    ``max_value``.

N)	max_valuec               *   [        U[        5      (       d  [        S5      eUS:  a  [        S5      eUb0  [        U[        5      (       d  [        S5      eX!:  a  [        S5      e[        R
                  R                  5       U l        Xl        X l	        g )Nzinitial_value must be an intr   zinitial value must be >= 0z max_value must be None or an intz#max_values must be >= initial_value)
r   r   r   r   rE   rF   r	   rw   _value
_max_value)r2   initial_valuer   s      r!   r{   Semaphore.__init__  s    ---:;;19:: i-- BCC( !FGG
 MM,,.	##r    c                ~    U R                   c  SnOSU R                    3nSU R                   U S[        U 5      S S3$ )N z, max_value=z<trio.Semaphore(z) at r~   >)r   r   r   )r2   max_value_strs     r!   r   Semaphore.__repr__  sE    ??"M*4??*;<M!$++}oU2d8B-qQQr    c                    U R                   $ )z#The current value of the semaphore.)r   r1   s    r!   valueSemaphore.value  s     {{r    c                    U R                   $ )z<The maximum allowed value. May be None to indicate no limit.)r   r1   s    r!   r   Semaphore.max_value  s     r    c                    U R                   S:  a)  U R                  (       a   eU =R                   S-  sl         g[        R                  e)zjAttempt to decrement the semaphore value, without blocking.

Raises:
  WouldBlock: if the value is zero.

r   r   N)r   rw   rE   r   r1   s    r!   r   Semaphore.acquire_nowait  s3     ;;?yy =KK1K//!r    c                H  #    [         R                  R                  5       I Sh  vN    U R                  5         [         R                  R	                  5       I Sh  vN   g N< N! [         R
                   a&    U R                  R                  5       I Sh  vN     gf = f7f)z[Decrement the semaphore value, blocking if necessary to avoid
letting it drop below zero.

N)rE   rF   r   r   r   r   rw   r   r1   s    r!   rZ   Semaphore.acquire  sx      mm33555	=! --::<<< 	6 =  	#)).."""	#sO   "B"A!B"A% !B"A#B"#B"%1BBBB"BB"c                   U R                   (       a,  U R                  S:X  d   eU R                   R                  SS9  gU R                  b%  U R                  U R                  :X  a  [	        S5      eU =R                  S-  sl        g)zIncrement the semaphore value, possibly waking a task blocked in
:meth:`acquire`.

Raises:
  ValueError: if incrementing the value would cause it to exceed
      :attr:`max_value`.

r   r   r   Nz!semaphore released too many times)rw   r   r   r   r   r1   s    r!   r]   Semaphore.release  se     99;;!###II1%*t{{doo/M !DEEKK1Kr    c                6    U R                   R                  5       $ )zReturn an object containing debugging information.

Currently the following fields are defined:

* ``tasks_waiting``: The number of tasks blocked on this semaphore's
  :meth:`acquire` method.

)rw   rO   r1   s    r!   rO   Semaphore.statistics  s     yy##%%r    )rw   r   r   )r   r   r   
int | Noner   r   )rD   r   rR   )rD   r   )r   r   r   r   r   r{   r   r   r   r   r   r   rZ   r]   rO   r   r   r    r!   r   r     s    4 GK $$R     " " = =  "	&r    r   c                  8    \ rS rSr% SrS\S'   S\S'   S\S'   S	rg
)LockStatisticsi  ay  An object containing debugging information for a Lock.

Currently the following fields are defined:

* ``locked`` (boolean): indicating whether the lock is held.
* ``owner``: the :class:`trio.lowlevel.Task` currently holding the lock,
  or None if the lock is not held.
* ``tasks_waiting`` (int): The number of tasks blocked on this lock's
  :meth:`trio.Lock.acquire` method.

r-   lockedTask | Noneownerr   r   r   Nr   r   r    r!   r   r     s    
 Lr    r   )r#   r"   slotsc                      \ rS rSr% \R
                  " \SS9rS\S'   \R
                  " SSS9r	S\S	'   SS
 jr
SS jr\SS j5       r\SS j5       r\SS j5       rSS jrSrg)	_LockImpli$  Fr'   r	   rw   Nr+   r   _ownerc                    U R                  5       (       a  SnS[        U R                  5       S3nOSnSnSU SU R                  R                   S[        U 5      S	 U S
3$ )Nr   r   z waitersunlockedr   < z object at r~   r   )r   rN   rw   	__class__r   r   )r2   s1s2s      r!   r   _LockImpl.__repr__)  sc    ;;==B#dii.)2BBB2$a//0BtHR=ANNr    c                    U R                   SL$ )zhCheck whether the lock is currently held.

Returns:
  bool: True if the lock is held, False otherwise.

Nr   r1   s    r!   r   _LockImpl.locked2  s     {{$&&r    c                   [         R                  R                  5       nU R                  UL a  [	        S5      eU R                  c-  U R
                  (       d  Xl        [        XR
                  5        g[         R                  e)z\Attempt to acquire the lock, without blocking.

Raises:
  WouldBlock: if the lock is held.

z*attempt to re-acquire an already held LockN)rE   rF   rH   r   r   rw   r   r   r8   s     r!   r   _LockImpl.acquire_nowait;  sY     }}))+;;$KLL[[ K#D))4//!r    c                  #    [         R                  R                  5       I Sh  vN    U R                  5         [         R                  R	                  5       I Sh  vN   g N< N! [         R
                   ac     U R                  R                  5       I Sh  vN     g! [         R                   a%    [         R                  " SU R                   35      Sef = ff = f7f)z{Acquire the lock, blocking if necessary.

Raises:
  BrokenResourceError: if the owner of the lock exits without releasing.
Nz-Owner of this lock exited without releasing: )
rE   rF   r   r   r   r   rw   r   BrokenResourceErrorr   r1   s    r!   rZ   _LockImpl.acquireN  s      mm33555	=! --::<<< 	6 =  		 iinn&&&++ ..CDKK=Q		s[   "CA!CA% !CA#C#C%C:BBBC9CCCc                d   [         R                  R                  5       nXR                  La  [	        S5      e[        U R                  U R                  5        U R                  (       aA  U R                  R                  SS9u  U l        [        U R                  U R                  5        gSU l        g)zXRelease the lock.

Raises:
  RuntimeError: if the calling task does not hold the lock.

z"can't release a Lock you don't ownr   r   N)	rE   rF   rH   r   r   r   rw   r   r   r8   s     r!   r]   _LockImpl.releasee  sy     }}))+{{"CDD"4;;		:99!YY--A-6NT[#DKK;DKr    c                n    [        U R                  5       U R                  [        U R                  5      S9$ )ac  Return an object containing debugging information.

Currently the following fields are defined:

* ``locked``: boolean indicating whether the lock is held.
* ``owner``: the :class:`trio.lowlevel.Task` currently holding the lock,
  or None if the lock is not held.
* ``tasks_waiting``: The number of tasks blocked on this lock's
  :meth:`acquire` method.

)r   r   r   )r   r   r   rN   rw   r1   s    r!   rO   _LockImpl.statisticsw  s,     ;;=++dii.
 	
r    r   r   rQ   rR   )rD   r   )r   r   r   r   rT   rU   r	   rw   r   r   r   r   r   r   rZ   r]   rO   r   r   r    r!   r   r   $  sx    {{:EBD*B++d?FK?O' " "$ = =,  "
r    r   c                      \ rS rSrSrSrg)Locki  a5  A classic `mutex
<https://en.wikipedia.org/wiki/Lock_(computer_science)>`__.

This is a non-reentrant, single-owner lock. Unlike
:class:`threading.Lock`, only the owner of the lock is allowed to release
it.

A :class:`Lock` object can be used as an async context manager; it
blocks on entry but not on exit.

r   Nr   r   r   r   r   r   r   r    r!   r   r     s    
r    r   c                      \ rS rSrSrSrg)StrictFIFOLocki  u7  A variant of :class:`Lock` where tasks are guaranteed to acquire the
lock in strict first-come-first-served order.

An example of when this is useful is if you're implementing something like
:class:`trio.SSLStream` or an HTTP/2 server using `h2
<https://hyper-h2.readthedocs.io/>`__, where you have multiple concurrent
tasks that are interacting with a shared state machine, and at
unpredictable moments the state machine requests that a chunk of data be
sent over the network. (For example, when using h2 simply reading incoming
data can occasionally `create outgoing data to send
<https://http2.github.io/http2-spec/#PING>`__.) The challenge is to make
sure that these chunks are sent in the correct order, without being
garbled.

One option would be to use a regular :class:`Lock`, and wrap it around
every interaction with the state machine::

    # This approach is sometimes workable but often sub-optimal; see below
    async with lock:
        state_machine.do_something()
        if state_machine.has_data_to_send():
            await conn.sendall(state_machine.get_data_to_send())

But this can be problematic. If you're using h2 then *usually* reading
incoming data doesn't create the need to send any data, so we don't want
to force every task that tries to read from the network to sit and wait
a potentially long time for ``sendall`` to finish. And in some situations
this could even potentially cause a deadlock, if the remote peer is
waiting for you to read some data before it accepts the data you're
sending.

:class:`StrictFIFOLock` provides an alternative. We can rewrite our
example like::

    # Note: no awaits between when we start using the state machine and
    # when we block to take the lock!
    state_machine.do_something()
    if state_machine.has_data_to_send():
        # Notice that we fetch the data to send out of the state machine
        # *before* sleeping, so that other tasks won't see it.
        chunk = state_machine.get_data_to_send()
        async with strict_fifo_lock:
            await conn.sendall(chunk)

First we do all our interaction with the state machine in a single
scheduling quantum (notice there are no ``await``\s in there), so it's
automatically atomic with respect to other tasks. And then if and only if
we have data to send, we get in line to send it – and
:class:`StrictFIFOLock` guarantees that each task will send its data in
the same order that the state machine generated it.

Currently, :class:`StrictFIFOLock` is identical to :class:`Lock`,
but (a) this may not always be true in the future, especially if Trio ever
implements `more sophisticated scheduling policies
<https://github.com/python-trio/trio/issues/32>`__, and (b) the above code
is relying on a pretty subtle property of its lock. Using a
:class:`StrictFIFOLock` acts as an executable reminder that you're relying
on this property.

r   Nr   r   r    r!   r   r     s    ;r    r   c                  .    \ rS rSr% SrS\S'   S\S'   Srg)	ConditionStatisticsi  aL  An object containing debugging information for a Condition.

Currently the following fields are defined:

* ``tasks_waiting`` (int): The number of tasks blocked on this condition's
  :meth:`trio.Condition.wait` method.
* ``lock_statistics``: The result of calling the underlying
  :class:`Lock`\s  :meth:`~Lock.statistics` method.

r   r   r   lock_statisticsr   Nr   r   r    r!   r   r     s    	 ##r    r   c                      \ rS rSrSrSSS jjrSS jrSS jrSS jrSS jr	\
SS	 j5       rSSS
 jjrSS jrSS jrSrg)	Conditioni  a  A classic `condition variable
<https://en.wikipedia.org/wiki/Monitor_(synchronization)>`__, similar to
:class:`threading.Condition`.

A :class:`Condition` object can be used as an async context manager to
acquire the underlying lock; it blocks on entry but not on exit.

Args:
  lock (Lock): the lock object to use. If given, must be a
      :class:`trio.Lock`. If None, a new :class:`Lock` will be allocated
      and used.

Nc                    Uc
  [        5       n[        U5      [         La  [        S5      eXl        [        R
                  R                  5       U l        g )Nzlock must be a trio.Lock)r   typer   _lockrE   rF   r	   rw   )r2   locks     r!   r{   Condition.__init__  s?    <6D:T!677
MM,,.	r    c                6    U R                   R                  5       $ )zsCheck whether the underlying lock is currently held.

Returns:
  bool: True if the lock is held, False otherwise.

)r   r   r1   s    r!   r   Condition.locked  s     zz  ""r    c                6    U R                   R                  5       $ )zqAttempt to acquire the underlying lock, without blocking.

Raises:
  WouldBlock: if the lock is currently held.

)r   r   r1   s    r!   r   Condition.acquire_nowait  s     zz((**r    c                T   #    U R                   R                  5       I Sh  vN   g N7f)zAcquire the underlying lock, blocking if necessary.

Raises:
  BrokenResourceError: if the owner of the underlying lock exits without releasing.
N)r   rZ   r1   s    r!   rZ   Condition.acquire  s      jj  """s   (&(c                8    U R                   R                  5         g)zRelease the underlying lock.N)r   r]   r1   s    r!   r]   Condition.release  s    

r    c                  #    [         R                  R                  5       U R                  R                  La  [        S5      eU R                  5          U R                  R                  5       I Sh  vN   g N!   [         R                  " SS9   U R                  5       I Sh  vN    SSS5        e ! , (       d  f       e = f= f7f)as  Wait for another task to call :meth:`notify` or
:meth:`notify_all`.

When calling this method, you must hold the lock. It releases the lock
while waiting, and then re-acquires it before waking up.

There is a subtlety with how this method interacts with cancellation:
when cancelled it will block to re-acquire the lock before raising
:exc:`Cancelled`. This may cause cancellation to be less prompt than
expected. The advantage is that it makes code like this work::

   async with condition:
       await condition.wait()

If we didn't re-acquire the lock before waking up, and :meth:`wait`
were cancelled here, then we'd crash in ``condition.__aexit__`` when
we tried to release the lock we no longer held.

Raises:
  RuntimeError: if the calling task does not hold the lock.
  BrokenResourceError: if the owner of the lock exits without releasing, when attempting to re-acquire.

zmust hold the lock to waitNT)shield)rE   rF   rH   r   r   r   r]   rw   r   CancelScoperZ   r1   s    r!   rK   Condition.wait   s     2 ==%%'tzz/@/@@;<<	)).."""	!!.lln$$ / /.sT   ACA9 1A72A9 6C7A9 9CB2#B&$B2)	C2
C 	<CCc                    [         R                  R                  5       U R                  R                  La  [        S5      eU R                  R                  U R                  R                  US9  g)zWake one or more tasks that are blocked in :meth:`wait`.

Args:
  n (int): The number of tasks to wake.

Raises:
  RuntimeError: if the calling task does not hold the lock.

must hold the lock to notifyr   N)rE   rF   rH   r   r   r   rw   repark)r2   ns     r!   notifyCondition.notifyE  sN     ==%%'tzz/@/@@=>>		2r    c                    [         R                  R                  5       U R                  R                  La  [        S5      eU R                  R                  U R                  R                  5        g)zWake all tasks that are currently blocked in :meth:`wait`.

Raises:
  RuntimeError: if the calling task does not hold the lock.

r  N)rE   rF   rH   r   r   r   rw   
repark_allr1   s    r!   
notify_allCondition.notify_allS  sI     ==%%'tzz/@/@@=>>		TZZ__-r    c                l    [        [        U R                  5      U R                  R	                  5       S9$ )a.  Return an object containing debugging information.

Currently the following fields are defined:

* ``tasks_waiting``: The number of tasks blocked on this condition's
  :meth:`wait` method.
* ``lock_statistics``: The result of calling the underlying
  :class:`Lock`\s  :meth:`~Lock.statistics` method.

)r   r   )r   rN   rw   r   rO   r1   s    r!   rO   Condition.statistics^  s,     #dii. JJ113
 	
r    )r   rw   r>   )r   zLock | NonerQ   rR   )r   )r  r   rD   rS   )rD   r   )r   r   r   r   r   r{   r   r   rZ   r]   r   rK   r  r  rO   r   r   r    r!   r   r     sD    /#+# " "H3	.
r    r   )&
__future__r   r   typingr   r   rT   rE   r   r   r   r	   r
   r   r   r   _utilr   typesr   r   _core._parking_lotr   frozenr   definer%   rW   ra   rm   rt   r   r   r   r   r   r   r   r   r    r!   <module>r!     s   "  *     #8 
 
 
 5U#E? E? $ E?P% %    6 m
. m
 m
` u&( u& u&p   $ U%0b
( b
 1b
J 9   <Y < <~ $ $ $  A
( A
 A
r    