|
155 | 155 |
|
156 | 156 | from abc import ABC, abstractmethod |
157 | 157 | from collections.abc import Callable |
158 | | -from typing import TYPE_CHECKING, Any, Generic, Self, TypeGuard |
| 158 | +from typing import TYPE_CHECKING, Any, Generic, Self, TypeGuard, TypeVar, overload |
159 | 159 |
|
160 | 160 | from ._exceptions import Error |
161 | 161 | from ._generic import MappedMessageT_co, ReceiverMessageT_co |
162 | 162 |
|
163 | 163 | if TYPE_CHECKING: |
164 | 164 | from ._select import Selected |
165 | 165 |
|
| 166 | +FilteredMessageT_co = TypeVar("FilteredMessageT_co", covariant=True) |
| 167 | +"""Type variable for the filtered message type.""" |
| 168 | + |
166 | 169 |
|
167 | 170 | class Receiver(ABC, Generic[ReceiverMessageT_co]): |
168 | 171 | """An endpoint to receive messages.""" |
@@ -267,11 +270,66 @@ def map( |
267 | 270 | """ |
268 | 271 | return _Mapper(receiver=self, mapping_function=mapping_function) |
269 | 272 |
|
| 273 | + @overload |
| 274 | + def filter( |
| 275 | + self, |
| 276 | + filter_function: Callable[ |
| 277 | + [ReceiverMessageT_co], TypeGuard[FilteredMessageT_co] |
| 278 | + ], |
| 279 | + /, |
| 280 | + ) -> Receiver[FilteredMessageT_co]: |
| 281 | + """Apply a type guard on the messages on a receiver. |
| 282 | +
|
| 283 | + Tip: |
| 284 | + The returned receiver type won't have all the methods of the original |
| 285 | + receiver. If you need to access methods of the original receiver that are |
| 286 | + not part of the `Receiver` interface you should save a reference to the |
| 287 | + original receiver and use that instead. |
| 288 | +
|
| 289 | + Args: |
| 290 | + filter_function: The function to be applied on incoming messages to |
| 291 | + determine if they should be received. |
| 292 | +
|
| 293 | + Returns: |
| 294 | + A new receiver that only receives messages that pass the filter. |
| 295 | + """ |
| 296 | + ... # pylint: disable=unnecessary-ellipsis |
| 297 | + |
| 298 | + @overload |
270 | 299 | def filter( |
271 | 300 | self, filter_function: Callable[[ReceiverMessageT_co], bool], / |
272 | 301 | ) -> Receiver[ReceiverMessageT_co]: |
273 | 302 | """Apply a filter function on the messages on a receiver. |
274 | 303 |
|
| 304 | + Tip: |
| 305 | + The returned receiver type won't have all the methods of the original |
| 306 | + receiver. If you need to access methods of the original receiver that are |
| 307 | + not part of the `Receiver` interface you should save a reference to the |
| 308 | + original receiver and use that instead. |
| 309 | +
|
| 310 | + Args: |
| 311 | + filter_function: The function to be applied on incoming messages to |
| 312 | + determine if they should be received. |
| 313 | +
|
| 314 | + Returns: |
| 315 | + A new receiver that only receives messages that pass the filter. |
| 316 | + """ |
| 317 | + ... # pylint: disable=unnecessary-ellipsis |
| 318 | + |
| 319 | + def filter( |
| 320 | + self, |
| 321 | + filter_function: ( |
| 322 | + Callable[[ReceiverMessageT_co], bool] |
| 323 | + | Callable[[ReceiverMessageT_co], TypeGuard[FilteredMessageT_co]] |
| 324 | + ), |
| 325 | + /, |
| 326 | + ) -> Receiver[ReceiverMessageT_co] | Receiver[FilteredMessageT_co]: |
| 327 | + """Apply a filter function on the messages on a receiver. |
| 328 | +
|
| 329 | + Note: |
| 330 | + You can pass a [type guard][typing.TypeGuard] as the filter function to |
| 331 | + narrow the type of the messages that pass the filter. |
| 332 | +
|
275 | 333 | Tip: |
276 | 334 | The returned receiver type won't have all the methods of the original |
277 | 335 | receiver. If you need to access methods of the original receiver that are |
|
0 commit comments