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
U
Z±d8ã@söddlmZmZddlmZddlZddlmZmZddl    m
Z
m Z m Z ddl mZmZddlZddlmZed    d
„ƒZejd d d Gd d„dƒƒZejd dGdd„dƒƒZejdddGdd„de
edƒZejdddGdd„de edƒZdS)é)ÚdequeÚ OrderedDict)ÚinfN)ÚErrorÚValueé)Ú SendChannelÚReceiveChannelÚChannel)Úgeneric_functionÚNoPublicConstructor)Úenable_ki_protectioncCsF|tkrt|tƒstdƒ‚|dkr*tdƒ‚t|ƒ}t |¡t |¡fS)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.infrzmax_buffer_size must be >= 0)    rÚ
isinstanceÚintÚ    TypeErrorÚ
ValueErrorÚMemoryChannelStateÚMemorySendChannelÚ_createÚMemoryReceiveChannel)Úmax_buffer_sizeÚstate©rúDd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\trio/_channel.pyÚopen_memory_channels5þrT)ÚfrozenÚslotsc@s<eZdZe ¡Ze ¡Ze ¡Ze ¡Ze ¡Z    e ¡Z
dS)ÚMemoryChannelStatsN) Ú__name__Ú
__module__Ú __qualname__ÚattrÚibÚcurrent_buffer_usedrÚopen_send_channelsÚopen_receive_channelsÚtasks_waiting_sendÚtasks_waiting_receiverrrrrNs r)rc@sXeZdZe ¡ZejedZejddZejddZ    eje
dZ eje
dZ dd„Z dS)r©Úfactoryr©ÚdefaultcCs,tt|jƒ|j|j|jt|jƒt|jƒdS)N)r#rr$r%r&r')rÚlenÚdatarr$r%Ú
send_tasksÚ receive_tasks©ÚselfrrrÚ
statisticsdsúzMemoryChannelState.statisticsN)rrr r!r"rrr-r$r%rr.r/r2rrrrrXs     rF)ÚeqÚreprc@seZdZe ¡ZejddZejedZdd„Z    dd„Z
dd    „Z e d
d „ƒZ e d d „ƒZe dd„ƒZdd„Zdd„Ze dd„ƒZe dd„ƒZdS)rFr*r(cCs|jjd7_dS©Nr)Ú_stater$r0rrrÚ__attrs_post_init__xsz%MemorySendChannel.__attrs_post_init__cCsd t|ƒt|jƒ¡S)Nz.<send channel at {:#x}, using buffer at {:#x}>©ÚformatÚidr6r0rrrÚ__repr__{sÿzMemorySendChannel.__repr__cCs
|j ¡S©N©r6r2r0rrrr2€szMemorySendChannel.statisticscCs–|jr tj‚|jjdkrtj‚|jjrh|jjr2t‚|jjj    dd\}}|j
j   |¡tj  |t|ƒ¡n*t|jjƒ|jjkrŒ|jj |¡ntj‚dS)z‚Like `~trio.abc.SendChannel.send`, but if the channel's buffer is
        full, raises `WouldBlock` instead of blocking.
 
        rF©ÚlastN)Ú_closedÚtrioÚClosedResourceErrorr6r%ÚBrokenResourceErrorr/r-ÚAssertionErrorÚpopitemÚcustom_sleep_dataÚ_tasksÚremoveÚlowlevelÚ
reschedulerr,rÚappendÚ
WouldBlock)r1ÚvalueÚtaskÚ_rrrÚ send_nowait„s  zMemorySendChannel.send_nowaitcƒs–tj ¡IdHzˆ |¡Wntjk
r4YnXtj ¡IdHdStj ¡‰ˆj ˆ¡|ˆj    j
ˆ<ˆˆ_ ‡‡fdd„}tj  |¡IdHdS)zŒSee `SendChannel.send <trio.abc.SendChannel.send>`.
 
        Memory channels allow multiple tasks to call `send` at the same time.
 
        Ncs ˆj ˆ¡ˆjjˆ=tjjjSr<)rGrHr6r.rArIÚAbortÚ    SUCCEEDED©rO©r1rNrrÚabort_fn­s 
