From 790c2cabd861ecc4b358ff38086305f4d97c1ed0 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Fri, 19 Apr 2019 14:43:43 -0700 Subject: [PATCH] simplify code using updated definition API Signed-off-by: Dirk Thomas --- rosidl_generator_py/resource/_action.py.em | 2 +- .../_action_pkg_typesupport_entry_point.c.em | 2 +- rosidl_generator_py/resource/_msg.py.em | 39 +++++++++---------- .../_msg_pkg_typesupport_entry_point.c.em | 6 +-- .../resource/_msg_support.c.em | 6 +-- rosidl_generator_py/resource/_srv.py.em | 2 +- .../_srv_pkg_typesupport_entry_point.c.em | 4 +- .../rosidl_generator_py/generate_py_impl.py | 38 ++++++------------ .../rosidl_runtime_py/convert.py | 8 ++-- 9 files changed, 44 insertions(+), 63 deletions(-) diff --git a/rosidl_generator_py/resource/_action.py.em b/rosidl_generator_py/resource/_action.py.em index 9f1877ba..8b920c8d 100644 --- a/rosidl_generator_py/resource/_action.py.em +++ b/rosidl_generator_py/resource/_action.py.em @@ -46,7 +46,7 @@ class Metaclass_@(action.namespaced_type.name)(type): import logging import traceback logger = logging.getLogger( - '@('.'.join(action.namespaced_type.namespaces + [action.namespaced_type.name]))') + '@('.'.join(action.namespaced_type.namespaced_name()))') logger.debug( 'Failed to import needed modules for type support:\n' + traceback.format_exc()) diff --git a/rosidl_generator_py/resource/_action_pkg_typesupport_entry_point.c.em b/rosidl_generator_py/resource/_action_pkg_typesupport_entry_point.c.em index f3de723b..e7b512d1 100644 --- a/rosidl_generator_py/resource/_action_pkg_typesupport_entry_point.c.em +++ b/rosidl_generator_py/resource/_action_pkg_typesupport_entry_point.c.em @@ -70,7 +70,7 @@ int8_t int8_t err; PyObject * pyobject_@(function_name) = NULL; pyobject_@(function_name) = PyCapsule_New( - (void *)ROSIDL_TYPESUPPORT_INTERFACE__ACTION_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(action.namespaced_type.namespaces + [action.namespaced_type.name])))(), + (void *)ROSIDL_TYPESUPPORT_INTERFACE__ACTION_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(action.namespaced_type.namespaced_name())))(), NULL, NULL); if (!pyobject_@(function_name)) { // previously added objects will be removed when the module is destroyed diff --git a/rosidl_generator_py/resource/_msg.py.em b/rosidl_generator_py/resource/_msg.py.em index 91a50b40..cac8b50f 100644 --- a/rosidl_generator_py/resource/_msg.py.em +++ b/rosidl_generator_py/resource/_msg.py.em @@ -16,8 +16,14 @@ from rosidl_parser.definition import ACTION_GOAL_SUFFIX from rosidl_parser.definition import ACTION_RESULT_SUFFIX from rosidl_parser.definition import Array from rosidl_parser.definition import BasicType +from rosidl_parser.definition import BOOLEAN_TYPE from rosidl_parser.definition import BoundedSequence +from rosidl_parser.definition import CHARACTER_TYPES +from rosidl_parser.definition import FLOATING_POINT_TYPES +from rosidl_parser.definition import INTEGER_TYPES from rosidl_parser.definition import NamespacedType +from rosidl_parser.definition import SIGNED_INTEGER_TYPES +from rosidl_parser.definition import UNSIGNED_INTEGER_TYPES }@ @#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @# Collect necessary import statements for all members @@ -91,7 +97,7 @@ class Metaclass_@(message.structure.namespaced_type.name)(type): import logging import traceback logger = logging.getLogger( - '@('.'.join(message.structure.namespaced_type.namespaces + [message.structure.namespaced_type.name]))') + '@('.'.join(message.structure.namespaced_type.namespaced_name()))') logger.debug( 'Failed to import needed modules for type support:\n' + traceback.format_exc()) @@ -253,7 +259,7 @@ if isinstance(type_, AbstractNestedType): '@(member.name)', [bytes([0]) for x in range(@(member.type.size))] ) -@[ elif isinstance(type_, BasicType) and type_.typename in ('char', 'wchar')]@ +@[ elif isinstance(type_, BasicType) and type_.typename in CHARACTER_TYPES]@ self.@(member.name) = kwargs.get( '@(member.name)', [chr(0) for x in range(@(member.type.size))] @@ -280,7 +286,7 @@ if isinstance(type_, AbstractNestedType): @[ end if]@ @[ elif isinstance(type_, BasicType) and type_.typename == 'octet']@ self.@(member.name) = kwargs.get('@(member.name)', bytes([0])) -@[ elif isinstance(type_, BasicType) and type_.typename in ('char', 'wchar')]@ +@[ elif isinstance(type_, BasicType) and type_.typename in CHARACTER_TYPES]@ self.@(member.name) = kwargs.get('@(member.name)', chr(0)) @[ else]@ self.@(member.name) = kwargs.get('@(member.name)', @(get_python_type(type_))()) @@ -374,7 +380,7 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): from collections import UserString @[ elif isinstance(type_, BasicType) and type_.typename == 'octet']@ from collections.abc import ByteString -@[ elif isinstance(type_, BasicType) and type_.typename in ('char', 'wchar')]@ +@[ elif isinstance(type_, BasicType) and type_.typename in CHARACTER_TYPES]@ from collections import UserString @[ end if]@ assert \ @@ -389,7 +395,7 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): all(len(val) <= @(type_.maximum_size) for val in value) and @{assert_msg_suffixes.append('and each string value not longer than %d' % type_.maximum_size)}@ @[ end if]@ -@[ if isinstance(member.type, Array) or isinstance(member.type, BoundedSequence)]@ +@[ if isinstance(member.type, (Array, BoundedSequence))]@ @[ if isinstance(member.type, BoundedSequence)]@ len(value) <= @(member.type.maximum_size) and @{assert_msg_suffixes.insert(1, 'with length <= %d' % member.type.maximum_size)}@ @@ -400,14 +406,14 @@ if member.name in dict(inspect.getmembers(builtins)).keys(): @[ 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 isinstance(type_, BasicType) and type_.typename.startswith('int')]@ +@[ if isinstance(type_, BasicType) and type_.typename in SIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[3:]) bound = 2**(nbits - 1) }@ all(val >= -@(bound) and val < @(bound) for val in value)), \ @{assert_msg_suffixes.append('and each integer in [%d, %d]' % (-bound, bound - 1))}@ -@[ elif isinstance(type_, BasicType) and type_.typename.startswith('uint')]@ +@[ elif isinstance(type_, BasicType) and type_.typename in UNSIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[4:]) bound = 2**nbits @@ -422,7 +428,7 @@ bound = 2**nbits @[ end if]@ "The '@(member.name)' field must be @(' '.join(assert_msg_suffixes))" @[ elif isinstance(member.type, AbstractGenericString) and member.type.has_maximum_size()]@ - ((isinstance(value, str) or isinstance(value, UserString)) and + (isinstance(value, (str, UserString)) and len(value) <= @(member.type.maximum_size)), \ "The '@(member.name)' field must be string value " \ 'not longer than @(type_.maximum_size)' @@ -430,35 +436,28 @@ bound = 2**nbits isinstance(value, @(type_.name)), \ "The '@(member.name)' field must be a sub message of type '@(type_.name)'" @[ elif isinstance(type_, BasicType) and type_.typename == 'octet']@ - ((isinstance(value, bytes) or isinstance(value, ByteString)) and + (isinstance(value, (bytes, ByteString)) and len(value) == 1), \ "The '@(member.name)' field must be of type 'bytes' or 'ByteString' with length 1" @[ elif isinstance(type_, BasicType) and type_.typename == 'char']@ - ((isinstance(value, str) or isinstance(value, UserString)) and + (isinstance(value, (str, UserString)) and len(value) == 1 and ord(value) >= -128 and ord(value) < 128), \ "The '@(member.name)' field must be of type 'str' or 'UserString' " \ 'with length 1 and the character ord() in [-128, 127]' @[ elif isinstance(type_, AbstractGenericString)]@ isinstance(value, str), \ "The '@(member.name)' field must be of type '@(get_python_type(type_))'" -@[ elif isinstance(type_, BasicType) and type_.typename in [ - 'boolean', - 'float', 'double', - 'int8', 'uint8', - 'int16', 'uint16', - 'int32', 'uint32', - 'int64', 'uint64', - ]]@ +@[ elif isinstance(type_, BasicType) and type_.typename in (BOOLEAN_TYPE, *FLOATING_POINT_TYPES, *INTEGER_TYPES)]@ isinstance(value, @(get_python_type(type_))), \ "The '@(member.name)' field must be of type '@(get_python_type(type_))'" -@[ if type_.typename.startswith('int')]@ +@[ if type_.typename in SIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[3:]) bound = 2**(nbits - 1) }@ assert value >= -@(bound) and value < @(bound), \ "The '@(member.name)' field must be an integer in [@(-bound), @(bound - 1)]" -@[ elif type_.typename.startswith('uint')]@ +@[ elif type_.typename in UNSIGNED_INTEGER_TYPES]@ @{ nbits = int(type_.typename[4:]) bound = 2**nbits diff --git a/rosidl_generator_py/resource/_msg_pkg_typesupport_entry_point.c.em b/rosidl_generator_py/resource/_msg_pkg_typesupport_entry_point.c.em index c8cb2559..1a76db9c 100644 --- a/rosidl_generator_py/resource/_msg_pkg_typesupport_entry_point.c.em +++ b/rosidl_generator_py/resource/_msg_pkg_typesupport_entry_point.c.em @@ -34,7 +34,7 @@ header_files = [ @ @{ module_name = convert_camel_case_to_lower_case_underscore(message.structure.namespaced_type.name) -msg_typename = '__'.join(message.structure.namespaced_type.namespaces + [message.structure.namespaced_type.name]) +msg_typename = '__'.join(message.structure.namespaced_type.namespaced_name()) }@ static void * @('__'.join(message.structure.namespaced_type.namespaces + [module_name]))__create_ros_message(void) @@ -56,7 +56,7 @@ PyObject * @('__'.join(message.structure.namespaced_type.namespaces + [module_na ROSIDL_GENERATOR_C_IMPORT const rosidl_message_type_support_t * -ROSIDL_GET_MSG_TYPE_SUPPORT(@(', '.join(message.structure.namespaced_type.namespaces + [message.structure.namespaced_type.name]))); +ROSIDL_GET_MSG_TYPE_SUPPORT(@(', '.join(message.structure.namespaced_type.namespaced_name()))); @{ register_function = '_register_msg_type__' + '__'.join(message.structure.namespaced_type.namespaces[1:] + [module_name]) @@ -76,7 +76,7 @@ function_names = ['create_ros_message', 'destroy_ros_message', 'convert_from_py' @[ if function_name != 'type_support']@ (void *)&@('__'.join(message.structure.namespaced_type.namespaces + [module_name]))__@(function_name), @[ else]@ - (void *)ROSIDL_GET_MSG_TYPE_SUPPORT(@(', '.join(message.structure.namespaced_type.namespaces + [message.structure.namespaced_type.name]))), + (void *)ROSIDL_GET_MSG_TYPE_SUPPORT(@(', '.join(message.structure.namespaced_type.namespaced_name()))), @[ end if]@ NULL, NULL); if (!pyobject_@(function_name)) { diff --git a/rosidl_generator_py/resource/_msg_support.c.em b/rosidl_generator_py/resource/_msg_support.c.em index d2883a97..840b4103 100644 --- a/rosidl_generator_py/resource/_msg_support.c.em +++ b/rosidl_generator_py/resource/_msg_support.c.em @@ -116,7 +116,7 @@ if isinstance(member.type, AbstractNestedType) and isinstance(member.type.value_ // end nested array functions include @[end if]@ @{ -msg_typename = '__'.join(message.structure.namespaced_type.namespaces + [message.structure.namespaced_type.name]) +msg_typename = '__'.join(message.structure.namespaced_type.namespaced_name()) }@ @ @[for member in message.structure.members]@ @@ -191,7 +191,7 @@ if isinstance(type_, AbstractNestedType): } @[ if isinstance(type_, NamespacedType)]@ @{ -nested_type = '__'.join(type_.namespaces + [type_.name]) +nested_type = '__'.join(type_.namespaced_name()) }@ @[ if isinstance(member.type, AbstractNestedType)]@ PyObject * seq_field = PySequence_Fast(field, "expected a sequence in '@(member.name)'"); @@ -496,7 +496,7 @@ if isinstance(type_, AbstractNestedType): @[ else]@ @[ if isinstance(type_, NamespacedType)]@ @{ -nested_type = '__'.join(type_.namespaces + [type_.name]) +nested_type = '__'.join(type_.namespaced_name()) }@ @[ if isinstance(member.type, AbstractNestedType)]@ @[ if isinstance(member.type, AbstractSequence)]@ diff --git a/rosidl_generator_py/resource/_srv.py.em b/rosidl_generator_py/resource/_srv.py.em index 8b5a40d6..8f1e608c 100644 --- a/rosidl_generator_py/resource/_srv.py.em +++ b/rosidl_generator_py/resource/_srv.py.em @@ -30,7 +30,7 @@ class Metaclass_@(service.namespaced_type.name)(type): import logging import traceback logger = logging.getLogger( - '@('.'.join(service.namespaced_type.namespaces + [service.namespaced_type.name]))') + '@('.'.join(service.namespaced_type.namespaced_name()))') logger.debug( 'Failed to import needed modules for type support:\n' + traceback.format_exc()) diff --git a/rosidl_generator_py/resource/_srv_pkg_typesupport_entry_point.c.em b/rosidl_generator_py/resource/_srv_pkg_typesupport_entry_point.c.em index 179234c7..09d43836 100644 --- a/rosidl_generator_py/resource/_srv_pkg_typesupport_entry_point.c.em +++ b/rosidl_generator_py/resource/_srv_pkg_typesupport_entry_point.c.em @@ -25,7 +25,7 @@ function_name = 'type_support' ROSIDL_GENERATOR_C_IMPORT const rosidl_service_type_support_t * -ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(service.namespaced_type.namespaces + [service.namespaced_type.name])))(); +ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(service.namespaced_type.namespaced_name())))(); @{ register_function = '_register_srv_type__' + '__'.join(service.namespaced_type.namespaces[1:] + [type_name]) @@ -37,7 +37,7 @@ int8_t int8_t err; PyObject * pyobject_@(function_name) = NULL; pyobject_@(function_name) = PyCapsule_New( - (void *)ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(service.namespaced_type.namespaces + [service.namespaced_type.name])))(), + (void *)ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join(service.namespaced_type.namespaced_name())))(), NULL, NULL); if (!pyobject_@(function_name)) { // previously added objects will be removed when the module is destroyed diff --git a/rosidl_generator_py/rosidl_generator_py/generate_py_impl.py b/rosidl_generator_py/rosidl_generator_py/generate_py_impl.py index d59db7c5..94f1cd3c 100644 --- a/rosidl_generator_py/rosidl_generator_py/generate_py_impl.py +++ b/rosidl_generator_py/rosidl_generator_py/generate_py_impl.py @@ -26,8 +26,11 @@ from rosidl_parser.definition import AbstractString from rosidl_parser.definition import Array from rosidl_parser.definition import BasicType +from rosidl_parser.definition import CHARACTER_TYPES +from rosidl_parser.definition import FLOATING_POINT_TYPES from rosidl_parser.definition import IdlContent from rosidl_parser.definition import IdlLocator +from rosidl_parser.definition import INTEGER_TYPES from rosidl_parser.definition import NamespacedType from rosidl_parser.parser import parse_idl_file @@ -153,12 +156,7 @@ def primitive_value_to_py(type_, value): if type_.typename == 'boolean': return 'True' if value else 'False' - if type_.typename in ( - 'int8', 'uint8', - 'int16', 'uint16', - 'int32', 'uint32', - 'int64', 'uint64', - ): + if type_.typename in INTEGER_TYPES: return str(value) if type_.typename == 'char': @@ -167,7 +165,7 @@ def primitive_value_to_py(type_, value): if type_.typename == 'octet': return repr(bytes([value])) - if type_.typename in ('float', 'double'): + if type_.typename in FLOATING_POINT_TYPES: return '%s' % value assert False, "unknown primitive type '%s'" % type_.typename @@ -180,12 +178,7 @@ def constant_value_to_py(type_, value): if type_.typename == 'bool': return 'True' if value else 'False' - if type_.typename in ( - 'int8', 'uint8', - 'int16', 'uint16', - 'int32', 'uint32', - 'int64', 'uint64', - ): + if type_.typename in INTEGER_TYPES: return str(value) if type_.typename == 'char': @@ -194,7 +187,7 @@ def constant_value_to_py(type_, value): if type_.typename == 'octet': return repr(bytes([value])) - if type_.typename in ('float', 'double'): + if type_.typename in FLOATING_POINT_TYPES: return '%s' % value if isinstance(type_, AbstractString): @@ -228,7 +221,7 @@ def get_python_type(type_): if ( isinstance(type_.value_type, BasicType) and - type_.value_type.typename in ('char', 'wchar') + type_.value_type.typename in CHARACTER_TYPES ): return 'str' @@ -238,22 +231,13 @@ def get_python_type(type_): if isinstance(type_, BasicType) and type_.typename == 'octet': return 'bytes' - if isinstance(type_, BasicType) and type_.typename in ( - 'int8', 'uint8', - 'int16', 'uint16', - 'int32', 'uint32', - 'int64', 'uint64', - ): + if isinstance(type_, BasicType) and type_.typename in INTEGER_TYPES: return 'int' - if isinstance(type_, BasicType) and type_.typename in ( - 'float', 'double', - ): + if isinstance(type_, BasicType) and type_.typename in FLOATING_POINT_TYPES: return 'float' - if isinstance(type_, BasicType) and type_.typename in ( - 'char', 'wchar', - ): + if isinstance(type_, BasicType) and type_.typename in CHARACTER_TYPES: return 'str' assert False, "unknown type '%s'" % type_ diff --git a/rosidl_runtime_py/rosidl_runtime_py/convert.py b/rosidl_runtime_py/rosidl_runtime_py/convert.py index 663384db..fc783f13 100644 --- a/rosidl_runtime_py/rosidl_runtime_py/convert.py +++ b/rosidl_runtime_py/rosidl_runtime_py/convert.py @@ -128,9 +128,7 @@ def _convert_value(value, truncate_length=None): elif isinstance(value, str): if truncate_length is not None and len(value) > truncate_length: value = value[:truncate_length] + '...' - elif (any( - isinstance(value, t) for t in [list, tuple, array.array, numpy.ndarray] - )): + elif isinstance(value, (list, tuple, array.array, numpy.ndarray)): # Since arrays and ndarrays can't contain mixed types convert to list typename = tuple if isinstance(value, tuple) else list if truncate_length is not None and len(value) > truncate_length: @@ -143,7 +141,7 @@ def _convert_value(value, truncate_length=None): # Truncate every item in the list value = typename( [_convert_value(v, truncate_length) for v in value]) - elif isinstance(value, dict) or isinstance(value, OrderedDict): + elif isinstance(value, (dict, OrderedDict)): # Convert each key and value in the mapping new_value = {} if isinstance(value, dict) else OrderedDict() for k, v in value.items(): @@ -152,7 +150,7 @@ def _convert_value(value, truncate_length=None): value = new_value elif isinstance(value, numpy.number): value = value.item() - elif not any(isinstance(value, t) for t in (bool, float, int)): + elif not isinstance(value, (bool, float, int)): # Assuming value is a message since it is neither a collection nor a primitive type value = message_to_ordereddict(value, truncate_length=truncate_length) return value