|
45 | 45 | from ros2topic.api import get_msg_class |
46 | 46 | from ros2topic.api import positive_int |
47 | 47 | from ros2topic.api import TopicNameCompleter |
48 | | -from ros2topic.eval import base_eval_model, Expr |
49 | 48 | from ros2topic.verb import VerbExtension |
50 | 49 |
|
51 | 50 | DEFAULT_WINDOW_SIZE = 10000 |
@@ -87,70 +86,20 @@ def main(self, *, args): |
87 | 86 | return main(args) |
88 | 87 |
|
89 | 88 |
|
90 | | -def _get_nested_messages(msg_class): |
91 | | - all_attributes = list(msg_class.__slots__) |
92 | | - for attr in msg_class.__slots__: |
93 | | - value = getattr(msg_class, attr) |
94 | | - if hasattr(value, '__slots__'): |
95 | | - nested_messages = _get_nested_messages(value) |
96 | | - all_attributes.extend(nested_messages) |
97 | | - return all_attributes |
98 | | - |
99 | | -def _setup_base_safe_eval(): |
100 | | - safe_eval_model = base_eval_model.clone() |
101 | | - |
102 | | - # extend base_eval_model |
103 | | - safe_eval_model.nodes.extend(['Call', 'Attribute', 'List', 'Tuple', 'Dict', 'Set', |
104 | | - 'ListComp', 'DictComp', 'SetComp', 'comprehension', |
105 | | - 'Mult', 'Pow', 'boolop', 'mod', 'Invert', |
106 | | - 'Is', 'IsNot', 'FloorDiv', 'If', 'For']) |
107 | | - |
108 | | - # allow-list safe Python built-in functions |
109 | | - safe_builtins = [ |
110 | | - 'abs', 'all', 'any', 'bin', 'bool', 'chr', 'cmp', 'divmod', 'enumerate', |
111 | | - 'float', 'format', 'hex', 'id', 'int', 'isinstance', 'issubclass', |
112 | | - 'len', 'list', 'long', 'max', 'min', 'ord', 'pow', 'range', 'reversed', |
113 | | - 'round', 'slice', 'sorted', 'str', 'sum', 'tuple', 'type', 'unichr', |
114 | | - 'unicode', 'xrange', 'zip', 'filter', 'dict', 'set', 'next' |
115 | | - ] |
116 | | - |
117 | | - safe_eval_model.allowed_functions.extend(safe_builtins) |
118 | | - return safe_eval_model |
119 | | - |
120 | | -def _setup_safe_eval(safe_eval_model, msg_class, topic): |
121 | | - # allow-list topic builtins, msg attributes |
122 | | - topic_builtins = [i for i in dir(topic) if not i.startswith('_')] |
123 | | - safe_eval_model.attributes.extend(topic_builtins) |
124 | | - # recursively get all nested message attributes |
125 | | - msg_attributes = _get_nested_messages(msg_class) |
126 | | - safe_eval_model.attributes.extend(msg_attributes) |
127 | | - return safe_eval_model |
128 | | - |
129 | | - |
130 | 89 | def main(args): |
131 | | - with DirectNode(args) as node: |
132 | | - topics = args.topic_name |
| 90 | + topic = args.topic_name |
| 91 | + if args.filter_expr: |
| 92 | + def expr_eval(expr): |
| 93 | + def eval_fn(m): |
| 94 | + return eval(expr) |
| 95 | + return eval_fn |
| 96 | + filter_expr = expr_eval(args.filter_expr) |
| 97 | + else: |
133 | 98 | filter_expr = None |
134 | | - # set up custom safe eval model for filter expression |
135 | | - if args.filter_expr: |
136 | | - safe_eval_model = _setup_base_safe_eval() |
137 | | - for topic in topics: |
138 | | - msg_class = get_msg_class( |
139 | | - node, topic, blocking=True, include_hidden_topics=True) |
140 | | - if msg_class is None: |
141 | | - continue |
142 | | - |
143 | | - safe_eval_model = _setup_safe_eval(safe_eval_model, msg_class, topic) |
144 | | - |
145 | | - def expr_eval(expr): |
146 | | - def eval_fn(m): |
147 | | - safe_expression = Expr(expr, model=safe_eval_model) |
148 | | - return eval(safe_expression.code) |
149 | | - return eval_fn |
150 | | - filter_expr = expr_eval(args.filter_expr) |
151 | | - |
152 | | - _rostopic_hz(node.node, topics, qos_args=args, window_size=args.window_size, |
153 | | - filter_expr=filter_expr, use_wtime=args.use_wtime) |
| 99 | + |
| 100 | + with DirectNode(args) as node: |
| 101 | + _rostopic_hz(node.node, topic, window_size=args.window_size, filter_expr=filter_expr, |
| 102 | + use_wtime=args.use_wtime) |
154 | 103 |
|
155 | 104 |
|
156 | 105 | class ROSTopicHz(object): |
|
0 commit comments