From 3247a651351285a733220dfc635be0fc8c8aff30 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Wed, 14 Sep 2022 15:39:21 +0800 Subject: [PATCH 1/5] allow byte array to use int data Signed-off-by: Chen Lihui --- rosidl_generator_py/CMakeLists.txt | 8 +++ rosidl_generator_py/msg/ByteArray.msg | 1 + rosidl_generator_py/resource/_msg.py.em | 18 +++++- rosidl_generator_py/test/test_byte_array.py | 72 +++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 rosidl_generator_py/msg/ByteArray.msg create mode 100644 rosidl_generator_py/test/test_byte_array.py diff --git a/rosidl_generator_py/CMakeLists.txt b/rosidl_generator_py/CMakeLists.txt index acffa894..c6cc067e 100644 --- a/rosidl_generator_py/CMakeLists.txt +++ b/rosidl_generator_py/CMakeLists.txt @@ -56,6 +56,7 @@ if(BUILD_TESTING) ${test_interface_files_MSG_FILES} # Cases not covered by test_interface_files msg/BuiltinTypeSequencesIdl.idl + msg/ByteArray.msg msg/StringArrays.msg msg/Property.msg ADD_LINTER_TESTS @@ -88,6 +89,13 @@ if(BUILD_TESTING) APPEND_LIBRARY_DIRS "${_append_library_dirs}" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py" ) + + ament_add_pytest_test(test_byte_array_py test/test_byte_array.py + PYTHON_EXECUTABLE "${BUILDTYPE_PYTHON_EXECUTABLE}" + APPEND_ENV "PYTHONPATH=${pythonpath}" + APPEND_LIBRARY_DIRS "${_append_library_dirs}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_py" + ) endif() endif() diff --git a/rosidl_generator_py/msg/ByteArray.msg b/rosidl_generator_py/msg/ByteArray.msg new file mode 100644 index 00000000..fb7239a1 --- /dev/null +++ b/rosidl_generator_py/msg/ByteArray.msg @@ -0,0 +1 @@ +byte[] data diff --git a/rosidl_generator_py/resource/_msg.py.em b/rosidl_generator_py/resource/_msg.py.em index f32126f6..d5e9a633 100644 --- a/rosidl_generator_py/resource/_msg.py.em +++ b/rosidl_generator_py/resource/_msg.py.em @@ -411,6 +411,7 @@ if isinstance(type_, AbstractNestedType): import inspect import builtins noqa_string = '' +byte_array_detected = False if member.name in dict(inspect.getmembers(builtins)).keys(): noqa_string = ' # noqa: A003' }@ @@ -487,8 +488,16 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): @{assert_msg_suffixes.insert(1, 'with length %d' % member.type.size)}@ @[ end if]@ @[ end if]@ - all(isinstance(v, @(get_python_type(type_))) for v in value) and @{assert_msg_suffixes.append("and each value of type '%s'" % get_python_type(type_))}@ +@[ if get_python_type(type_) == 'bytes']@ +@{byte_array_detected = True}@ +@{assert_msg_suffixes.append("or type 'uint8'")}@ + (isinstance(value, @(get_python_type(type_))) or + all(isinstance(v, @(get_python_type(type_))) for v in value) or + all(isinstance(v, int) for v in value)) and +@[ else]@ + all(isinstance(v, @(get_python_type(type_))) for v in value) and +@[ end if]@ @[ if isinstance(type_, BasicType) and type_.typename in SIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[3:]) @@ -588,6 +597,13 @@ bound = 1.7976931348623157e+308 self._@(member.name) = array.array('@(SPECIAL_NESTED_BASIC_TYPES[member.type.value_type.typename]['type_code'])', value) @[ end if]@ @[ else]@ +@[ if byte_array_detected]@ + if any(isinstance(v, int) for v in value): + self._@(member.name) = bytes(value) + else: + self._@(member.name) = value +@[ else]@ self._@(member.name) = value +@[ end if]@ @[ end if]@ @[end for]@ diff --git a/rosidl_generator_py/test/test_byte_array.py b/rosidl_generator_py/test/test_byte_array.py new file mode 100644 index 00000000..cf85f9cb --- /dev/null +++ b/rosidl_generator_py/test/test_byte_array.py @@ -0,0 +1,72 @@ +# Copyright 2022 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from rosidl_generator_py.msg import ByteArray + + +def test_msg_bytearray(): + msg = ByteArray() + + # types + assert isinstance(msg.data, list) + + # default values + assert [] == msg.data + + # set values + l1 = [1,2,3] + msg.data = l1 + # get values + assert bytes(l1) == msg.data + + # set values + l2 = {1,2,3} + msg.data = l2 + # get values + assert bytes(l2) == msg.data + + from collections import UserList + # set values + l3 = UserList(l1) + msg.data = l3 + # get values + assert bytes(l3) == msg.data + + # set values + l4 = bytes('123', 'utf-8') + msg.data = l4 + # get values + assert l4 == msg.data + + # set values + l5 = [b'1', b'2', b'3'] + msg.data = l5 + # get values + assert l5 == msg.data + +def test_msg_bytearray_exception(): + msg = ByteArray() + + with pytest.raises(ValueError): + l = [1,2,256] + msg.data = l + + with pytest.raises(AssertionError): + l = ['a', 'b'] + msg.data = l + + with pytest.raises(AssertionError): + l = [1, b'2', b'3'] + msg.data = l From 6dcbcd13349d10620f6722fecb550657cd388ee2 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Wed, 14 Sep 2022 15:56:43 +0800 Subject: [PATCH 2/5] flake8 Signed-off-by: Chen Lihui --- rosidl_generator_py/test/test_byte_array.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/rosidl_generator_py/test/test_byte_array.py b/rosidl_generator_py/test/test_byte_array.py index cf85f9cb..eb0ef0b7 100644 --- a/rosidl_generator_py/test/test_byte_array.py +++ b/rosidl_generator_py/test/test_byte_array.py @@ -26,13 +26,13 @@ def test_msg_bytearray(): assert [] == msg.data # set values - l1 = [1,2,3] + l1 = [1, 2, 3] msg.data = l1 # get values assert bytes(l1) == msg.data # set values - l2 = {1,2,3} + l2 = {1, 2, 3} msg.data = l2 # get values assert bytes(l2) == msg.data @@ -56,17 +56,18 @@ def test_msg_bytearray(): # get values assert l5 == msg.data + def test_msg_bytearray_exception(): msg = ByteArray() with pytest.raises(ValueError): - l = [1,2,256] - msg.data = l + l1 = [1, 2, 256] + msg.data = l1 with pytest.raises(AssertionError): - l = ['a', 'b'] - msg.data = l + l2 = ['a', 'b'] + msg.data = l2 with pytest.raises(AssertionError): - l = [1, b'2', b'3'] - msg.data = l + l3 = [1, b'2', b'3'] + msg.data = l3 From 243ae80629557873c2f031af2fd8cd7477de8258 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Thu, 15 Sep 2022 13:21:25 +0800 Subject: [PATCH 3/5] adjust indent and message Signed-off-by: Chen Lihui --- rosidl_generator_py/resource/_msg.py.em | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rosidl_generator_py/resource/_msg.py.em b/rosidl_generator_py/resource/_msg.py.em index d5e9a633..86000d09 100644 --- a/rosidl_generator_py/resource/_msg.py.em +++ b/rosidl_generator_py/resource/_msg.py.em @@ -489,15 +489,15 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): @[ end if]@ @[ end if]@ @{assert_msg_suffixes.append("and each value of type '%s'" % get_python_type(type_))}@ -@[ if get_python_type(type_) == 'bytes']@ +@[ if get_python_type(type_) == 'bytes']@ @{byte_array_detected = True}@ -@{assert_msg_suffixes.append("or type 'uint8'")}@ +@{assert_msg_suffixes.append("or type 'int' in range(0, 256)")}@ (isinstance(value, @(get_python_type(type_))) or all(isinstance(v, @(get_python_type(type_))) for v in value) or all(isinstance(v, int) for v in value)) and -@[ else]@ +@[ else]@ all(isinstance(v, @(get_python_type(type_))) for v in value) and -@[ end if]@ +@[ end if]@ @[ if isinstance(type_, BasicType) and type_.typename in SIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[3:]) From 2a61cfccec49001845bffed5700acee530c202ab Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Tue, 17 Jan 2023 17:28:26 +0800 Subject: [PATCH 4/5] address comments Co-authored-by: Tomoya Fujita Signed-off-by: Chen Lihui --- rosidl_generator_py/resource/_msg.py.em | 2 +- rosidl_generator_py/test/test_byte_array.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rosidl_generator_py/resource/_msg.py.em b/rosidl_generator_py/resource/_msg.py.em index 86000d09..b252b27a 100644 --- a/rosidl_generator_py/resource/_msg.py.em +++ b/rosidl_generator_py/resource/_msg.py.em @@ -491,7 +491,7 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): @{assert_msg_suffixes.append("and each value of type '%s'" % get_python_type(type_))}@ @[ if get_python_type(type_) == 'bytes']@ @{byte_array_detected = True}@ -@{assert_msg_suffixes.append("or type 'int' in range(0, 256)")}@ +@{assert_msg_suffixes.append("or type 'int' in range(0, 255)")}@ (isinstance(value, @(get_python_type(type_))) or all(isinstance(v, @(get_python_type(type_))) for v in value) or all(isinstance(v, int) for v in value)) and diff --git a/rosidl_generator_py/test/test_byte_array.py b/rosidl_generator_py/test/test_byte_array.py index eb0ef0b7..58a1620c 100644 --- a/rosidl_generator_py/test/test_byte_array.py +++ b/rosidl_generator_py/test/test_byte_array.py @@ -1,4 +1,4 @@ -# Copyright 2022 Open Source Robotics Foundation, Inc. +# Copyright 2022 Sony Group Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 51fd5ee9c2adce21871f2cf954c071ebd06e613b Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Fri, 27 Oct 2023 17:41:49 +0800 Subject: [PATCH 5/5] fix test Signed-off-by: Chen Lihui --- rosidl_generator_py/test/test_byte_array.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/rosidl_generator_py/test/test_byte_array.py b/rosidl_generator_py/test/test_byte_array.py index 58a1620c..fffedffa 100644 --- a/rosidl_generator_py/test/test_byte_array.py +++ b/rosidl_generator_py/test/test_byte_array.py @@ -56,6 +56,12 @@ def test_msg_bytearray(): # get values assert l5 == msg.data + # set values + l6 = ['a', 'b'] + msg.data = l6 + # get values + assert l6 == msg.data + def test_msg_bytearray_exception(): msg = ByteArray() @@ -64,10 +70,6 @@ def test_msg_bytearray_exception(): l1 = [1, 2, 256] msg.data = l1 - with pytest.raises(AssertionError): - l2 = ['a', 'b'] + with pytest.raises(TypeError): + l2 = [1, b'2', b'3'] msg.data = l2 - - with pytest.raises(AssertionError): - l3 = [1, b'2', b'3'] - msg.data = l3