
     fZ                       U d dl mZ d dlZd dlmZmZmZmZ ddlm	Z	m
Z
 ddlmZ ddlmZmZ erd dlmZ eg ee         f         Zd	ed
<   eg ef         Zd	ed<    ede          Z ede          Z G d d          Ze
j         G d de                      Ze
j         G d de                      Zddd/dZd0dZd1d"Zd2d$Z G d% d&          Z  G d' d(e          Z! G d) d*e          Z"d3d,Z#d4d.Z$dS )5    )annotationsN)TYPE_CHECKING	AwaitableCallableTypeVar   )_core_utilStapledStream)ReceiveStream
SendStream)	TypeAliasr   	AsyncHookSyncHookSendStreamT)boundReceiveStreamTc                  R    e Zd ZddZddZddZddZddZddZdddZ	dddZ
dS )_UnboundedByteQueuereturnNonec                    t                      | _        d| _        t          j                    | _        t          j        d          | _        d S )NFz%another task is already fetching data)		bytearray_data_closedr	   
ParkingLot_lotr
   ConflictDetector_fetch_lockselfs    _/var/www/api.educacionweb.es/myenv/lib/python3.11/site-packages/trio/testing/_memory_streams.py__init__z_UnboundedByteQueue.__init__   sB    [[
$&&	 13
 
    c                F    d| _         | j                                         d S NT)r   r   
unpark_allr!   s    r#   closez_UnboundedByteQueue.close'   s#    	r%   c                T    t                      | _        |                                  d S N)r   r   r)   r!   s    r#   close_and_wipez"_UnboundedByteQueue.close_and_wipe+   s    [[


r%   databytes | bytearray | memoryviewc                    | j         rt          j        d          | xj        |z  c_        | j                                         d S )Nzvirtual connection closed)r   r	   ClosedResourceErrorr   r   r(   r"   r-   s     r#   putz_UnboundedByteQueue.put/   sI    < 	I+,GHHH

d

	r%   	max_bytes
int | Nonec                `    |d S t          j        |          }|dk     rt          d          d S )N   max_bytes must be >= 1)operatorindex
ValueErrorr"   r3   s     r#   _check_max_bytesz$_UnboundedByteQueue._check_max_bytes5   s;    FN9--	q==5666 =r%   r   c                    | j         s	| j        sJ |t          | j                  }| j        r| j        d |         }| j        d |= |sJ |S t                      S r+   )r   r   lenr   )r"   r3   chunks      r#   	_get_implz_UnboundedByteQueue._get_impl<   sj    |)tz)))DJI: 	Jz	z*E
:I:&LLLL;;r%   Nc                    | j         5  |                     |           | j        s| j        st          j        |                     |          cd d d            S # 1 swxY w Y   d S r+   )r    r<   r   r   r	   
WouldBlockr@   r;   s     r#   
get_nowaitz_UnboundedByteQueue.get_nowaitH   s     	- 	-!!),,,< '
 '&&>>),,		- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   AAA Ac                *  K   | j         5  |                     |           | j        s'| j        s | j                                         d {V  nt          j                     d {V  |                     |          cd d d            S # 1 swxY w Y   d S r+   )	r    r<   r   r   r   parkr	   
checkpointr@   r;   s     r#   getz_UnboundedByteQueue.getO   s       	- 	-!!),,,< )
 )inn&&&&&&&&&&&(((((((((>>),,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   A1BBBr   r   r-   r.   r   r   )r3   r4   r   r   r3   r4   r   r   r+   )__name__
__module____qualname__r$   r)   r,   r2   r<   r@   rC   rG    r%   r#   r   r      s        
 
 
 
         7 7 7 7
 
 
 
- - - - -- - - - - - -r%   r   c                  V    e Zd ZdZ	 	 	 dddZddZddZddZddZdddZ	dddZ
dS )MemorySendStreama  An in-memory :class:`~trio.abc.SendStream`.

    Args:
      send_all_hook: An async function, or None. Called from
          :meth:`send_all`. Can do whatever you like.
      wait_send_all_might_not_block_hook: An async function, or None. Called
          from :meth:`wait_send_all_might_not_block`. Can do whatever you
          like.
      close_hook: A synchronous function, or None. Called from :meth:`close`
          and :meth:`aclose`. Can do whatever you like.

    .. attribute:: send_all_hook
                   wait_send_all_might_not_block_hook
                   close_hook

       All of these hooks are also exposed as attributes on the object, and
       you can change them at any time.

    Nsend_all_hookAsyncHook | None"wait_send_all_might_not_block_hook
close_hookSyncHook | Nonec                    t          j        d          | _        t                      | _        || _        || _        || _        d S )N!another task is using this stream)r
   r   _conflict_detectorr   	_outgoingrQ   rS   rT   )r"   rQ   rS   rT   s       r#   r$   zMemorySendStream.__init__o   sF     #("8/#
 #
 -..*2T/$r%   r-   r.   r   r   c                $  K   | j         5  t          j                     d{V  t          j                     d{V  | j                            |           | j        |                                  d{V  ddd           dS # 1 swxY w Y   dS )z}Places the given data into the object's internal buffer, and then
        calls the :attr:`send_all_hook` (if any).

        N)rX   r	   rF   rY   r2   rQ   r1   s     r#   send_allzMemorySendStream.send_all}   s       $ 	+ 	+"$$$$$$$$$"$$$$$$$$$Nt$$$!-((*********	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+   A.BB	B	c                $  K   | j         5  t          j                     d{V  t          j                     d{V  | j                            d           | j        |                                  d{V  ddd           dS # 1 swxY w Y   dS )znCalls the :attr:`wait_send_all_might_not_block_hook` (if any), and
        then returns immediately.

        Nr%   )rX   r	   rF   rY   r2   rS   r!   s    r#   wait_send_all_might_not_blockz.MemorySendStream.wait_send_all_might_not_block   s      $ 	@ 	@"$$$$$$$$$"$$$$$$$$$Ns###6B==?????????	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@r\   c                r    | j                                          | j        |                                  dS dS )z^Marks this stream as closed, and then calls the :attr:`close_hook`
        (if any).

        N)rY   r)   rT   r!   s    r#   r)   zMemorySendStream.close   s>     	?&OO '&r%   c                d   K   |                                   t          j                     d{V  dS z!Same as :meth:`close`, but async.Nr)   r	   rF   r!   s    r#   aclosezMemorySendStream.aclose   :      

           r%   r3   r4   r   c                F   K   | j                             |           d{V S )a  Retrieves data from the internal buffer, blocking if necessary.

        Args:
          max_bytes (int or None): The maximum amount of data to
              retrieve. None (the default) means to retrieve all the data
              that's present (but still blocks until at least one byte is
              available).

        Returns:
          If this stream has been closed, an empty bytearray. Otherwise, the
          requested data.

        N)rY   rG   r;   s     r#   get_datazMemorySendStream.get_data   s0       ^''	222222222r%   c                6    | j                             |          S )zRetrieves data from the internal buffer, but doesn't block.

        See :meth:`get_data` for details.

        Raises:
          trio.WouldBlock: if no data is available to retrieve.

        )rY   rC   r;   s     r#   get_data_nowaitz MemorySendStream.get_data_nowait   s     ~((333r%   )NNN)rQ   rR   rS   rR   rT   rU   rI   rH   r+   rJ   )rK   rL   rM   __doc__r$   r[   r^   r)   rc   rf   rh   rN   r%   r#   rP   rP   Y   s         , +/?C&*	% % % % %+ + + +@ @ @ @   "! ! ! !
3 3 3 3 3 	4 	4 	4 	4 	4 	4 	4r%   rP   c                  J    e Zd ZdZ	 	 dddZdddZddZddZddZddZ	dS )MemoryReceiveStreama  An in-memory :class:`~trio.abc.ReceiveStream`.

    Args:
      receive_some_hook: An async function, or None. Called from
          :meth:`receive_some`. Can do whatever you like.
      close_hook: A synchronous function, or None. Called from :meth:`close`
          and :meth:`aclose`. Can do whatever you like.

    .. attribute:: receive_some_hook
                   close_hook

       Both hooks are also exposed as attributes on the object, and you can
       change them at any time.

    Nreceive_some_hookrR   rT   rU   c                    t          j        d          | _        t                      | _        d| _        || _        || _        d S )NrW   F)r
   r   rX   r   	_incomingr   rl   rT   )r"   rl   rT   s      r#   r$   zMemoryReceiveStream.__init__   sE    
 #("8/#
 #
 -..!2$r%   r3   r4   r   r   c                ~  K   | j         5  t          j                     d{V  t          j                     d{V  | j        rt          j        | j        |                                  d{V  | j                            |           d{V }| j        rt          j        |cddd           S # 1 swxY w Y   dS )zCalls the :attr:`receive_some_hook` (if any), and then retrieves
        data from the internal buffer, blocking if necessary.

        N)rX   r	   rF   r   r0   rl   rn   rG   )r"   r3   r-   s      r#   receive_somez MemoryReceiveStream.receive_some   s6      $ 	 	"$$$$$$$$$"$$$$$$$$$| 0//%1,,.........
 ++I66666666D| 0//	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   BB22B69B6r   c                    d| _         | j                                         | j        |                                  dS dS )zfDiscards any pending data from the internal buffer, and marks this
        stream as closed.

        TN)r   rn   r,   rT   r!   s    r#   r)   zMemoryReceiveStream.close  sE    
 %%'''?&OO '&r%   c                d   K   |                                   t          j                     d{V  dS ra   rb   r!   s    r#   rc   zMemoryReceiveStream.aclose  rd   r%   r-   r.   c                :    | j                             |           dS )z.Appends the given data to the internal buffer.N)rn   r2   r1   s     r#   put_datazMemoryReceiveStream.put_data  s    4     r%   c                8    | j                                          dS )z2Adds an end-of-file marker to the internal buffer.N)rn   r)   r!   s    r#   put_eofzMemoryReceiveStream.put_eof  s    r%   )NN)rl   rR   rT   rU   r+   rJ   rH   rI   )
rK   rL   rM   ri   r$   rp   r)   rc   rt   rv   rN   r%   r#   rk   rk      s         $ /3&*% % % % %    .   ! ! ! !
! ! ! !     r%   rk   )r3   memory_send_streammemory_receive_streamr3   r4   r   boolc                  	 |                      |          }n# t          j        $ r Y dS w xY w	 |s|                                 n|                    |           n(# t          j        $ r t          j        d          dw xY wdS )a  Take data out of the given :class:`MemorySendStream`'s internal buffer,
    and put it into the given :class:`MemoryReceiveStream`'s internal buffer.

    Args:
      memory_send_stream (MemorySendStream): The stream to get data from.
      memory_receive_stream (MemoryReceiveStream): The stream to put data into.
      max_bytes (int or None): The maximum amount of data to transfer in this
          call, or None to transfer all available data.

    Returns:
      True if it successfully transferred some data, or False if there was no
      data to transfer.

    This is used to implement :func:`memory_stream_one_way_pair` and
    :func:`memory_stream_pair`; see the latter's docstring for an example
    of how you might use it yourself.

    FzMemoryReceiveStream was closedNT)rh   r	   rB   rv   rt   r0   BrokenResourceError)rw   rx   r3   r-   s       r#   memory_stream_pumpr|     s    0!11)<<   uuT 	1!))++++!**4000$ T T T'(HIItST4s    ++,A %B,tuple[MemorySendStream, MemoryReceiveStream]c                 ~    t                      t                      dfddfd} | _        _        fS )uQ  Create a connected, pure-Python, unidirectional stream with infinite
    buffering and flexible configuration options.

    You can think of this as being a no-operating-system-involved
    Trio-streamsified version of :func:`os.pipe` (except that :func:`os.pipe`
    returns the streams in the wrong order – we follow the superior convention
    that data flows from left to right).

    Returns:
      A tuple (:class:`MemorySendStream`, :class:`MemoryReceiveStream`), where
      the :class:`MemorySendStream` has its hooks set up so that it calls
      :func:`memory_stream_pump` from its
      :attr:`~MemorySendStream.send_all_hook` and
      :attr:`~MemorySendStream.close_hook`.

    The end result is that data automatically flows from the
    :class:`MemorySendStream` to the :class:`MemoryReceiveStream`. But you're
    also free to rearrange things however you like. For example, you can
    temporarily set the :attr:`~MemorySendStream.send_all_hook` to None if you
    want to simulate a stall in data transmission. Or see
    :func:`memory_stream_pair` for a more elaborate example.

    r   r   c                 (    t                      d S r+   )r|   )recv_streamsend_streams   r#   $pump_from_send_stream_to_recv_streamzHmemory_stream_one_way_pair.<locals>.pump_from_send_stream_to_recv_stream[  s    ;44444r%   c                     K                  d S r+   rN   )r   s   r#   *async_pump_from_send_stream_to_recv_streamzNmemory_stream_one_way_pair.<locals>.async_pump_from_send_stream_to_recv_stream^  s      ,,.....r%   rH   )rP   rk   rQ   rT   )r   r   r   r   s    @@@r#   memory_stream_one_way_pairr   @  s|    0 #$$K%''K5 5 5 5 5 5 5/ / / / / / !KKAK##r%   one_way_pair0Callable[[], tuple[SendStreamT, ReceiveStreamT]]]tuple[StapledStream[SendStreamT, ReceiveStreamT], StapledStream[SendStreamT, ReceiveStreamT]]c                ~     |             \  }} |             \  }}t          ||          }t          ||          }||fS r+   r   )r   
pipe1_send
pipe1_recv
pipe2_send
pipe2_recvstream1stream2s          r#   _make_stapled_pairr   f  sM     *\^^J
)\^^J
J
33GJ
33GGr%   qtuple[StapledStream[MemorySendStream, MemoryReceiveStream], StapledStream[MemorySendStream, MemoryReceiveStream]]c                 *    t          t                    S )a  Create a connected, pure-Python, bidirectional stream with infinite
    buffering and flexible configuration options.

    This is a convenience function that creates two one-way streams using
    :func:`memory_stream_one_way_pair`, and then uses
    :class:`~trio.StapledStream` to combine them into a single bidirectional
    stream.

    This is like a no-operating-system-involved, Trio-streamsified version of
    :func:`socket.socketpair`.

    Returns:
      A pair of :class:`~trio.StapledStream` objects that are connected so
      that data automatically flows from one to the other in both directions.

    After creating a stream pair, you can send data back and forth, which is
    enough for simple tests::

       left, right = memory_stream_pair()
       await left.send_all(b"123")
       assert await right.receive_some() == b"123"
       await right.send_all(b"456")
       assert await left.receive_some() == b"456"

    But if you read the docs for :class:`~trio.StapledStream` and
    :func:`memory_stream_one_way_pair`, you'll see that all the pieces
    involved in wiring this up are public APIs, so you can adjust to suit the
    requirements of your tests. For example, here's how to tweak a stream so
    that data flowing from left to right trickles in one byte at a time (but
    data flowing from right to left proceeds at full speed)::

        left, right = memory_stream_pair()
        async def trickle():
            # left is a StapledStream, and left.send_stream is a MemorySendStream
            # right is a StapledStream, and right.recv_stream is a MemoryReceiveStream
            while memory_stream_pump(left.send_stream, right.recv_stream, max_bytes=1):
                # Pause between each byte
                await trio.sleep(1)
        # Normally this send_all_hook calls memory_stream_pump directly without
        # passing in a max_bytes. We replace it with our custom version:
        left.send_stream.send_all_hook = trickle

    And here's a simple test using our modified stream objects::

        async def sender():
            await left.send_all(b"12345")
            await left.send_eof()

        async def receiver():
            async for data in right:
                print(data)

        async with trio.open_nursery() as nursery:
            nursery.start_soon(sender)
            nursery.start_soon(receiver)

    By default, this will print ``b"12345"`` and then immediately exit; with
    our trickle stream it instead sleeps 1 second, then prints ``b"1"``, then
    sleeps 1 second, then prints ``b"2"``, etc.

    Pro-tip: you can insert sleep calls (like in our example above) to
    manipulate the flow of data across tasks... and then use
    :class:`MockClock` and its :attr:`~MockClock.autojump_threshold`
    functionality to keep your test suite running quickly.

    If you want to stress test a protocol implementation, one nice trick is to
    use the :mod:`random` module (preferably with a fixed seed) to move random
    numbers of bytes at a time, and insert random sleeps in between them. You
    can also set up a custom :attr:`~MemoryReceiveStream.receive_some_hook` if
    you want to manipulate things on the receiving side, and not just the
    sending side.

    )r   r   rN   r%   r#   memory_stream_pairr   s  s    Z 8999r%   c                  P    e Zd ZddZddZddZddZdd	ZddZddZ	dddZ
dS )_LockstepByteQueuer   r   c                    t                      | _        d| _        d| _        d| _        t          j                    | _        t          j	        d          | _
        t          j	        d          | _        d S )NFzanother task is already sendingz!another task is already receiving)r   r   _sender_closed_receiver_closed_receiver_waitingr	   r   _waitersr
   r   _send_conflict_detector_receive_conflict_detectorr!   s    r#   r$   z_LockstepByteQueue.__init__  sm    [[
# %!&(**','=-(
 (
$ +0*@/+
 +
'''r%   c                8    | j                                          d S r+   )r   r(   r!   s    r#   _something_happenedz&_LockstepByteQueue._something_happened  s      """""r%   fnCallable[[], bool]c                   K   	  |            rn/| j         s| j        rn | j                                         d {V  :t	          j                     d {V  d S r+   )r   r   r   rE   r	   rF   )r"   r   s     r#   	_wait_forz_LockstepByteQueue._wait_for  s      	'rtt " d&; -$$&&&&&&&&&	'            r%   c                <    d| _         |                                  d S r'   )r   r   r!   s    r#   close_senderz_LockstepByteQueue.close_sender  s"    "  """""r%   c                <    d| _         |                                  d S r'   )r   r   r!   s    r#   close_receiverz!_LockstepByteQueue.close_receiver  s"     $  """""r%   r-   r.   c                   K    j         5   j        rt          j         j        rt          j         j        rJ  xj        |z  c_                                                                fd           d {V   j        rt          j         j        r j        rt          j        d d d            d S # 1 swxY w Y   d S )Nc                      j         dk    S Nr%   r   r!   s   r#   <lambda>z-_LockstepByteQueue.send_all.<locals>.<lambda>  s    s): r%   )	r   r   r	   r0   r   r{   r   r   r   r1   s   ` r#   r[   z_LockstepByteQueue.send_all  s+     ) 	0 	0" 0//$ 0//z!!!JJ$JJ$$&&&..!:!:!:!:;;;;;;;;;" 0//z 0d3 0//	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0s   BB77B;>B;c                2   K    j         5   j        rt          j         j        r't          j                     d {V  	 d d d            d S                       fd           d {V   j        rt          j        	 d d d            d S # 1 swxY w Y   d S )Nc                      j         S r+   )r   r!   s   r#   r   zB_LockstepByteQueue.wait_send_all_might_not_block.<locals>.<lambda>  s
    )? r%   )r   r   r	   r0   r   rF   r   r!   s   `r#   r^   z0_LockstepByteQueue.wait_send_all_might_not_block  s(     ) 	0 	0" 0//$ &(((((((((	0 	0 	0 	0 	0 	0 	0 	0 ..!?!?!?!?@@@@@@@@@" 0//0	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0s   5B1BBBNr3   r4   bytes | bytearrayc                "   K    j         5  |)t          j        |          }|dk     rt          d           j        rt
          j        d _                                          	  	                     fd           d {V  d _        n# d _        w xY w j        rt
          j         j
        r; j
        d |         } j
        d |=                                   |cd d d            S  j        sJ 	 d d d            dS # 1 swxY w Y   d S )Nr6   r7   Tc                      j         dk    S r   r   r!   s   r#   r   z1_LockstepByteQueue.receive_some.<locals>.<lambda>  s    TZ3-> r%   Fr%   )r   r8   r9   r:   r   r	   r0   r   r   r   r   r   )r"   r3   gots   `  r#   rp   z_LockstepByteQueue.receive_some  s     , 	 	$$N955	q==$%=>>>$ 0//%)D"$$&&&/nn%>%>%>%>?????????).&&&....$ 0//z 	 j),Jz	z*((***3	 	 	 	 	 	 	 	6 ****9	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s1   AD&BD	BAD-
