19 from pubsub
import pub
20 from typing
import Type, Callable
21 from ..publish.messages
import RideMessage
32 if inspect.isclass(topic_cls)
and issubclass(topic_cls, RideMessage):
33 return topic_cls.topic()
34 raise TypeError(
'Expected topic type {}, actual {}.'.format(RideMessage, topic_cls))
38 sig = inspect.signature(listener)
39 params = sig.parameters
40 error_msg =
'only 1 required param (message) is expected.'
41 assert len(params) == 1,
'Too many listener params, ' + error_msg
42 assert str(list(params.values())[0])
in [
'message',
'data'],
'Invalid listener param, ' + error_msg
45 def subscribe(self, listener: Callable, topic: Type[RideMessage]):
50 def publish(self, topic: Type[RideMessage], message):
53 def unsubscribe(self, listener: Callable, topic: Type[RideMessage]):
68 def _listener_filter(listener):
72 _callable = listener.getCallable()
75 if _callable
in functions
or _callable
in methods:
81 _listener_filter = _listener_filter
if obj
is not None else None
82 self.
_publisher_publisher.unsubAll(listenerFilter=_listener_filter)
87 def __call__(self, listenerID: str, topicObj: pub.Topic):
88 from .messages
import RideLogException
89 topic_name = topicObj.getName()
90 if topic_name != RideLogException.topic():
91 error_msg =
'Error in listener: {}, topic: {}'.format(listenerID, topic_name)
93 exception=
None, level=
'ERROR')
94 sys.stderr.write(log_message.__getattribute__(
'message'))
108 if inspect.isclass(obj):
109 mro = (obj,) + inspect.getmro(obj)
119 for base
in obj.__bases__:
120 for k, v
in base.__dict__.items():
121 if isinstance(v, types.DynamicClassAttribute):
123 except AttributeError:
130 value = getattr(obj, key)
134 except Exception
as e:
135 """ UPDATED HERE: Catch all types of exceptions. """
136 if isinstance(e, AttributeError):
137 """ UPDATED HERE: Use old logic if exception is AttributeError. """
139 if key
in base.__dict__:
140 value = base.__dict__[key]
147 """ UPDATED HERE: Ignore this attribute when other types of exception raised. """
149 if not predicate
or predicate(value):
150 results.append((key, value))
152 results.sort(key=
lambda pair: pair[0])
156 """Global `Publisher` instance for subscribing to and unsubscribing from RideMessages."""
This class represents a general purpose log message with a traceback appended to message text.
def __call__(self, str listenerID, pub.Topic topicObj)
str _get_topic(Type[RideMessage] topic_cls)
def subscribe(self, Callable listener, Type[RideMessage] topic)
The listener's param signature must be (message)
def publish(self, Type[RideMessage] topic, message)
All subscribed listeners' param signatures have been guaranteed.
def unsubscribe(self, Callable listener, Type[RideMessage] topic)
def unsubscribe_all(self, obj=None)
If the given object's:
def _validate_listener(Callable listener)
def _get_members_safely(obj, predicate=None)
Return all members of an object as (name, value) pairs sorted by name.