diff --git a/rosidl_generator_py/resource/_msg.py.em b/rosidl_generator_py/resource/_msg.py.em index 86b59f60..e9cd3b36 100644 --- a/rosidl_generator_py/resource/_msg.py.em +++ b/rosidl_generator_py/resource/_msg.py.em @@ -14,6 +14,7 @@ @# - value_to_py (function) @####################################################################### @ +from copy import copy import logging import traceback @@ -114,6 +115,28 @@ class @(spec.base_type.type)(metaclass=Metaclass): '_@(field.name)', @[end for]@ ] + + _fields_and_field_types = { +@[for field in spec.fields]@ +@[ if field.type.is_primitive_type() ]@ + '@(field.name)': '@(field.type)', +@[ else ]@ +@[ if field.type.is_array ]@ +@[ if field.type.array_size ]@ +@[ if field.type.is_upper_bound ]@ + '@(field.name)': '@(field.type.pkg_name)/@(field.type.type)[<=@(field.type.array_size)]', +@[ else ]@ + '@(field.name)': '@(field.type.pkg_name)/@(field.type.type)[@(field.type.array_size)]', +@[ end if ]@ +@[ else ]@ + '@(field.name)': '@(field.type.pkg_name)/@(field.type.type)[]', +@[ end if ]@ +@[ else ]@ + '@(field.name)': '@(field.type.pkg_name)/@(field.type.type)', +@[ end if ]@ +@[ end if ]@ +@[end for]@ + } @ @[if len(spec.fields) > 0]@ @@ -175,6 +198,10 @@ class @(spec.base_type.type)(metaclass=Metaclass): return False @[end for]@ return True + + @@classmethod + def get_fields_and_field_types(cls): + return copy(cls._fields_and_field_types) @[for field in spec.fields]@ @{ diff --git a/rosidl_generator_py/test/test_interfaces.py b/rosidl_generator_py/test/test_interfaces.py index e9f59c2d..215eb32f 100644 --- a/rosidl_generator_py/test/test_interfaces.py +++ b/rosidl_generator_py/test/test_interfaces.py @@ -257,3 +257,60 @@ def test_out_of_range(): setattr(b, 'unbounded_uint64_values', [2**64]) with pytest.raises(AssertionError): setattr(b, 'unbounded_uint64_values', [-1]) + + +def test_slot_attributes(): + a = Nested() + assert hasattr(a, 'get_fields_and_field_types') + assert hasattr(a, '__slots__') + nested_slot_types_dict = getattr(a, 'get_fields_and_field_types')() + nested_slots = getattr(a, '__slots__') + assert len(nested_slot_types_dict) == len(nested_slots) + expected_nested_slot_types_dict = { + 'primitives': 'rosidl_generator_py/Primitives', + 'two_primitives': 'rosidl_generator_py/Primitives[2]', + 'up_to_three_primitives': 'rosidl_generator_py/Primitives[<=3]', + 'unbounded_primitives': 'rosidl_generator_py/Primitives[]', + } + assert len(nested_slot_types_dict) == len(expected_nested_slot_types_dict) + + for expected_field, expected_slot_type in expected_nested_slot_types_dict.items(): + assert expected_field in nested_slot_types_dict.keys() + assert expected_slot_type == nested_slot_types_dict[expected_field] + + +def test_primative_slot_attributes(): + b = StringArrays() + assert hasattr(b, 'get_fields_and_field_types') + assert hasattr(b, '__slots__') + string_slot_types_dict = getattr(b, 'get_fields_and_field_types')() + string_slots = getattr(b, '__slots__') + assert len(string_slot_types_dict) == len(string_slots) + expected_string_slot_types_dict = { + 'ub_string_static_array_value': 'string<=5[3]', + 'ub_string_ub_array_value': 'string<=5[<=10]', + 'ub_string_dynamic_array_value': 'string<=5[]', + 'string_dynamic_array_value': 'string[]', + 'string_static_array_value': 'string[3]', + 'string_bounded_array_value': 'string[<=10]', + 'def_string_dynamic_array_value': 'string[]', + 'def_string_static_array_value': 'string[3]', + 'def_string_bounded_array_value': 'string[<=10]', + 'def_various_quotes': 'string[]', + 'def_various_commas': 'string[]', + } + + assert len(string_slot_types_dict) == len(expected_string_slot_types_dict) + + for expected_field, expected_slot_type in expected_string_slot_types_dict.items(): + assert expected_field in string_slot_types_dict.keys() + assert expected_slot_type == string_slot_types_dict[expected_field] + + +def test_modifying_slot_fields_and_types(): + b = StringArrays() + assert hasattr(b, 'get_fields_and_field_types') + string_slot_types_dict = getattr(b, 'get_fields_and_field_types')() + string_slot_types_dict_len = len(string_slot_types_dict) + string_slot_types_dict[1] = 2 + assert len(getattr(b, 'get_fields_and_field_types')()) == string_slot_types_dict_len