zmc
2023-12-22 9fdbf60165db0400c2e8e6be2dc6e88138ac719a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
U
Z±d/kã@sbddlZddlZddlZddlmZddlmZmZddlmZej    ddGdd    „d    ƒƒZ
ej    d
d
d
dd Gd d „d edƒZ Gdd„dƒZ ej    ddGdd„dƒƒZ Gdd„de edZGdd„de edZej    ddGdd„dƒƒZej    d
d
d
dGdd„de ƒƒZGdd„deedZGdd„deedZej    ddGd d!„d!ƒƒZGd"d#„d#e edZdS)$éNé)Ú_core)Úenable_ki_protectionÚ
ParkingLot)ÚFinalT)Úfrozenc@seZdZe ¡ZdS)Ú_EventStatisticsN)Ú__name__Ú
__module__Ú __qualname__ÚattrÚibÚ tasks_waiting©rrúAd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\trio/_sync.pyr srF)ÚreprÚeqÚhashÚslotsc@sPeZdZdZejeddZejdddZdd„Z    e
dd„ƒZd    d
„Z d d „Z d S)ÚEventaç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Úinit©ÚdefaultrcCs|jS)z.Return the current value of the internal flag.)Ú_flag©ÚselfrrrÚis_set/sz Event.is_setcCs0|js,d|_|jD]}t |¡q|j ¡dS)z@Set the internal flag value to True, and wake any waiting tasks.TN)rÚ_tasksrZ
rescheduleÚclear©rÚtaskrrrÚset3s
 
 z    Event.setcƒsNˆjrtj ¡IdHn2t ¡‰ˆj ˆ¡‡‡fdd„}t |¡IdHdS)z€Block until the internal flag value becomes True.
 
        If it's already True, then this method returns immediately.
 
        Ncsˆj ˆ¡tjjS©N)rÚremoverZAbortZ    SUCCEEDED)Ú_r!rrÚabort_fnHs zEvent.wait.<locals>.abort_fn)    rÚtrioÚlowlevelÚ
checkpointrÚ current_taskrÚaddZwait_task_rescheduled)rr'rr!rÚwait<s  z
Event.waitcCstt|jƒdS)zÚReturn 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ÚlenrrrrrÚ
statisticsNs    zEvent.statisticsN) r    r
r Ú__doc__r r r#rrrrr-r/rrrrrs
r)Ú    metaclassc@s$eZdZedd„ƒZedd„ƒZdS)ÚAsyncContextManagerMixincÃs| ¡IdHdSr$)ÚacquirerrrrÚ
__aenter__[sz#AsyncContextManagerMixin.__aenter__cÇs | ¡dSr$)Úrelease)rÚargsrrrÚ    __aexit___sz"AsyncContextManagerMixin.__aexit__N)r    r
r rr4r7rrrrr2Zs
r2c@s,eZdZe ¡Ze ¡Ze ¡Ze ¡ZdS)Ú_CapacityLimiterStatisticsN)    r    r
r r r Úborrowed_tokensÚ total_tokensÚ    borrowersrrrrrr8dsr8c@sªeZdZdZdd„Zdd„Zedd„ƒZejdd„ƒZd    d
„Z    ed d „ƒZ
ed d„ƒZ e dd„ƒZ e dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZe dd„ƒZdd„ZdS)ÚCapacityLimitera\    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.
 
    cCs.tƒ|_tƒ|_i|_||_|j|ks*t‚dSr$)rÚ_lotr#Ú
_borrowersÚ_pending_borrowersr:Ú _total_tokensÚAssertionError)rr:rrrÚ__init__¢s
zCapacityLimiter.__init__cCs"d t|ƒt|jƒ|jt|jƒ¡S)Nz6<trio.CapacityLimiter at {:#x}, {}/{} with {} waiting>)ÚformatÚidr.r>r@r=rrrrÚ__repr__«s ÿzCapacityLimiter.__repr__cCs|jS)aThe 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.
 
        )r@rrrrr:°s zCapacityLimiter.total_tokenscCs>t|tƒs|tjkrtdƒ‚|dkr,tdƒ‚||_| ¡dS)Nz'total_tokens must be an int or math.infrztotal_tokens must be >= 1)Ú