z(MemorySendChannel.send.<locals>.abort_fn) rArIÚcheckpoint_if_cancelledrPrLÚcancel_shielded_checkpointÚ current_taskrGÚaddr6r.rFÚwait_task_rescheduled©r1rMrUrrTrÚsend˜s
  zMemorySendChannel.sendcCs|jr tj‚t |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@rArBrrr6r0rrrÚclone´szMemorySendChannel.clonecCs|Sr<rr0rrrÚ    __enter__ÑszMemorySendChannel.__enter__cCs | ¡dSr<©Úclose©r1Úexc_typeÚexc_valÚexc_tbrrrÚ__exit__ÔszMemorySendChannel.__exit__cCs°|jr
dSd|_|jD]$}tj |tt ¡ƒ¡|jj|=q|j     ¡|jj
d8_
|jj
dkr¬|jjrnt ‚|jj D](}|j j |¡tj |tt ¡ƒ¡qv|jj      ¡dS)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.
 
        NTrr)r@rGrArIrJrrBr6r.Úclearr$rDr/rFrHÚ EndOfChannelrTrrrr`×s 
 
   zMemorySendChannel.closecÃs| ¡tj ¡IdHdSr<©r`rArIÚ
checkpointr0rrrÚacloseószMemorySendChannel.acloseN)rrr r!r"r6r@ÚsetrGr7r;r2r rPr\r]r^rer`rjrrrrros$  
 
 
 
r)Ú    metaclassc@seZdZe ¡ZejddZejedZdd„Z    dd„Z
dd    „Z e d
d „ƒZ e d d „ƒZe dd„ƒZdd„Zdd„Ze dd„ƒZe dd„ƒZdS)rFr*r(cCs|jjd7_dSr5)r6r%r0rrrr7ÿsz(MemoryReceiveChannel.__attrs_post_init__cCs
|j ¡Sr<r=r0rrrr2szMemoryReceiveChannel.statisticscCsd t|ƒt|jƒ¡S)Nz1<receive channel at {:#x}, using buffer at {:#x}>r8r0rrrr;sÿzMemoryReceiveChannel.__repr__cCs||jr tj‚|jjrP|jjjdd\}}|jj |¡tj     
|¡|jj   |¡|jj rd|jj   ¡S|jjsrtj‚tj‚dS)zŒLike `~trio.abc.ReceiveChannel.receive`, but if there's nothing
        ready to receive, raises `WouldBlock` instead of blocking.
 
        Fr>N)r@rArBr6r.rErFrGrHrIrJr-rKÚpopleftr$rgrL)r1rNrMrrrÚreceive_nowait
s  z#MemoryReceiveChannel.receive_nowaitcƒstj ¡IdHz ˆ ¡}Wntjk
r2YnXtj ¡IdH|Stj ¡‰ˆj ˆ¡dˆj    j
ˆ<ˆˆ_ ‡‡fdd„}tj  |¡IdHS)aSee `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.
 
        Ncs ˆj ˆ¡ˆjjˆ=tjjjSr<)rGrHr6r/rArIrQrRrSrTrrrU5s 
z.MemoryReceiveChannel.receive.<locals>.abort_fn) rArIrVrnrLrWrXrGrYr6r/rFrZr[rrTrÚreceives     
  zMemoryReceiveChannel.receivecCs|jr tj‚t |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@rArBrrr6r0rrrr]<szMemoryReceiveChannel.clonecCs|Sr<rr0rrrr^\szMemoryReceiveChannel.__enter__cCs | ¡dSr<r_rarrrre_szMemoryReceiveChannel.__exit__cCs¼|jr
dSd|_|jD]$}tj |tt ¡ƒ¡|jj|=q|j     ¡|jj
d8_
|jj
dkr¸|jjrnt ‚|jj D](}|j j |¡tj |tt ¡ƒ¡qv|jj      ¡|jj     ¡dS)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.
 
        NTrr)r@rGrArIrJrrBr6r/rfr%rDr.rFrHrCr-rTrrrr`bs 
 
    zMemoryReceiveChannel.closecÃs| ¡tj ¡IdHdSr<rhr0rrrrjszMemoryReceiveChannel.acloseN)rrr r!r"r6r@rkrGr7r2r;r rnror]r^rer`rjrrrrrùs$  
 
 
 
r)Ú collectionsrrÚmathrr!ZoutcomerrÚabcrr    r
Z_utilr r rAZ_corer rÚsrrrrrrrrÚ<module>s$  
?