From 9483332ccb66e050954516f889ecc9225a83280c Mon Sep 17 00:00:00 2001 From: Russ Webber Date: Sat, 2 Nov 2024 15:59:15 +1100 Subject: [PATCH 1/3] fix(set_message): encode strings if field is bytes Signed-off-by: Russ Webber --- rosidl_runtime_py/set_message.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rosidl_runtime_py/set_message.py b/rosidl_runtime_py/set_message.py index 5e7921e..26819bc 100644 --- a/rosidl_runtime_py/set_message.py +++ b/rosidl_runtime_py/set_message.py @@ -28,7 +28,7 @@ def set_message_fields( - msg: Any, values: Dict[str, str], expand_header_auto: bool = False, + msg: Any, values: Dict[str, Any], expand_header_auto: bool = False, expand_time_now: bool = False) -> List[Any]: """ Set the fields of a ROS message. @@ -52,7 +52,7 @@ def set_message_fields( timestamp_fields = [] def set_message_fields_internal( - msg: Any, values: Dict[str, str], + msg: Any, values: Dict[str, Any], timestamp_fields: List[Any]) -> List[Any]: try: items = values.items() @@ -70,6 +70,8 @@ def set_message_fields_internal( value = numpy.array(field_value, dtype=field.dtype) elif type(field_value) is field_type: value = field_value + elif field_type is bytes and type(field_value) is str: + value = field_value.encode() # We can't import these types directly, so we use the qualified class name to # distinguish them from other fields elif qualified_class_name == 'std_msgs.msg._header.Header' and \ From ad5a8b200466a011acdd4d2f70ef5cd174f0481b Mon Sep 17 00:00:00 2001 From: Russ Webber Date: Sun, 3 Nov 2024 16:15:36 +1100 Subject: [PATCH 2/3] chore: add test Signed-off-by: Russ Webber --- test/rosidl_runtime_py/test_set_message.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/rosidl_runtime_py/test_set_message.py b/test/rosidl_runtime_py/test_set_message.py index 9c39f09..093285e 100644 --- a/test/rosidl_runtime_py/test_set_message.py +++ b/test/rosidl_runtime_py/test_set_message.py @@ -14,11 +14,12 @@ import builtins import copy +import yaml from builtin_interfaces.msg import Time import pytest import rosidl_parser.definition -from rosidl_runtime_py import set_message_fields +from rosidl_runtime_py import set_message_fields, message_to_yaml from std_msgs.msg import Header from test_msgs import message_fixtures @@ -140,6 +141,18 @@ def test_set_message_fields_partial(): assert getattr(modified_msg, attr) == getattr(original_msg, attr) +def test_set_message_fields_from_yaml(): + original_msg = message_fixtures.get_msg_basic_types()[1] + original_yaml = message_to_yaml(original_msg) + values = yaml.safe_load(original_yaml) + + modified_msg = copy.copy(message_fixtures.get_msg_basic_types()[0]) + set_message_fields(modified_msg, values) + + for attr in original_msg.get_fields_and_field_types().keys(): + assert getattr(modified_msg, attr) == getattr(original_msg, attr) + + def test_set_message_fields_full(): msg_list = message_fixtures.get_msg_basic_types() msg0 = msg_list[0] From 7f219e2177e76de21891713607663bbcf02bbcd5 Mon Sep 17 00:00:00 2001 From: Russ Webber Date: Sun, 3 Nov 2024 17:12:36 +1100 Subject: [PATCH 3/3] hack to get it encode high value bytes --- rosidl_runtime_py/set_message.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rosidl_runtime_py/set_message.py b/rosidl_runtime_py/set_message.py index 26819bc..aa62074 100644 --- a/rosidl_runtime_py/set_message.py +++ b/rosidl_runtime_py/set_message.py @@ -71,7 +71,9 @@ def set_message_fields_internal( elif type(field_value) is field_type: value = field_value elif field_type is bytes and type(field_value) is str: - value = field_value.encode() + # value = field_value.encode() + value = bytes([ord(c) for c in field_value]) + # value = bytes(field_value, 'ascii', 'backslashreplace') # We can't import these types directly, so we use the qualified class name to # distinguish them from other fields elif qualified_class_name == 'std_msgs.msg._header.Header' and \