Skip to content

Commit 82f5f9a

Browse files
committed
fix(generator): emit .msg syntax in _fields_and_field_types for bounded types
_fields_and_field_types / get_fields_and_field_types() is documented as a Python introspection API for message field types. However it was emitting OMG IDL 4.2 syntax for bounded strings and sequences: sequence<string<256>, 32> (IDL) instead of the canonical ROS 2 .msg syntax: string<=256[<=32] (.msg) This breaks any consumer that passes the output directly to the MCAP ros2msg schema encoder (e.g. mcap_utils _build_ros2_schema()), because the ros2msg schema encoding requires .msg syntax per the MCAP registry spec (https://mcap.dev/spec/registry#ros2msg). Foxglove and other ros2msg-aware tools reject the IDL form. Changes: - Remove IDL-style sequence<> prefix/suffix generation in the _fields_and_field_types dict template. - Emit bounded string bound with <= (string<=N) instead of <N>. - Emit bounded sequence bound as [<=N], unbounded sequence as [], fixed-size array as [N] -- all matching .msg syntax. - Update test_interfaces.py expected values accordingly. The SLOT_TYPES tuple (rosidl_parser.definition objects) is unchanged and remains the correct API for programmatic type inspection.
1 parent e210dc3 commit 82f5f9a

2 files changed

Lines changed: 17 additions & 22 deletions

File tree

rosidl_generator_py/resource/_msg.py.em

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,7 @@ if isinstance(type_, AbstractNestedType):
268268
type_ = type_.value_type
269269
}@
270270
'@(member.name)': '@
271-
@# the prefix for nested types
272-
@[ if isinstance(member.type, AbstractSequence)]@
273-
sequence<@
274-
@[ end if]@
275-
@# the typename of the non-nested type or the nested basetype
271+
@# the typename of the non-nested type or the nested basetype (.msg syntax)
276272
@[ if isinstance(type_, BasicType)]@
277273
@(type_.typename)@
278274
@[ elif isinstance(type_, AbstractGenericString)]@
@@ -282,17 +278,16 @@ w@
282278
@[ end if]@
283279
string@
284280
@[ if type_.has_maximum_size()]@
285-
<@(type_.maximum_size)>@
281+
<=@(type_.maximum_size)@
286282
@[ end if]@
287283
@[ elif isinstance(type_, NamespacedType)]@
288284
@('/'.join([type_.namespaces[0], type_.name]))@
289285
@[ end if]@
290-
@# the suffix for nested types
291-
@[ if isinstance(member.type, AbstractSequence)]@
292-
@[ if isinstance(member.type, BoundedSequence)]@
293-
, @(member.type.maximum_size)@
294-
@[ end if]@
295-
>@
286+
@# array/sequence suffix in .msg syntax
287+
@[ if isinstance(member.type, BoundedSequence)]@
288+
[<=@(member.type.maximum_size)]@
289+
@[ elif isinstance(member.type, UnboundedSequence)]@
290+
[]@
296291
@[ elif isinstance(member.type, Array)]@
297292
[@(member.type.size)]@
298293
@[ end if]@

rosidl_generator_py/test/test_interfaces.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -939,17 +939,17 @@ def test_string_slot_attributes() -> None:
939939
assert hasattr(msg, '__slots__')
940940
string_slot_types_dict = getattr(msg, 'get_fields_and_field_types')()
941941
expected_string_slot_types_dict = {
942-
'ub_string_static_array_value': 'string<5>[3]',
943-
'ub_string_ub_array_value': 'sequence<string<5>, 10>',
944-
'ub_string_dynamic_array_value': 'sequence<string<5>>',
945-
'string_dynamic_array_value': 'sequence<string>',
942+
'ub_string_static_array_value': 'string<=5[3]',
943+
'ub_string_ub_array_value': 'string<=5[<=10]',
944+
'ub_string_dynamic_array_value': 'string<=5[]',
945+
'string_dynamic_array_value': 'string[]',
946946
'string_static_array_value': 'string[3]',
947-
'string_bounded_array_value': 'sequence<string, 10>',
948-
'def_string_dynamic_array_value': 'sequence<string>',
947+
'string_bounded_array_value': 'string[<=10]',
948+
'def_string_dynamic_array_value': 'string[]',
949949
'def_string_static_array_value': 'string[3]',
950-
'def_string_bounded_array_value': 'sequence<string, 10>',
951-
'def_various_quotes': 'sequence<string>',
952-
'def_various_commas': 'sequence<string>',
950+
'def_string_bounded_array_value': 'string[<=10]',
951+
'def_various_quotes': 'string[]',
952+
'def_various_commas': 'string[]',
953953
}
954954

955955
assert len(string_slot_types_dict) == len(expected_string_slot_types_dict)
@@ -1012,7 +1012,7 @@ def test_builtin_sequence_slot_attributes() -> None:
10121012
assert hasattr(msg, '__slots__')
10131013
builtin_sequence_slot_types_dict = getattr(msg, 'get_fields_and_field_types')()
10141014
expected_builtin_sequence_slot_types_dict = {
1015-
'char_sequence_unbounded': 'sequence<char>',
1015+
'char_sequence_unbounded': 'char[]',
10161016
}
10171017

10181018
assert len(builtin_sequence_slot_types_dict) == len(expected_builtin_sequence_slot_types_dict)

0 commit comments

Comments
 (0)