2929# This file is originally from:
3030# https://github.com/ros/ros_comm/blob/6e5016f4b2266d8a60c9a1e163c4928b8fc7115e/tools/rostopic/src/rostopic/__init__.py
3131
32- from collections import defaultdict
3332
33+ from collections import defaultdict , OrderedDict
3434import functools
3535import math
3636import threading
5050from ros2topic .api import TopicNameCompleter
5151from ros2topic .eval import base_eval_model , Expr
5252from ros2topic .verb import VerbExtension
53+ from rosidl_runtime_py .convert import message_to_ordereddict
5354
5455DEFAULT_WINDOW_SIZE = 10000
5556
@@ -92,16 +93,6 @@ def main(self, *, args):
9293 return main (args )
9394
9495
95- def _get_nested_messages (msg_class ):
96- all_attributes = list (msg_class .__slots__ )
97- for attr in msg_class .__slots__ :
98- value = getattr (msg_class , attr )
99- if hasattr (value , '__slots__' ):
100- nested_messages = _get_nested_messages (value )
101- all_attributes .extend (nested_messages )
102- return all_attributes
103-
104-
10596def _setup_base_safe_eval ():
10697 safe_eval_model = base_eval_model .clone ()
10798
@@ -124,12 +115,27 @@ def _setup_base_safe_eval():
124115 return safe_eval_model
125116
126117
118+ def _get_nested_messages (msg_ordereddict ):
119+ """Helper function to get a list of all message field names recursively"""
120+ all_attributes = []
121+ for (k , v ) in msg_ordereddict .items ():
122+ all_attributes .append (k )
123+ if type (v ) is OrderedDict :
124+ nested_attrs = _get_nested_messages (v )
125+ all_attributes .extend (nested_attrs )
126+ return all_attributes
127+
128+
127129def _setup_safe_eval (safe_eval_model , msg_class , topic ):
128130 # allow-list topic builtins, msg attributes
129131 topic_builtins = [i for i in dir (topic ) if not i .startswith ('_' )]
130132 safe_eval_model .attributes .extend (topic_builtins )
133+
131134 # recursively get all nested message attributes
132- msg_attributes = _get_nested_messages (msg_class )
135+ # msg_class in this case is a prototype that needs to be instantiated to get
136+ # an ordered dictionary of message fields
137+ msg_ordereddict = message_to_ordereddict (msg_class ())
138+ msg_attributes = _get_nested_messages (msg_ordereddict )
133139 safe_eval_model .attributes .extend (msg_attributes )
134140 return safe_eval_model
135141
0 commit comments