Skip to content

Commit ad2d285

Browse files
mikaelarguedasjacobperron
authored andcommitted
store types as tuple of abstract types (ros2/rosidl_python#33)
* store types as constant and return ordered dict Signed-off-by: Mikael Arguedas <[email protected]> update tests Signed-off-by: Mikael Arguedas <[email protected]> simplify logic by printing member type directly Signed-off-by: Mikael Arguedas <[email protected]> move dict construction to rosidl_runtime_py Signed-off-by: Mikael Arguedas <[email protected]> add utility to import complex message and add support for nested array in set_message Signed-off-by: Mikael Arguedas <[email protected]> update tests and remove coverage for dict to avoid circular dependency Signed-off-by: Mikael Arguedas <[email protected]> more descriptive variable name Signed-off-by: Mikael Arguedas <[email protected]> refactor import logic according to ros2/rosidl_python#35 Signed-off-by: Mikael Arguedas <[email protected]> move imports to top of file Signed-off-by: Mikael Arguedas <[email protected]> string maximum size doesn't need quoting or str conversion Signed-off-by: Mikael Arguedas <[email protected]> update docblock Signed-off-by: Mikael Arguedas <[email protected]> slot_types_dict_from_message -> get_message_slot_types Signed-off-by: Mikael Arguedas <[email protected]> check Abstrct type instead of 'list' Signed-off-by: Mikael Arguedas <[email protected]> use NestedType Signed-off-by: Mikael Arguedas <[email protected]> add conditional is namespaces is an empty list Signed-off-by: Mikael Arguedas <[email protected]> one liner Signed-off-by: Mikael Arguedas <[email protected]> extend test suite to cover NesteTypes of NamespacedTypes Signed-off-by: Mikael Arguedas <[email protected]> single message fixture to use Signed-off-by: Mikael Arguedas <[email protected]> use NestedType Signed-off-by: Mikael Arguedas <[email protected]> add coverage for static array of nested messages Signed-off-by: Mikael Arguedas <[email protected]> restore old API Signed-off-by: Mikael Arguedas <[email protected]> SLOT_TYPES improvement from dirk-thomas Signed-off-by: Mikael Arguedas <[email protected]> resolve conflicts Signed-off-by: Mikael Arguedas <[email protected]> * add back I100 ignore Signed-off-by: Mikael Arguedas <[email protected]> * use new rosidl_parser.definition types and new test interfaces Signed-off-by: Mikael Arguedas <[email protected]> * restore original test, add test for SLOT_TYPES Signed-off-by: Mikael Arguedas <[email protected]>
1 parent 564fef9 commit ad2d285

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
<exec_depend>python3-numpy</exec_depend>
1313
<exec_depend>python3-yaml</exec_depend>
14+
<exec_depend>rosidl_parser</exec_depend>
1415

1516
<test_depend>ament_copyright</test_depend>
1617
<test_depend>ament_flake8</test_depend>

rosidl_runtime_py/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from .convert import get_message_slot_types
1516
from .convert import message_to_csv
1617
from .convert import message_to_ordereddict
1718
from .convert import message_to_yaml
19+
from .import_message import import_message_from_namespaced_type
1820
from .set_message import set_message_fields
1921

2022

2123
__all__ = [
24+
'get_message_slot_types',
25+
'import_message_from_namespaced_type',
2226
'message_to_csv',
2327
'message_to_ordereddict',
2428
'message_to_yaml',

rosidl_runtime_py/convert.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,13 @@ def _convert_value(value, truncate_length=None):
154154
# Assuming value is a message since it is neither a collection nor a primitive type
155155
value = message_to_ordereddict(value, truncate_length=truncate_length)
156156
return value
157+
158+
159+
def get_message_slot_types(msg: Any) -> OrderedDict:
160+
"""
161+
Return an OrderedDict of the slot types of a message.
162+
163+
:param msg: The ROS message to get members types from.
164+
:returns: An OrderedDict with message member names as keys and slot types as values.
165+
"""
166+
return OrderedDict(zip([s[1:] for s in msg.__slots__], msg.SLOT_TYPES))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2019 Mikael Arguedas.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import importlib
16+
from typing import Any
17+
18+
from rosidl_parser.definition import NamespacedType
19+
20+
21+
def import_message_from_namespaced_type(message_type: NamespacedType) -> Any:
22+
module = importlib.import_module(
23+
'.'.join(message_type.value_type.namespaces))
24+
return getattr(module, message_type.value_type.name)

rosidl_runtime_py/set_message.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
from typing import Any
1616
from typing import Dict
1717

18+
from rosidl_parser.definition import AbstractNestedType
19+
from rosidl_parser.definition import NamespacedType
20+
from rosidl_runtime_py.convert import get_message_slot_types
21+
from rosidl_runtime_py.import_message import import_message_from_namespaced_type
22+
1823

1924
def set_message_fields(msg: Any, values: Dict[str, str]) -> None:
2025
"""
@@ -33,4 +38,13 @@ def set_message_fields(msg: Any, values: Dict[str, str]) -> None:
3338
except TypeError:
3439
value = field_type()
3540
set_message_fields(value, field_value)
41+
rosidl_type = get_message_slot_types(msg)[field_name]
42+
# Check if field is an array of ROS messages
43+
if isinstance(rosidl_type, AbstractNestedType):
44+
if isinstance(rosidl_type.value_type, NamespacedType):
45+
field_elem_type = import_message_from_namespaced_type(rosidl_type)
46+
for n in range(len(value)):
47+
submsg = field_elem_type()
48+
set_message_fields(submsg, value[n])
49+
value[n] = submsg
3650
setattr(msg, field_name, value)

test/rosidl_runtime_py/test_set_message.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,39 @@ def test_set_message_fields_invalid():
9191
invalid_type['int32_value'] = 'this is not an integer'
9292
with pytest.raises(ValueError):
9393
set_message_fields(msg, invalid_type)
94+
95+
96+
def test_set_nested_namespaced_fields():
97+
unbounded_sequence_msg = message_fixtures.get_msg_unbounded_sequences()[1]
98+
test_values = {
99+
'basic_types_values': [
100+
{'float64_value': 42.42, 'int8_value': 42},
101+
{'float64_value': 11.11, 'int8_value': 11}
102+
]
103+
}
104+
set_message_fields(unbounded_sequence_msg, test_values)
105+
assert unbounded_sequence_msg.basic_types_values[0].float64_value == 42.42
106+
assert unbounded_sequence_msg.basic_types_values[0].int8_value == 42
107+
assert unbounded_sequence_msg.basic_types_values[0].uint8_value == 0
108+
assert unbounded_sequence_msg.basic_types_values[1].float64_value == 11.11
109+
assert unbounded_sequence_msg.basic_types_values[1].int8_value == 11
110+
assert unbounded_sequence_msg.basic_types_values[1].uint8_value == 0
111+
112+
arrays_msg = message_fixtures.get_msg_arrays()[0]
113+
test_values = {
114+
'basic_types_values': [
115+
{'float64_value': 42.42, 'int8_value': 42},
116+
{'float64_value': 11.11, 'int8_value': 11},
117+
{'float64_value': 22.22, 'int8_value': 22},
118+
]
119+
}
120+
set_message_fields(arrays_msg, test_values)
121+
assert arrays_msg.basic_types_values[0].float64_value == 42.42
122+
assert arrays_msg.basic_types_values[0].int8_value == 42
123+
assert arrays_msg.basic_types_values[0].uint8_value == 0
124+
assert arrays_msg.basic_types_values[1].float64_value == 11.11
125+
assert arrays_msg.basic_types_values[1].int8_value == 11
126+
assert arrays_msg.basic_types_values[1].uint8_value == 0
127+
assert arrays_msg.basic_types_values[2].float64_value == 22.22
128+
assert arrays_msg.basic_types_values[2].int8_value == 22
129+
assert arrays_msg.basic_types_values[2].uint8_value == 0

0 commit comments

Comments
 (0)