isinstanceÚintÚmathÚinfÚ    TypeErrorÚ
ValueErrorr@Ú _wake_waiters)rZnew_total_tokensrrrr:¿s cCs<|jt|jƒ}|jj|dD]}|j |j |¡¡qdS)N©Úcount)r@r.r>r=Úunparkr,r?Úpop)rÚ    availableZwokenrrrrLÈszCapacityLimiter._wake_waiterscCs
t|jƒS)z/The amount of capacity that's currently in use.)r.r>rrrrr9ÍszCapacityLimiter.borrowed_tokenscCs |j|jS)z/The amount of capacity that's available to use.)r:r9rrrrÚavailable_tokensÒsz CapacityLimiter.available_tokenscCs| tj ¡¡dS)zßBorrow 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_nowaitr(r)r+rrrrÚacquire_nowait×s
zCapacityLimiter.acquire_nowaitcCs@||jkrtdƒ‚t|jƒ|jkr6|js6|j |¡ntj‚dS)a¯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)r>Ú RuntimeErrorr.r@r=r,r(Ú
WouldBlock©rÚborrowerrrrrSãs
ÿz+CapacityLimiter.acquire_on_behalf_of_nowaitcÃs| tj ¡¡IdHdS)z²Borrow 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_ofr(r)r+rrrrr3s    zCapacityLimiter.acquirec Ãs˜tj ¡IdHz| |¡Wndtjk
r‚tj ¡}||j|<z|j ¡IdHWn$tj    k
r||j 
|¡‚YnXYnXtj  ¡IdHdS)a«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) r(r)Úcheckpoint_if_cancelledrSrVr+r?r=ÚparkZ    CancelledrPÚcancel_shielded_checkpoint)rrXr"rrrrY s
 
 z$CapacityLimiter.acquire_on_behalf_ofcCs| tj ¡¡dS)z Put 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_ofr(r)r+rrrrr5(s    zCapacityLimiter.releasecCs*||jkrtdƒ‚|j |¡| ¡dS)z¼Put 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)r>rUr%rLrWrrrr]3s     
ÿ z$CapacityLimiter.release_on_behalf_ofcCs$tt|jƒ|jt|jƒt|jƒdS)aÆ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.
 
        )r9r:r;r)r8r.r>r@Úlistr=rrrrr/Cs úzCapacityLimiter.statisticsN)r    r
r r0rBrEÚpropertyr:ÚsetterrLr9rRrrTrSr3rYr5r]r/rrrrr<ls25    
 
 
 
 
 
 
 
 
 
 
 
r<c@sjeZdZdZddœdd„Zdd„Zedd    „ƒZed
d „ƒZe    d d „ƒZ
e    dd„ƒZ e    dd„ƒZ dd„Z dS)Ú    SemaphoreuA `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_valuecCsht|tƒstdƒ‚|dkr"tdƒ‚|dk    rLt|tƒs<tdƒ‚||krLtdƒ‚tj ¡|_||_||_    dS)Nzinitial_value must be an intrzinitial value must be >= 0z max_value must be None or an intz#max_values must be >= initial_value)
rFrGrJrKr(r)rr=Ú_valueÚ
_max_value)rÚ initial_valuerbrrrrBys
 
 zSemaphore.__init__cCs0|jdkrd}n d |j¡}d |j|t|ƒ¡S)NÚz, max_value={}z<trio.Semaphore({}{}) at {:#x}>)rdrCrcrD)rZ max_value_strrrrrE‹s
 ÿzSemaphore.__repr__cCs|jS)z#The current value of the semaphore.)rcrrrrÚvalue”szSemaphore.valuecCs|jS)z<The maximum allowed value. May be None to indicate no limit.)rdrrrrrb™szSemaphore.max_valuecCs.|jdkr$|jrt‚|jd8_ntj‚dS)z‚Attempt to decrement the semaphore value, without blocking.
 
        Raises:
          WouldBlock: if the value is zero.
 
        rrN)rcr=rAr(rVrrrrrTžs
 
zSemaphore.acquire_nowaitcÃsXtj ¡IdHz | ¡Wn&tjk
rB|j ¡IdHYnXtj ¡IdHdS)zkDecrement the semaphore value, blocking if necessary to avoid
        letting it drop below zero.
 
        N©r(r)rZrTrVr=r[r\rrrrr3¬s  zSemaphore.acquirecCsT|jr$|jdkst‚|jjddn,|jdk    rB|j|jkrBtdƒ‚|jd7_dS)zÞIncrement 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`.
 
        rrrMNz!semaphore released too many times)r=rcrArOrdrKrrrrr5ºs
zSemaphore.releasecCs
|j ¡S)záReturn 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.
 
        )r=r/rrrrr/Ìs    zSemaphore.statistics)r    r
