77
88from asyncio import Condition
99from collections import deque
10- from typing import Deque , Generic , Optional
10+ from typing import Deque , Generic , Type
1111
1212from ._base_classes import Receiver as BaseReceiver
1313from ._base_classes import Sender as BaseSender
@@ -151,6 +151,10 @@ async def send(self, msg: T) -> None:
151151 self ._chan .recv_cv .notify (1 )
152152
153153
154+ class _Empty :
155+ """A sentinel value to indicate that a value has not been set."""
156+
157+
154158class Receiver (BaseReceiver [T ]):
155159 """A receiver to receive messages from an Anycast channel.
156160
@@ -165,7 +169,7 @@ def __init__(self, chan: Anycast[T]) -> None:
165169 chan: A reference to the channel that this receiver belongs to.
166170 """
167171 self ._chan = chan
168- self ._next : Optional [ T ] = None
172+ self ._next : T | Type [ _Empty ] = _Empty
169173
170174 async def ready (self ) -> bool :
171175 """Wait until the receiver is ready with a value or an error.
@@ -179,7 +183,7 @@ async def ready(self) -> bool:
179183 Whether the receiver is still active.
180184 """
181185 # if a message is already ready, then return immediately.
182- if self ._next is not None :
186+ if self ._next is not _Empty :
183187 return True
184188
185189 while len (self ._chan .deque ) == 0 :
@@ -202,12 +206,15 @@ def consume(self) -> T:
202206 ReceiverStoppedError: if the receiver stopped producing messages.
203207 ReceiverError: if there is some problem with the receiver.
204208 """
205- if self ._next is None and self ._chan .closed :
209+ if self ._next is _Empty and self ._chan .closed :
206210 raise ReceiverStoppedError (self ) from ChannelClosedError (self ._chan )
207211
208212 assert (
209- self ._next is not None
213+ self ._next is not _Empty
210214 ), "`consume()` must be preceeded by a call to `ready()`"
211- next_val = self ._next
212- self ._next = None
215+ # mypy doesn't understand that the assert above ensures that self._next is not
216+ # _Sentinel. So we have to use a type ignore here.
217+ next_val : T = self ._next # type: ignore[assignment]
218+ self ._next = _Empty
219+
213220 return next_val
0 commit comments