157157from collections .abc import Callable
158158from typing import TYPE_CHECKING , Any , Generic , Self , TypeGuard , TypeVar , overload
159159
160+ from typing_extensions import override
161+
160162from ._exceptions import Error
161163from ._generic import MappedMessageT_co , ReceiverMessageT_co
162164
@@ -215,6 +217,15 @@ def consume(self) -> ReceiverMessageT_co:
215217 ReceiverError: If there is some problem with the receiver.
216218 """
217219
220+ def close (self ) -> None :
221+ """Close the receiver.
222+
223+ After calling this method, new messages will not be available from the receiver.
224+ Once the receiver's buffer is drained, trying to receive a message will raise a
225+ [`ReceiverStoppedError`][frequenz.channels.ReceiverStoppedError].
226+ """
227+ raise NotImplementedError ("close() must be implemented by subclasses" )
228+
218229 def __aiter__ (self ) -> Self :
219230 """Get an async iterator over the received messages.
220231
@@ -433,6 +444,7 @@ def __init__(
433444 )
434445 """The function to apply on the input data."""
435446
447+ @override
436448 async def ready (self ) -> bool :
437449 """Wait until the receiver is ready with a message or an error.
438450
@@ -448,6 +460,7 @@ async def ready(self) -> bool:
448460
449461 # We need a noqa here because the docs have a Raises section but the code doesn't
450462 # explicitly raise anything.
463+ @override
451464 def consume (self ) -> MappedMessageT_co : # noqa: DOC502
452465 """Return a transformed message once `ready()` is complete.
453466
@@ -460,6 +473,16 @@ def consume(self) -> MappedMessageT_co: # noqa: DOC502
460473 """
461474 return self ._mapping_function (self ._receiver .consume ())
462475
476+ @override
477+ def close (self ) -> None :
478+ """Close the receiver.
479+
480+ After calling this method, new messages will not be received. Once the
481+ receiver's buffer is drained, trying to receive a message will raise a
482+ [`ReceiverStoppedError`][frequenz.channels.ReceiverStoppedError].
483+ """
484+ self ._receiver .close ()
485+
463486 def __str__ (self ) -> str :
464487 """Return a string representation of the mapper."""
465488 return f"{ type (self ).__name__ } :{ self ._receiver } :{ self ._mapping_function } "
@@ -509,6 +532,7 @@ def __init__(
509532
510533 self ._recv_closed = False
511534
535+ @override
512536 async def ready (self ) -> bool :
513537 """Wait until the receiver is ready with a message or an error.
514538
@@ -528,6 +552,7 @@ async def ready(self) -> bool:
528552 self ._recv_closed = True
529553 return False
530554
555+ @override
531556 def consume (self ) -> ReceiverMessageT_co :
532557 """Return a transformed message once `ready()` is complete.
533558
@@ -547,6 +572,16 @@ def consume(self) -> ReceiverMessageT_co:
547572 self ._next_message = _SENTINEL
548573 return message
549574
575+ @override
576+ def close (self ) -> None :
577+ """Close the receiver.
578+
579+ After calling this method, new messages will not be received. Once the
580+ receiver's buffer is drained, trying to receive a message will raise a
581+ [`ReceiverStoppedError`][frequenz.channels.ReceiverStoppedError].
582+ """
583+ self ._receiver .close ()
584+
550585 def __str__ (self ) -> str :
551586 """Return a string representation of the filter."""
552587 return f"{ type (self ).__name__ } :{ self ._receiver } :{ self ._filter_function } "
0 commit comments