
    ,hX                       d dl mZ d dlZd dlmZm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 d dlmZmZ d dlZd d	lmZmZ d dlZd
dlmZmZmZmZmZ d
dlmZm Z m!Z!m"Z" d
dl#m$Z$m%Z%m&Z&m'Z'm(Z( ejR                  dk  rd dl*m+Z+ erd dl,m-Z- d dl.m/Z/m0Z0  e/d      Z1ndejd                  v r	 d dl.m/Z/  e/d      Z1	 	 	 	 d(dZ4er G d de5d         Z6n e'e4      Z6ejn                   G d d             Z8ejr                   G d dee                Z:e& ejr                  ddd       G d  d!ee   e%"                    Z;e& ejr                  ddd       G d# d$ee   e%"                    Z< G d% d&ee         Z=	 	 	 	 d)d'Z>y# e3$ r dZ1Y w xY w)*    )annotationsN)OrderedDictdeque)AsyncGeneratorCallable)AbstractAsyncContextManagerasynccontextmanager)wraps)inf)TYPE_CHECKINGGeneric)ErrorValue   )ReceiveChannelReceiveTypeSendChannelSendTypeT)AbortRaiseCancelTTaskenable_ki_protection)MultipleExceptionErrorNoPublicConstructorfinalgeneric_function!raise_single_exception_from_group)      )BaseExceptionGroup)TracebackType)	ParamSpecSelfPsphinx)r#   .c                    | t         k7  rt        | t              st        d      | dk  rt	        d      t        |       }t        t           j                  |      t        t           j                  |      fS )u	  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     O/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/trio/_channel.py_open_memory_channelr3   0   sp    l #j#&FHII788#5o#FE!$$U+Q''.     c                  $    e Zd Z	 	 	 	 ddZddZy)open_memory_channelc                    t        |      S N)r3   )clsr0   s     r2   __new__zopen_memory_channel.__new__w   s     (88r4   c                     y r8    )selfr0   s     r2   __init__zopen_memory_channel.__init__}   s    r4   Nr0   int | floatreturnz4tuple[MemorySendChannel[T], MemoryReceiveChannel[T]])r0   r@   rA   None)__name__
__module____qualname__r:   r>   r<   r4   r2   r6   r6   v   s    	9(	9 B	9	r4   r6   )zMemorySendChannel[T]MemoryReceiveChannel[T]c                  J    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   y	)
MemoryChannelStatisticsr)   current_buffer_usedr@   r0   open_send_channelsopen_receive_channelstasks_waiting_sendtasks_waiting_receiveN)rC   rD   rE   __annotations__r<   r4   r2   rH   rH      s&      r4   rH   c                      e Zd ZU ded<    ej
                  e      Zded<   dZded<   dZ	ded<    ej
                  e
      Zd	ed
<    ej
                  e
      Zded<   ddZy)r,   r@   r0   zdeque[T]datar   r)   rJ   rK   zOrderedDict[Task, T]
send_taskszOrderedDict[Task, None]receive_tasksc           
         t        t        | j                        | j                  | j                  | j
                  t        | j                        t        | j                              S )N)rI   r0   rJ   rK   rL   rM   )rH   lenrP   r0   rJ   rK   rQ   rR   r=   s    r2   
statisticszMemoryChannelState.statistics   sO    & #DII 00#66"&"<"<"4??3"%d&8&8"9
 	