r r0rBrEr_rgrbrrTr3r5r/rrrrra^s    
 
 
 
 
rac@s$eZdZe ¡Ze ¡Ze ¡ZdS)Ú_LockStatisticsN)r    r
r r r ÚlockedÚownerrrrrrriØsri)rrrc@sdeZdZejeddZejdddZdd„Zdd„Z    e
d    d
„ƒZ e
d d „ƒZ e
d d„ƒZ dd„ZdS)Ú    _LockImplFrNrcCs>| ¡rd}d t|jƒ¡}nd}d}d ||jjt|ƒ|¡S)Nrjz with {} waitersÚunlockedrfz<{} {} object at {:#x}{}>)rjrCr.r=Ú    __class__r    rD)rÚs1Ús2rrrrEäsÿz_LockImpl.__repr__cCs
|jdk    S)z€Check whether the lock is currently held.
 
        Returns:
          bool: True if the lock is held, False otherwise.
 
        N)Ú_ownerrrrrrjïsz_LockImpl.lockedcCs@tj ¡}|j|krtdƒ‚n|jdkr6|js6||_ntj‚dS)ztAttempt to acquire the lock, without blocking.
 
        Raises:
          WouldBlock: if the lock is held.
 
        z*attempt to re-acquire an already held LockN)r(r)r+rqrUr=rVr!rrrrTøs     
 
 
z_LockImpl.acquire_nowaitcÃsXtj ¡IdHz | ¡Wn&tjk
rB|j ¡IdHYnXtj ¡IdHdS)z(Acquire the lock, blocking if necessary.Nrhrrrrr3
s  z_LockImpl.acquirecCs@tj ¡}||jk    rtdƒ‚|jr6|jjdd\|_nd|_dS)zpRelease the lock.
 
        Raises:
          RuntimeError: if the calling task does not hold the lock.
 
        z"can't release a Lock you don't ownrrMN)r(r)r+rqrUr=rOr!rrrr5s 
 
z_LockImpl.releasecCst| ¡|jt|jƒdS)a›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.
 
        )rjrkr)rirjrqr.r=rrrrr/(s
ÿz_LockImpl.statistics)r    r
r r r rr=rqrErjrrTr3r5r/rrrrrlßs     
 
 
rlc@seZdZdZdS)ÚLockaQA 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.
 
    N©r    r
r r0rrrrrr9srrc@seZdZdZdS)ÚStrictFIFOLockuÿ 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.
 
    NrsrrrrrtGsrtc@seZdZe ¡Ze ¡ZdS)Ú_ConditionStatisticsN)r    r
r r r rÚlock_statisticsrrrrru†sruc@s`eZdZdZddd„Zdd„Zdd„Zd    d
„Zd d „Ze    d d„ƒZ
ddd„Z dd„Z dd„Z dS)Ú    ConditionaÎ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.
 
    NcCs8|dkrtƒ}t|ƒtk    r"tdƒ‚||_tj ¡|_dS)Nzlock must be a trio.Lock)rrÚtyperJÚ_lockr(r)rr=)rÚlockrrrrB›s  zCondition.__init__cCs
|j ¡S)z‹Check whether the underlying lock is currently held.
 
        Returns:
          bool: True if the lock is held, False otherwise.
 
        )ryrjrrrrrj£szCondition.lockedcCs
|j ¡S)z‰Attempt to acquire the underlying lock, without blocking.
 
        Raises:
          WouldBlock: if the lock is currently held.
 
        )ryrTrrrrrT¬szCondition.acquire_nowaitcÃs|j ¡IdHdS)z3Acquire the underlying lock, blocking if necessary.N)ryr3rrrrr3µszCondition.acquirecCs|j ¡dS)zRelease the underlying lock.N)ryr5rrrrr5¹szCondition.releasec Ãsptj ¡|jjk    rtdƒ‚| ¡z|j ¡IdHWn4tj    dd| 
¡IdHW5QRX‚YnXdS)aƒ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.
 
        zmust hold the lock to waitNT)Zshield) r(r)r+ryrqrUr5r=r[Z CancelScoper3rrrrr-½szCondition.waitrcCs2tj ¡|jjk    rtdƒ‚|jj|jj|ddS)zÖWake 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 notifyrMN)r(r)r+ryrqrUr=Zrepark)rÚnrrrÚnotifyás
zCondition.notifycCs.tj ¡|jjk    rtdƒ‚|j |jj¡dS)z™Wake all tasks that are currently blocked in :meth:`wait`.
 
        Raises:
          RuntimeError: if the calling task does not hold the lock.
 
        r{N)r(r)r+ryrqrUr=Z
repark_allrrrrÚ
notify_allïszCondition.notify_allcCstt|jƒ|j ¡dS)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.
 
        )rrv)rur.r=ryr/rrrrr/ús ÿzCondition.statistics)N)r)r    r
r r0rBrjrTr3r5rr-r}r~r/rrrrrwŒs
        
#
 rw)rHr r(rfrrrZ_utilrÚsrrr2r8r<rarirlrrrtrurwrrrrÚ<module>s0  
H
 
sz
Y?