1818 List ,
1919 NamedTuple ,
2020 Optional ,
21+ Tuple ,
2122 Type ,
2223 Union ,
2324)
@@ -85,25 +86,25 @@ def unregister(self, bus: BusABC, notifier: "Notifier") -> None:
8586 for pair in registered_pairs_to_remove :
8687 self .pairs .remove (pair )
8788
88- def find_instance (self , bus : BusABC ) -> Optional ["Notifier" ]:
89- """Find the :class:`~can.Notifier` instance associated with a given CAN bus.
89+ def find_instances (self , bus : BusABC ) -> Tuple ["Notifier" , ... ]:
90+ """Find the :class:`~can.Notifier` instances associated with a given CAN bus.
9091
9192 This method searches the registry for the :class:`~can.Notifier`
9293 that is linked to the specified bus. If the bus is found, the
93- corresponding :class:`~can.Notifier` instance is returned. If the bus is not
94- found in the registry, `None` is returned.
94+ corresponding :class:`~can.Notifier` instances are returned. If the bus is not
95+ found in the registry, an empty tuple is returned.
9596
9697 :param bus:
9798 The CAN bus for which to find the associated :class:`~can.Notifier` .
9899 :return:
99- The :class:`~can.Notifier` instance associated with the given bus,
100- or `None` if no such association exists.
100+ A tuple of :class:`~can.Notifier` instances associated with the given bus.
101101 """
102+ instance_list = []
102103 with self .lock :
103104 for pair in self .pairs :
104105 if bus is pair .bus :
105- return pair .notifier
106- return None
106+ instance_list . append ( pair .notifier )
107+ return tuple ( instance_list )
107108
108109
109110class Notifier (AbstractContextManager ):
@@ -128,7 +129,7 @@ def __init__(
128129
129130
130131 :param bus:
131- A :ref:`bus` or a list of buses to listen to .
132+ A :ref:`bus` or a list of buses to consume messages from .
132133 :param listeners:
133134 An iterable of :class:`~can.Listener` or callables that receive a :class:`~can.Message`
134135 and return nothing.
@@ -137,10 +138,10 @@ def __init__(
137138 :param loop:
138139 An :mod:`asyncio` event loop to schedule the ``listeners`` in.
139140 :raises ValueError:
140- If the *bus* is already assigned to an active :class:`~can.Notifier`.
141+ If a passed in *bus* is already assigned to an active :class:`~can.Notifier`.
141142 """
142143 self .listeners : List [MessageRecipient ] = list (listeners )
143- self .bus = bus
144+ self ._bus_list : List [ BusABC ] = []
144145 self .timeout = timeout
145146 self ._loop = loop
146147
@@ -151,10 +152,17 @@ def __init__(
151152 self ._lock = threading .Lock ()
152153
153154 self ._readers : List [Union [int , threading .Thread ]] = []
154- self . _bus_list = self . bus if isinstance (self . bus , list ) else [self . bus ]
155- for each_bus in self . _bus_list :
155+ _bus_list : List [ BusABC ] = bus if isinstance (bus , list ) else [bus ]
156+ for each_bus in _bus_list :
156157 self .add_bus (each_bus )
157158
159+ @property
160+ def bus (self ) -> Union [BusABC , Tuple ["BusABC" , ...]]:
161+ """Return the associated bus or a tuple of buses."""
162+ if len (self ._bus_list ) == 1 :
163+ return self ._bus_list [0 ]
164+ return tuple (self ._bus_list )
165+
158166 def add_bus (self , bus : BusABC ) -> None :
159167 """Add a bus for notification.
160168
@@ -164,7 +172,10 @@ def add_bus(self, bus: BusABC) -> None:
164172 If the *bus* is already assigned to an active :class:`~can.Notifier`.
165173 """
166174 # add bus to notifier registry
167- self ._registry .register (bus , self )
175+ Notifier ._registry .register (bus , self )
176+
177+ # add bus to internal bus list
178+ self ._bus_list .append (bus )
168179
169180 file_descriptor : int = - 1
170181 try :
@@ -181,7 +192,7 @@ def add_bus(self, bus: BusABC) -> None:
181192 reader_thread = threading .Thread (
182193 target = self ._rx_thread ,
183194 args = (bus ,),
184- name = f'can.notifier for bus "{ bus .channel_info } "' ,
195+ name = f'{ self . __class__ . __qualname__ } for bus "{ bus .channel_info } "' ,
185196 )
186197 reader_thread .daemon = True
187198 reader_thread .start ()
@@ -211,7 +222,7 @@ def stop(self, timeout: float = 5.0) -> None:
211222
212223 # remove bus from registry
213224 for bus in self ._bus_list :
214- self ._registry .unregister (bus , self )
225+ Notifier ._registry .unregister (bus , self )
215226
216227 def _rx_thread (self , bus : BusABC ) -> None :
217228 # determine message handling callable early, not inside while loop
@@ -294,22 +305,21 @@ def stopped(self) -> bool:
294305 """Return ``True``, if Notifier was properly shut down with :meth:`~can.Notifier.stop`."""
295306 return self ._stopped
296307
297- @classmethod
298- def find_instance ( cls , bus : BusABC ) -> Optional ["Notifier" ]:
299- """Find the :class:`~can.Notifier` instance associated with a given CAN bus.
308+ @staticmethod
309+ def find_instances ( bus : BusABC ) -> Tuple ["Notifier" , ... ]:
310+ """Find :class:`~can.Notifier` instances associated with a given CAN bus.
300311
301312 This method searches the registry for the :class:`~can.Notifier`
302313 that is linked to the specified bus. If the bus is found, the
303- corresponding :class:`~can.Notifier` instance is returned. If the bus is not
304- found in the registry, `None` is returned.
314+ corresponding :class:`~can.Notifier` instances are returned. If the bus is not
315+ found in the registry, an empty tuple is returned.
305316
306317 :param bus:
307318 The CAN bus for which to find the associated :class:`~can.Notifier` .
308319 :return:
309- The :class:`~can.Notifier` instance associated with the given bus,
310- or `None` if no such association exists.
320+ A tuple of :class:`~can.Notifier` instances associated with the given bus.
311321 """
312- return cls ._registry .find_instance (bus )
322+ return Notifier ._registry .find_instances (bus )
313323
314324 def __exit__ (
315325 self ,
0 commit comments