DDDrH   )r   r   r   r   rI   r+   r3   r4   r   r   )rK   rL   rM   r$   r   r   r   r   r[   r^   rp   rN   r%   r#   r   r     s        
 
 
 
# # # #
! ! ! !# # # ## # # #0 0 0 0	0 	0 	0 	0      r%   r   c                  6    e Zd ZddZddZddZdd
ZddZdS )_LockstepSendStreamlbqr   c                    || _         d S r+   _lbqr"   r   s     r#   r$   z_LockstepSendStream.__init__'      			r%   r   r   c                8    | j                                          d S r+   )r   r   r!   s    r#   r)   z_LockstepSendStream.close*  s    	     r%   c                d   K   |                                   t          j                     d {V  d S r+   rb   r!   s    r#   rc   z_LockstepSendStream.aclose-  :      

           r%   r-   r.   c                J   K   | j                             |           d {V  d S r+   )r   r[   r1   s     r#   r[   z_LockstepSendStream.send_all1  s4      i  &&&&&&&&&&&r%   c                H   K   | j                                          d {V  d S r+   )r   r^   r!   s    r#   r^   z1_LockstepSendStream.wait_send_all_might_not_block4  s2      i5577777777777r%   Nr   r   rH   rI   )rK   rL   rM   r$   r)   rc   r[   r^   rN   r%   r#   r   r   &  sx           ! ! ! !! ! ! !' ' ' '8 8 8 8 8 8r%   r   c                  0    e Zd ZddZddZddZdddZdS )_LockstepReceiveStreamr   r   c                    || _         d S r+   r   r   s     r#   r$   z_LockstepReceiveStream.__init__9  r   r%   r   r   c                8    | j                                          d S r+   )r   r   r!   s    r#   r)   z_LockstepReceiveStream.close<  s    	  """""r%   c                d   K   |                                   t          j                     d {V  d S r+   rb   r!   s    r#   rc   z_LockstepReceiveStream.aclose?  r   r%   Nr3   r4   r   c                F   K   | j                             |           d {V S r+   )r   rp   r;   s     r#   rp   z#_LockstepReceiveStream.receive_someC  s.      Y++I666666666r%   r   rH   r+   r   )rK   rL   rM   r$   r)   rc   rp   rN   r%   r#   r   r   8  si           # # # #! ! ! !7 7 7 7 7 7 7r%   r    tuple[SendStream, ReceiveStream]c                 Z    t                      } t          |           t          |           fS )a  Create a connected, pure Python, unidirectional stream where data flows
    in lockstep.

    Returns:
      A tuple
      (:class:`~trio.abc.SendStream`, :class:`~trio.abc.ReceiveStream`).

    This stream has *absolutely no* buffering. Each call to
    :meth:`~trio.abc.SendStream.send_all` will block until all the given data
    has been returned by a call to
    :meth:`~trio.abc.ReceiveStream.receive_some`.

    This can be useful for testing flow control mechanisms in an extreme case,
    or for setting up "clogged" streams to use with
    :func:`check_one_way_stream` and friends.

    In addition to fulfilling the :class:`~trio.abc.SendStream` and
    :class:`~trio.abc.ReceiveStream` interfaces, the return objects
    also have a synchronous ``close`` method.

    )r   r   r   )r   s    r#   lockstep_stream_one_way_pairr   G  s+    . 

