From 9c721ddd3b96a73a8352287c1e239d27484606bf Mon Sep 17 00:00:00 2001 From: David Kasakaitis Date: Thu, 17 Apr 2025 18:28:40 +0100 Subject: [PATCH 1/2] ref(signal): use `DOMNode` type instead of `MessagePump` for subscribing When publishing the signal requires a `_pruning` attribute in order to check if the node is not currently getting removed. The attribute is implemented in `DOMNode` and not `MessagePump`. --- src/textual/signal.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/textual/signal.py b/src/textual/signal.py index cc1be10b52..197c211b5e 100644 --- a/src/textual/signal.py +++ b/src/textual/signal.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from textual.dom import DOMNode - from textual.message_pump import MessagePump + SignalT = TypeVar("SignalT") SignalCallbackType = Union[ @@ -43,9 +43,9 @@ def __init__(self, owner: DOMNode, name: str) -> None: """ self._owner = ref(owner) self._name = name - self._subscriptions: WeakKeyDictionary[ - MessagePump, list[SignalCallbackType] - ] = WeakKeyDictionary() + self._subscriptions: WeakKeyDictionary[DOMNode, list[SignalCallbackType]] = ( + WeakKeyDictionary() + ) def __rich_repr__(self) -> rich.repr.Result: yield "owner", self.owner @@ -59,7 +59,7 @@ def owner(self) -> DOMNode | None: def subscribe( self, - node: MessagePump, + node: DOMNode, callback: SignalCallbackType, immediate: bool = False, ) -> None: @@ -97,7 +97,7 @@ def signal_callback(data: object) -> None: callbacks = self._subscriptions.setdefault(node, []) callbacks.append(signal_callback) - def unsubscribe(self, node: MessagePump) -> None: + def unsubscribe(self, node: DOMNode) -> None: """Unsubscribe a node from this signal. Args: From eb065e09d53485afbc72aa57fc71431870c914d0 Mon Sep 17 00:00:00 2001 From: David Kasakaitis Date: Thu, 17 Apr 2025 18:30:30 +0100 Subject: [PATCH 2/2] ref(signal): use class generic for `SignalCallbackType` Applies generics to the `SignalCallbackType`. Primarily to indicate what type is required, when subscribing. --- src/textual/signal.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/textual/signal.py b/src/textual/signal.py index 197c211b5e..daa7b28108 100644 --- a/src/textual/signal.py +++ b/src/textual/signal.py @@ -43,9 +43,9 @@ def __init__(self, owner: DOMNode, name: str) -> None: """ self._owner = ref(owner) self._name = name - self._subscriptions: WeakKeyDictionary[DOMNode, list[SignalCallbackType]] = ( - WeakKeyDictionary() - ) + self._subscriptions: WeakKeyDictionary[ + DOMNode, list[SignalCallbackType[SignalT]] + ] = WeakKeyDictionary() def __rich_repr__(self) -> rich.repr.Result: yield "owner", self.owner @@ -60,7 +60,7 @@ def owner(self) -> DOMNode | None: def subscribe( self, node: DOMNode, - callback: SignalCallbackType, + callback: SignalCallbackType[SignalT], immediate: bool = False, ) -> None: """Subscribe a node to this signal. @@ -84,13 +84,13 @@ def subscribe( if immediate: - def signal_callback(data: object) -> None: + def signal_callback(data: SignalT) -> None: """Invoke the callback immediately.""" callback(data) else: - def signal_callback(data: object) -> None: + def signal_callback(data: SignalT) -> None: """Post the callback to the node, to call at the next opertunity.""" node.call_next(callback, data)