r4   NrA   rH   )rC   rD   rE   rN   attrsFactoryr   rP   rJ   rK   r   rQ   rR   rV   r<   r4   r2   r,   r,      sd      "U]]5)D()!"3"'4u}}['AJ$A-:U]];-GM*G
r4   r,   F)eqreprslotsc                      e Zd ZU ded<   dZded<    ej                  e      Zded<   ddZ	dd	Z
dd
Zedd       Zedd       Zedd       ZddZ	 	 	 	 	 	 	 	 ddZedd       Zedd       Zy)r-   zMemoryChannelState[SendType]_stateFbool_closedz	set[Task]_tasksc                B    | j                   xj                  dz  c_        y Nr   )r^   rJ   rU   s    r2   __attrs_post_init__z%MemorySendChannel.__attrs_post_init__   s    &&!+&r4   c                P    dt        |       ddt        | j                        ddS )Nz<send channel at #x, using buffer at >idr^   rU   s    r2   __repr__zMemorySendChannel.__repr__   s+    "2d8B-/A"T[[/RTAUUVWWr4   c                6    | j                   j                         S z[Returns a `MemoryChannelStatistics` for the memory channel this is
        associated with.r^   rV   rU   s    r2   rV   zMemorySendChannel.statistics   s     {{%%''r4   c                   | j                   rt        j                  | j                  j                  dk(  rt        j
                  | j                  j                  r| j                  j                  rJ | j                  j                  j                  d      \  }}|j                  j                  j                  |       t        j                  j                  |t        |             yt        | j                  j                        | j                  j                   k  r&| j                  j                  j#                  |       yt        j$                  )zLike `~trio.abc.SendChannel.send`, but if the channel's buffer is
        full, raises `WouldBlock` instead of blocking.

        r   FlastN)r`   trioClosedResourceErrorr^   rK   BrokenResourceErrorrR   rP   popitemcustom_sleep_datara   removelowlevel
rescheduler   rT   r0   append
WouldBlock)r=   valuetask_s       r2   send_nowaitzMemorySendChannel.send_nowait   s     <<***;;,,1***;;$${{'''kk//77U7CGD!""))006MM$$T5<8!!"T[[%@%@@KK##E*//!r4   c                   K   t         j                  j                          d{    	  j                  |       t         j                  j	                          d{    y7 =7 # t         j
                  $ r Y nw xY wt         j                  j                          j                  j                         | j                  j                  <    _        d fd}t         j                  j                  |       d{  7   yw)zSee `SendChannel.send <trio.abc.SendChannel.send>`.

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

        Nc                    j                   j                         j                  j                  = t        j
                  j                  j                  S r8   )ra   rw   r^   rQ   rr   rx   r   	SUCCEEDEDr~   r=   r}   s    r2   abort_fnz(MemorySendChannel.send.<locals>.abort_fn   s=    KKt$&&t,==&&000r4   r~   r   rA   r   )rr   rx   checkpoint_if_cancelledr   cancel_shielded_checkpointr{   current_taskra   addr^   rQ   rv   wait_task_rescheduledr=   r|   r   r}   s   `  @r2   sendzMemorySendChannel.send   s      mm33555	U# --::<<< 	6 =  		 }}))+',t$!%	1
 mm11(;;;sP   "D
A$D
A( !D
A&D
&D
(A>;D
=A>>BD
DD
c                x    | j                   rt        j                  t        j	                  | j
                        S )a  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`   rr   rs   r-   r.   r^   rU   s    r2   clonezMemorySendChannel.clone   s,    2 <<*** ((55r4   c                    | S r8   r<   rU   s    r2   	__enter__zMemorySendChannel.__enter__      r4   c                $    | j                          y r8   closer=   exc_type	exc_value	tracebacks       r2   __exit__zMemorySendChannel.__exit__       	

r4   c                   | j                   ryd| _         | j                  D ]T  }t        j                  j	                  |t        t        j                                      | j                  j                  |= V | j                  j                          | j                  xj                  dz  c_
        | j                  j                  dk(  r| j                  j                  rJ | j                  j                  D ]b  }|j                  j                  j                  |       t        j                  j	                  |t        t        j                                      d | j                  j                  j                          yy)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`   ra   rr   rx   ry   r   rs   r^   rQ   clearrJ   rR   rv   rw   EndOfChannelr=   r}   s     r2   r   zMemorySendChannel.close  s    <<KK 	-DMM$$T51I1I1K+LM&&t,	- 	&&!+&;;))Q.{{---11 K&&--44T:((uT5F5F5H/IJK KK%%++- /r4   c                |   K   | j                          t        j                  j                          d{    y7 w)zVClose this send channel object asynchronously.

        See `MemorySendChannel.close`.Nr   rr   rx   
checkpointrU   s    r2   aclosezMemorySendChannel.aclose2  '     
 	

mm&&(((   2<:<NrA   rB   rA   strrW   )r|   r   rA   rB   )rA   zMemorySendChannel[SendType]rA   r$   r   ztype[BaseException] | Noner   zBaseException | Noner   zTracebackType | NonerA   rB   )rC   rD   rE   rN   r`   rX   rY   setra   rd   rk   rV   r   r   r   r   r   r   r   r   r<   r4   r2   r-   r-      s     )(GT &c*FI*,X( " "& < <8 6 68, ( (	
 
 . .6 ) )r4   r-   )	metaclassc                      e Zd ZU ded<   dZded<    ej                  e      Zded<   ddZ	dd	Z
dd
Zedd       Zedd       Zedd       ZddZ	 	 	 	 	 	 	 	 ddZedd       Zedd       Zy)r/   zMemoryChannelState[ReceiveType]r^   Fr_   r`   zset[trio._core._run.Task]ra   c                B    | j                   xj                  dz  c_        y rc   )r^   rK   rU   s    r2   rd   z(MemoryReceiveChannel.__attrs_post_init__B  s    ))Q.)r4   c                6    | j                   j                         S rm   rn   rU   s    r2   rV   zMemoryReceiveChannel.statisticsE  s     {{%%''r4   c                P    dt        |       ddt        | j                        ddS )Nz<receive channel at rf   rg   rh   ri   rU   s    r2   rk   zMemoryReceiveChannel.__repr__J  s-    "2d8B-/A"T[[/RTAUUVW	
r4   c                j   | j                   rt        j                  | j                  j                  r| j                  j                  j                  d      \  }}|j                  j                  j                  |       t        j                  j                  |       | j                  j                  j                  |       | j                  j                  r$| j                  j                  j                         S | j                  j                  st        j                  t        j                   )zLike `~trio.abc.ReceiveChannel.receive`, but if there's nothing
        ready to receive, raises `WouldBlock` instead of blocking.

        Frp   )r`   rr   rs   r^   rQ   ru   rv   ra   rw   rx   ry   rP   rz   popleftrJ   r   r{   )r=   r}   r|   s      r2   receive_nowaitz#MemoryReceiveChannel.receive_nowaitO  s     <<***;;!!++0088e8DKD%""))006MM$$T*KK##E*;;;;##++--{{--###oor4   c                   K   t         j                  j                          d{    	  j                         }t         j                  j	                          d{    |S 7 =7 # t         j
                  $ r Y nw xY wt         j                  j                          j                  j                         d j                  j                  <    _        d fd}t         j                  j                  |       d{  7  S w)a  See `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                    j                   j                         j                  j                  = t        j
                  j                  j                  S r8   )ra   rw   r^   rR   rr   rx   r   r   r   s    r2   r   z.MemoryReceiveChannel.receive.<locals>.abort_fnz  s=    KKt$))$/==&&000r4   r   )rr   rx   r   r   r   r{   r   ra   r   r^   rR   rv   r   r   s   `  @r2   receivezMemoryReceiveChannel.receivec  s      mm33555	'')E --::<<<L 	6 =  		 }}))+*.!!$'!%	1 ]]88BBBBsP   "D	A$D	A( !D	A&D	&D	(A>;D	=A>>BD	DD	c                x    | j                   rt        j                  t        j	                  | j
                        S )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`   rr   rs   r/   r.   r^   rU   s    r2   r   zMemoryReceiveChannel.clone  s,    8 <<***#++DKK88r4   c                    | S r8   r<   rU   s    r2   r   zMemoryReceiveChannel.__enter__  r   r4   c                $    | j                          y r8   r   r   s       r2   r   zMemoryReceiveChannel.__exit__  r   r4   c                N   | j                   ryd| _         | j                  D ]T  }t        j                  j	                  |t        t        j                                      | j                  j                  |= V | j                  j                          | j                  xj                  dz  c_
        | j                  j                  dk(  r| j                  j                  rJ | j                  j                  D ]b  }|j                  j                  j                  |       t        j                  j	                  |t        t        j                                      d | j                  j                  j                          | j                  j                  j                          yy)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`   ra   rr   rx   ry   r   rs   r^   rR   r   rK   rQ   rv   rw   rt   rP   r   s     r2   r   zMemoryReceiveChannel.close  s/    <<KK 	0DMM$$T51I1I1K+LM))$/	0 	))Q.);;,,1{{000.. R&&--44T:((uT5M5M5O/PQR KK""((*KK""$ 2r4   c                |   K   | j                          t        j                  j                          d{    y7 w)z\Close this receive channel object asynchronously.

        See `MemoryReceiveChannel.close`.Nr   rU   s    r2   r   zMemoryReceiveChannel.aclose  r   r   Nr   rW   r   )rA   r   )rA   z!MemoryReceiveChannel[ReceiveType]r   r   )rC   rD   rE   rN   r`   rX   rY   r   ra   rd   rV   rk   r   r   r   r   r   r   r   r   r<   r4   r2   r/   r/   ;  s     ,+GT(5c(:F%:/(


  & C C> 9 9>, ( (	
 
 % %8 ) )r4   r/   c                  P    e Zd Z	 	 	 	 	 	 ddZddZd	dZd
dZ	 	 	 	 	 	 	 	 ddZy)RecvChanWrapperc                     || _         || _        y r8   )
_recv_chan_send_semaphore)r=   	recv_chansend_semaphores      r2   r>   zRecvChanWrapper.__init__  s     $-r4   c                   K   | j                   j                          | j                  j                          d {   S 7 wr8   )r   releaser   r   rU   s    r2   r   zRecvChanWrapper.receive  s1     $$&__,,....s   8A?Ac                T   K   | j                   j                          d {    y 7 wr8   )r   r   rU   s    r2   r   zRecvChanWrapper.aclose  s     oo$$&&&s   (&(c                    | S r8   r<   rU   s    r2   r   zRecvChanWrapper.__enter__  r   r4   c                8    | j                   j                          y r8   )r   r   r   s       r2   r   zRecvChanWrapper.__exit__  s     	r4   N)r   rF   r   trio.SemaphorerA   rB   )rA   r   r   r   r   )rC   rD   rE   r>   r   r   r   r   r<   r4   r2   r   r     sY    .0.BP.	./' ,  (  (	 
 
 r4   r   c                n     t         t               	 	 	 	 	 	 d fd              }	 	 	 	 	 	 	 	 	 	 dd|S )a  Decorate an async generator function to make it cancellation-safe.

    The ``yield`` keyword offers a very convenient way to write iterators...
    which makes it really unfortunate that async generators are so difficult
    to call correctly.  Yielding from the inside of a cancel scope or a nursery
    to the outside `violates structured concurrency <https://xkcd.com/292/>`_
    with consequences explained in :pep:`789`.  Even then, resource cleanup
    errors remain common (:pep:`533`) unless you wrap every call in
    :func:`~contextlib.aclosing`.

    This decorator gives you the best of both worlds: with careful exception
    handling and a background task we preserve structured concurrency by
    offering only the safe interface, and you can still write your iterables
    with the convenience of ``yield``.  For example::

        @as_safe_channel
        async def my_async_iterable(arg, *, kwarg=True):
            while ...:
                item = await ...
                yield item

        async with my_async_iterable(...) as recv_chan:
            async for item in recv_chan:
                ...

    While the combined async-with-async-for can be inconvenient at first,
    the context manager is indispensable for both correctness and for prompt
    cleanup of resources.
    c                P  K   t        j                  t           d      \  }}	 t        j                  d      4 d {   } 