Cs##%;C%@%@@@r%   Ytuple[StapledStream[SendStream, ReceiveStream], StapledStream[SendStream, ReceiveStream]]c                 *    t          t                    S )a  Create a connected, pure-Python, bidirectional stream where data flows
    in lockstep.

    Returns:
      A tuple (:class:`~trio.StapledStream`, :class:`~trio.StapledStream`).

    This is a convenience function that creates two one-way streams using
    :func:`lockstep_stream_one_way_pair`, and then uses
    :class:`~trio.StapledStream` to combine them into a single bidirectional
    stream.

    )r   r   rN   r%   r#   lockstep_stream_pairr   b  s      :;;;r%   )rw   rP   rx   rk   r3   r4   r   ry   )r   r}   )r   r   r   r   )r   r   )r   r   )r   r   )%
__future__r   r8   typingr   r   r   r    r	   r
   _highlevel_genericr   abcr   r   typing_extensionsr   objectr   __annotations__r   r   r   r   finalrP   rk   r|   r   r   r   r   r   r   r   r   rN   r%   r#   <module>r      s   " " " " " " "  > > > > > > > > > > > >         . . . . . . + + + + + + + + ,++++++  If$5 56	 6 6 6 6r6z* * * * *gm:666)???<- <- <- <- <- <- <- <-~ o4 o4 o4 o4 o4z o4 o4 o4d J J J J J- J J Jb !	# # # # # #L#$ #$ #$ #$L
 
 
 
M: M: M: M:j[ [ [ [ [ [ [ [|8 8 8 8 8* 8 8 8$7 7 7 7 7] 7 7 7A A A A6< < < < < <r%   