
    vKgB              	      $   S SK Jr  S SKJrJr  S SKJr  S SKJrJ	r	J
r
  S SKrS SKJrJr  S SKrSSKJrJrJrJrJr  SS	KJrJrJrJr  SS
KJrJrJr  \(       a  S SKJ r   S SK!J"r"      SS jr#\(       a   " S S\
S   5      r$O\" \#5      r$\RJ                   " S S5      5       r&\RN                   " S S\	\   5      5       r(\\RN                  " SSSS9 " S S\\   \S95       5       r)\\RN                  " SSSS9 " S S\\   \S95       5       r*g)    )annotations)OrderedDictdeque)inf)TYPE_CHECKINGGenericTupleN)ErrorValue   )ReceiveChannelReceiveTypeSendChannelSendTypeT)AbortRaiseCancelTTaskenable_ki_protection)NoPublicConstructorfinalgeneric_function)TracebackType)Selfc                    U [         :w  a   [        U [        5      (       d  [        S5      eU S:  a  [	        S5      e[        U 5      n[        [           R                  U5      [        [           R                  U5      4$ )u1	  Open a channel for passing objects between tasks within a process.

Memory channels are lightweight, cheap to allocate, and entirely
in-memory. They don't involve any operating-system resources, or any kind
of serialization. They just pass Python objects directly between tasks
(with a possible stop in an internal buffer along the way).

Channel objects can be closed by calling `~trio.abc.AsyncResource.aclose`
or using ``async with``. They are *not* automatically closed when garbage
collected. Closing memory channels isn't mandatory, but it is generally a
good idea, because it helps avoid situations where tasks get stuck waiting
on a channel when there's no-one on the other side. See
:ref:`channel-shutdown` for details.

Memory channel operations are all atomic with respect to
cancellation, either `~trio.abc.ReceiveChannel.receive` will
successfully return an object, or it will raise :exc:`Cancelled`
while leaving the channel unchanged.

Args:
  max_buffer_size (int or math.inf): The maximum number of items that can
    be buffered in the channel before :meth:`~trio.abc.SendChannel.send`
    blocks. Choosing a sensible value here is important to ensure that
    backpressure is communicated promptly and avoid unnecessary latency;
    see :ref:`channel-buffering` for more details. If in doubt, use 0.

Returns:
  A pair ``(send_channel, receive_channel)``. If you have
  trouble remembering which order these go in, remember: data
  flows from left → right.

In addition to the standard channel methods, all memory channel objects
provide a ``statistics()`` method, which returns an object with the
following fields:

* ``current_buffer_used``: The number of items currently stored in the
  channel buffer.
* ``max_buffer_size``: The maximum number of items allowed in the buffer,
  as passed to :func:`open_memory_channel`.
* ``open_send_channels``: The number of open
  :class:`MemorySendChannel` endpoints pointing to this channel.
  Initially 1, but can be increased by
  :meth:`MemorySendChannel.clone`.
* ``open_receive_channels``: Likewise, but for open
  :class:`MemoryReceiveChannel` endpoints.
* ``tasks_waiting_send``: The number of tasks blocked in ``send`` on this
  channel (summing over all clones).
* ``tasks_waiting_receive``: The number of tasks blocked in ``receive`` on
  this channel (summing over all clones).

z.max_buffer_size must be an integer or math.infr   zmax_buffer_size must be >= 0)
r   
isinstanceint	TypeError
ValueErrorMemoryChannelStateMemorySendChannelr   _createMemoryReceiveChannel)max_buffer_sizestates     M/var/www/highfloat_scraper/venv/lib/python3.13/site-packages/trio/_channel.py_open_memory_channelr'      ss    l #j#&F&FHII788#5o#FE!$$U+Q''.     c                  0    \ rS rSr    SS jrSS jrSrg)open_memory_channela   c                    [        U5      $ N)r'   )clsr$   s     r&   __new__open_memory_channel.__new__b   s     (88r(   c                    g r-    )selfr$   s     r&   __init__open_memory_channel.__init__h   s    r(   r2   Nr$   int | floatreturnz4tuple[MemorySendChannel[T], MemoryReceiveChannel[T]])r$   r7   )__name__
__module____qualname____firstlineno__r/   r4   __static_attributes__r2   r(   r&   r*   r*   a   s    	9(	9 B	9	r(   r*   )zMemorySendChannel[T]zMemoryReceiveChannel[T]c                  R    \ rS rSr% S\S'   S\S'   S\S'   S\S'   S\S'   S\S	'   S
rg)MemoryChannelStatisticsq   r   current_buffer_usedr7   r$   open_send_channelsopen_receive_channelstasks_waiting_sendtasks_waiting_receiver2   N)r9   r:   r;   r<   __annotations__r=   r2   r(   r&   r?   r?   q   s&      r(   r?   c                      \ rS rSr% S\S'   \R                  " \5      rS\S'   Sr	S\S'   Sr
S\S	'   \R                  " \5      rS
\S'   \R                  " \5      rS\S'   SS jrSrg)r    {   r7   r$   zdeque[T]datar   r   rB   rC   zOrderedDict[Task, T]
send_taskszOrderedDict[Task, None]receive_tasksc           
         [        [        U R                  5      U R                  U R                  U R
                  [        U R                  5      [        U R                  5      S9$ )N)rA   r$   rB   rC   rD   rE   )r?   lenrI   r$   rB   rC   rJ   rK   r3   s    r&   
statisticsMemoryChannelState.statistics   sO    & #DII 00#66"&"<"<"4??3"%d&8&8"9
 	
r(   r2   Nr8   r?   )r9   r:   r;   r<   rF   attrsFactoryr   rI   rB   rC   r   rJ   rK   rO   r=   r2   r(   r&   r    r    {   s^      ]]5)D()!"3"',}}['AJ$A-2]];-GM*G
r(   r    F)eqreprslotsc                     \ rS rSr% S\S'   SrS\S'   \R                  " \5      r	S\S'   SS	 jr
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S jr\SS j5       r\SS j5       rSrg)r!      zMemoryChannelState[SendType]_stateFbool_closedz	set[Task]_tasksc                B    U R                   =R                  S-  sl        g Nr   )rY   rB   rN   s    r&   __attrs_post_init__%MemorySendChannel.__attrs_post_init__   s    &&!+&r(   c                P    S[        U 5      S S[        U R                  5      S S3$ )Nz<send channel at #x, using buffer at >idrY   rN   s    r&   __repr__MemorySendChannel.__repr__   s+    "2d8B-/A"T[[/RTAUUVWWr(   c                6    U R                   R                  5       $ zSReturns a `MemoryChannelStatistics` for the memory channel this is
associated with.rY   rO   rN   s    r&   rO   MemorySendChannel.statistics   s     {{%%''r(   c                   U R                   (       a  [        R                  eU R                  R                  S:X  a  [        R
                  eU R                  R                  (       a  U R                  R                  (       a   eU R                  R                  R                  SS9u  p#UR                  R                  R                  U5        [        R                  R                  U[        U5      5        g[        U R                  R                  5      U R                  R                   :  a&  U R                  R                  R#                  U5        g[        R$                  e)zrLike `~trio.abc.SendChannel.send`, but if the channel's buffer is
full, raises `WouldBlock` instead of blocking.

r   FlastN)r[   trioClosedResourceErrorrY   rC   BrokenResourceErrorrK   rI   popitemcustom_sleep_datar\   removelowlevel
rescheduler   rM   r$   append
WouldBlock)r3   valuetask_s       r&   send_nowaitMemorySendChannel.send_nowait   s     <<***;;,,1***;;$${{''''kk//77U7CGD""))006MM$$T5<8!!"T[[%@%@@KK##E*//!r(   c                  ^ ^#    [         R                  R                  5       I Sh  vN    T R                  U5        [         R                  R	                  5       I Sh  vN   g N= N! [         R
                   a     Of = f[         R                  R                  5       mT R                  R                  T5        UT R                  R                  T'   T Tl        SU U4S jjn[         R                  R                  U5      I Sh  vN    g7f)z|See `SendChannel.send <trio.abc.SendChannel.send>`.

Memory channels allow multiple tasks to call `send` at the same time.

Nc                   > TR                   R                  T5        TR                  R                  T	 [        R
                  R                  R                  $ r-   )r\   ru   rY   rJ   rp   rv   r   	SUCCEEDEDr|   r3   r{   s    r&   abort_fn(MemorySendChannel.send.<locals>.abort_fn   s=    KKt$&&t,==&&000r(   r|   r   r8   r   )rp   rv   checkpoint_if_cancelledr}   cancel_shielded_checkpointry   current_taskr\   addrY   rJ   rt   wait_task_rescheduledr3   rz   r   r{   s   `  @r&   sendMemorySendChannel.send   s      mm33555	U# --::<<< 	6 =  		 }}))+',t$!%	1 	1
 mm11(;;;sP   "DA$DA( !DA&D&D(A?<D>A??BDD	Dc                    U R                   (       a  [        R                  e[        R	                  U R
                  5      $ )at  Clone this send channel object.

This returns a new `MemorySendChannel` object, which acts as a
duplicate of the original: sending on the new object does exactly the
same thing as sending on the old object. (If you're familiar with
`os.dup`, then this is a similar idea.)

However, closing one of the objects does not close the other, and
receivers don't get `EndOfChannel` until *all* clones have been
closed.

This is useful for communication patterns that involve multiple
producers all sending objects to the same destination. If you give
each producer its own clone of the `MemorySendChannel`, and then make
sure to close each `MemorySendChannel` when it's finished, receivers
will automatically get notified when all producers are finished. See
:ref:`channel-mpmc` for examples.

Raises:
  trio.ClosedResourceError: if you already closed this
      `MemorySendChannel` object.

)r[   rp   rq   r!   r"   rY   rN   s    r&   cloneMemorySendChannel.clone   s,    2 <<*** ((55r(   c                    U $ r-   r2   rN   s    r&   	__enter__MemorySendChannel.__enter__       r(   c                $    U R                  5         g r-   closer3   exc_type	exc_value	tracebacks       r&   __exit__MemorySendChannel.__exit__        	

r(   c                (   U R                   (       a  gSU l         U R                   HV  n[        R                  R	                  U[        [        R                  " 5       5      5        U R                  R                  U	 MX     U R                  R                  5         U R                  =R                  S-  sl
        U R                  R                  S:X  a  U R                  R                  (       a   eU R                  R                   Hd  nUR                  R                  R                  U5        [        R                  R	                  U[        [        R                  " 5       5      5        Mf     U R                  R                  R                  5         gg)a  Close this send channel object synchronously.

All channel objects have an asynchronous `~.AsyncResource.aclose` method.
Memory channels can also be closed synchronously. This has the same
effect on the channel and other tasks using it, but `close` is not a
trio checkpoint. This simplifies cleaning up in cancelled tasks.

Using ``with send_channel:`` will close the channel object on leaving
the with block.

NTr   r   )r[   r\   rp   rv   rw   r
   rq   rY   rJ   clearrB   rK   rt   ru   EndOfChannelr3   r{   s     r&   r   MemorySendChannel.close  s    <<KKDMM$$T51I1I1K+LM&&t,   	&&!+&;;))Q.{{----11&&--44T:((uT5F5F5H/IJ 2 KK%%++- /r(   c                |   #    U R                  5         [        R                  R                  5       I Sh  vN   g N7f)zNClose this send channel object asynchronously.

See `MemorySendChannel.close`.Nr   rp   rv   
checkpointrN   s    r&   acloseMemorySendChannel.aclose  &     
 	

mm&&(((   2<:<r[   Nr8   Noner8   strrQ   )rz   r   r8   r   )r8   zMemorySendChannel[SendType]r8   r   r   ztype[BaseException] | Noner   zBaseException | Noner   zTracebackType | Noner8   r   )r9   r:   r;   r<   rF   r[   rR   rS   setr\   r_   rg   rO   r   r}   r   r   r   r   r   r   r=   r2   r(   r&   r!   r!      s     )(GT c*FI*,X( " "& < <8 6 68, ( (	
 
 . .6 ) )r(   r!   )	metaclassc                     \ rS rSr% S\S'   SrS\S'   \R                  " \5      r	S\S'   SS	 jr
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S jr\SS j5       r\SS j5       rSrg)r#   i&  zMemoryChannelState[ReceiveType]rY   FrZ   r[   zset[trio._core._run.Task]r\   c                B    U R                   =R                  S-  sl        g r^   )rY   rC   rN   s    r&   r_   (MemoryReceiveChannel.__attrs_post_init__-  s    ))Q.)r(   c                6    U R                   R                  5       $ rj   rk   rN   s    r&   rO   MemoryReceiveChannel.statistics0  s     {{%%''r(   c                P    S[        U 5      S S[        U R                  5      S S3$ )Nz<receive channel at rb   rc   rd   re   rN   s    r&   rg   MemoryReceiveChannel.__repr__5  s-    "2d8B-/A"T[[/RTAUUVW	
r(   c                   U R                   (       a  [        R                  eU R                  R                  (       a  U R                  R                  R                  SS9u  pUR                  R                  R                  U5        [        R                  R                  U5        U R                  R                  R                  U5        U R                  R                  (       a$  U R                  R                  R                  5       $ U R                  R                  (       d  [        R                  e[        R                   e)z|Like `~trio.abc.ReceiveChannel.receive`, but if there's nothing
ready to receive, raises `WouldBlock` instead of blocking.

Frn   )r[   rp   rq   rY   rJ   rs   rt   r\   ru   rv   rw   rI   rx   popleftrB   r   ry   )r3   r{   rz   s      r&   receive_nowait#MemoryReceiveChannel.receive_nowait:  s     <<***;;!!++0088e8DKD""))006MM$$T*KK##E*;;;;##++--{{--###oor(   c                  ^ ^#    [         R                  R                  5       I Sh  vN    T R                  5       n[         R                  R	                  5       I Sh  vN   U$  N= N! [         R
                   a     Of = f[         R                  R                  5       mT R                  R                  T5        ST R                  R                  T'   T Tl        SU U4S jjn[         R                  R                  U5      I Sh  vN  $ 7f)zSee `ReceiveChannel.receive <trio.abc.ReceiveChannel.receive>`.

Memory channels allow multiple tasks to call `receive` at the same
time. The first task will get the first item sent, the second task
will get the second item sent, and so on.

Nc                   > TR                   R                  T5        TR                  R                  T	 [        R
                  R                  R                  $ r-   )r\   ru   rY   rK   rp   rv   r   r   r   s    r&   r   .MemoryReceiveChannel.receive.<locals>.abort_fne  s=    KKt$))$/==&&000r(   r   )rp   rv   r   r   r   ry   r   r\   r   rY   rK   rt   r   r   s   `  @r&   receiveMemoryReceiveChannel.receiveN  s      mm33555	'')E --::<<<L 	6 =  		 }}))+*.!!$'!%	1 	1 ]]88BBBBsP   "DA$DA( !DA&D&D(A?<D>A??BDD	Dc                    U R                   (       a  [        R                  e[        R	                  U R
                  5      $ )a<  Clone this receive channel object.

This returns a new `MemoryReceiveChannel` object, which acts as a
duplicate of the original: receiving on the new object does exactly
the same thing as receiving on the old object.

However, closing one of the objects does not close the other, and the
underlying channel is not closed until all clones are closed. (If
you're familiar with `os.dup`, then this is a similar idea.)

This is useful for communication patterns that involve multiple
consumers all receiving objects from the same underlying channel. See
:ref:`channel-mpmc` for examples.

.. warning:: The clones all share the same underlying channel.
   Whenever a clone :meth:`receive`\s a value, it is removed from the
   channel and the other clones do *not* receive that value. If you
   want to send multiple copies of the same stream of values to
   multiple destinations, like :func:`itertools.tee`, then you need to
   find some other solution; this method does *not* do that.

Raises:
  trio.ClosedResourceError: if you already closed this
      `MemoryReceiveChannel` object.

)r[   rp   rq   r#   r"   rY   rN   s    r&   r   MemoryReceiveChannel.clonen  s,    8 <<***#++DKK88r(   c                    U $ r-   r2   rN   s    r&   r   MemoryReceiveChannel.__enter__  r   r(   c                $    U R                  5         g r-   r   r   s       r&   r   MemoryReceiveChannel.__exit__  r   r(   c                p   U R                   (       a  gSU l         U R                   HV  n[        R                  R	                  U[        [        R                  " 5       5      5        U R                  R                  U	 MX     U R                  R                  5         U R                  =R                  S-  sl
        U R                  R                  S:X  a  U R                  R                  (       a   eU R                  R                   Hd  nUR                  R                  R                  U5        [        R                  R	                  U[        [        R                  " 5       5      5        Mf     U R                  R                  R                  5         U R                  R                  R                  5         gg)a  Close this receive channel object synchronously.

All channel objects have an asynchronous `~.AsyncResource.aclose` method.
Memory channels can also be closed synchronously. This has the same
effect on the channel and other tasks using it, but `close` is not a
trio checkpoint. This simplifies cleaning up in cancelled tasks.

Using ``with receive_channel:`` will close the channel object on
leaving the with block.

NTr   r   )r[   r\   rp   rv   rw   r
   rq   rY   rK   r   rC   rJ   rt   ru   rr   rI   r   s     r&   r   MemoryReceiveChannel.close  s&    <<KKDMM$$T51I1I1K+LM))$/   	))Q.);;,,1{{0000..&&--44T:((uT5M5M5O/PQ / KK""((*KK""$ 2r(   c                |   #    U R                  5         [        R                  R                  5       I Sh  vN   g N7f)zTClose this receive channel object asynchronously.

See `MemoryReceiveChannel.close`.Nr   rN   s    r&   r   MemoryReceiveChannel.aclose  r   r   r   Nr   rQ   r   )r8   r   )r8   z!MemoryReceiveChannel[ReceiveType]r   r   )r9   r:   r;   r<   rF   r[   rR   rS   r   r\   r_   rO   rg   r   r   r   r   r   r   r   r   r=   r2   r(   r&   r#   r#   &  s     ,+GT(-c(:F%:/(


  & C C> 9 9>, ( (	
 
 % %8 ) )r(   r#   r6   )+
__future__r   collectionsr   r   mathr   typingr   r   r	   rR   outcomer
   r   rp   _abcr   r   r   r   r   _corer   r   r   r   _utilr   r   r   typesr   typing_extensionsr   r'   r*   frozenr?   definer    r!   r#   r2   r(   r&   <module>r      s0   " *       G G B B ? ?#&> >9>H e$UV  ++?@    
 
 
, U%0O)H-9L O) 1 O)d U%0T)>+6BU T) 1 T)r(   