| i |}t        j                  d      }|j                  	|||       d {    t        ||      5 }| d d d        |j                  j                          d d d       d {    y 7 7 K# 1 sw Y   8xY w7 # 1 d {  7  sw Y   y xY w# t        $ r2}	 t        |       n# t        $ r t        d|g      d w xY wY d }~y d }~ww xY ww)Nr   T)strict_exception_groupsz}Encountered exception during cleanup of generator object, as well as exception in the contextmanager body - unable to unwrap.)rr   r6   r   open_nursery	Semaphorestartr   cancel_scopecancelr!   r   r   )argskwargs	send_chanr   nurseryagenr   wrapped_recv_chaneg_move_elems_to_channelfns            r2   context_managerz(as_safe_channel.<locals>.context_manager  s:    
  $77:1=	9	((F . .'4*6*!%!2 mm*D)^   %Y? ,CT++, $$++-. . ., ,. . . . " 		1"5)  ) TD  6		s    D&C( CC( 5C7C8CC"C0C( ;C<C(  D&C( CC	
CC( C%CC%!C( $D&%C( (	D#2C>=D>DDD&D##D&c                  K   |5  	 |j                          	 |j                          d {    	 | j                          d {   }|j                  |       d {    K7 77  # t        $ r$ Y | j	                          d {  7   d d d        y w xY w7 9# | j	                          d {  7   w xY w# 1 sw Y   y xY wwr8   )startedacquire	__anext__StopAsyncIterationr   r   )r   r   r   task_statusr|   s        r2   r   z/as_safe_channel.<locals>._move_elems_to_channel2  s       	$$##%(00222&*nn&6 6 $../// 2 6- 
 kkm##	$ 	$ 0 kkm##	$ 	$s   CB7$BA#BA'A%A'	BBB%A''	B0B1B7BB7
	CBBB4-B0
.B44B77C <C)r   zP.argsr   zP.kwargsrA   z6AsyncGenerator[trio._channel.RecvChanWrapper[T], None])
r   zAsyncGenerator[T, None]r   ztrio.MemorySendChannel[T]r   r   r   ztrio.TaskStatusrA   rB   )r	   r
   )r   r   r   s   ` @r2   as_safe_channelr     sw    F 
2Y!)	?  >$%$,$ '$ %	$
 
$0 r4   r?   )r   z$Callable[P, AsyncGenerator[T, None]]rA   z;Callable[P, AbstractAsyncContextManager[ReceiveChannel[T]]])?
__future__r   syscollectionsr   r   collections.abcr   r   
contextlibr   r	   	functoolsr
   mathr   typingr   r   rX   outcomer   r   rr   _abcr   r   r   r   r   _corer   r   r   r   _utilr   r   r   r   r   version_infoexceptiongroupr!   typesr"   typing_extensionsr#   r$   r%   modulesImportErrorr3   tupler6   frozenrH   definer,   r-   r/   r   r   r<   r4   r2   <module>r      s   " 
 * 4 G  
     G G B B  g1#1#A/ cN> >9>H e$UV  ++?@    
 
 
, U%0O)H-9L O) 1 O)d U%0T)>+6BU T) 1 T)n nQ'  4\,\@\I  s   ,F FF