|
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