@@ -191,44 +191,33 @@ for member in message.structure.members:
191191 elif isinstance (member .type , AbstractSequence) and ' array.array' not in lazy_import_methods :
192192 lazy_import_methods .add (' array.array' )
193193 TEMPLATE (' _import_type.c.em' , full_type_name = ' array.array' , func_name = ' lazy_import_array' )
194- }@
195- @ {
194+
196195module_name = ' _' + convert_camel_case_to_lower_case_underscore (interface_path .stem )
197196class_module = ' %s.%s' % (' .' .join (message .structure .namespaced_type .namespaces ), module_name)
198197namespaced_type = message .structure .namespaced_type .name
198+ full_type_name = ' .' .join (message .structure .namespaced_type .namespaces + [module_name, message .structure .namespaced_type .name ])
199+ import_func_name = ' lazy_import_' + convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )
200+ no_fields = len (message .structure .members ) == 1 and message .structure .members [0 ].name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME
201+ TEMPLATE (
202+ ' _import_type.c.em' ,
203+ full_type_name = full_type_name, func_name = import_func_name, ensure_is_type = True)
199204}@
200205ROSIDL_GENERATOR_C_EXPORT
201206bool @ (' __' .join (message .structure .namespaced_type .namespaces + [convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )]))__convert_from_py (PyObject * _pymsg, void * _ros_message)
202207{
203208 // check that the passed message is of the expected Python class
204209 {
205- PyObject * class_attr = PyObject_GetAttrString (_pymsg, " __class__" );
206- if (class_attr == NULL) {
207- return false ;
208- }
209- PyObject * name_attr = PyObject_GetAttrString (class_attr, " __name__" );
210- if (name_attr == NULL) {
211- Py_DECREF (class_attr);
212- return false ;
213- }
214- PyObject * module_attr = PyObject_GetAttrString (class_attr, " __module__" );
215- if (module_attr == NULL) {
216- Py_DECREF (name_attr);
217- Py_DECREF (class_attr);
218- return false ;
219- }
220-
221- // PyUnicode_1BYTE_DATA is just a cast
222- assert (strncmp (" @(class_module)" , (char * )PyUnicode_1BYTE_DATA (module_attr), @ (len (class_module))) == 0 );
223- assert (strncmp (" @(namespaced_type)" , (char * )PyUnicode_1BYTE_DATA (name_attr), @ (len (namespaced_type))) == 0 );
224-
225- Py_DECREF (module_attr);
226- Py_DECREF (name_attr);
227- Py_DECREF (class_attr);
210+ PyTypeObject * py_type = (PyTypeObject * )@ (import_func_name)();
211+ assert (Py_TYPE (_pymsg) == py_type);
228212 }
229213 @ (msg_typename) * ros_message = _ros_message;
214+ @ [if no_fields]@
215+ ros_message-> @ (member .name ) = 0 ;
216+ @ [else ]
217+ @ (message .structure .namespaced_type .name )Base * base_msg = (@ (message .structure .namespaced_type .name )Base * )_pymsg;
218+ @ [end if ]@
230219@ [for member in message .structure .members ]@
231- @ [ if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
220+ @ [ if no_fields ]@
232221 ros_message-> @ (member .name ) = 0 ;
233222@ [ continue ]@
234223@ [ end if ]@
@@ -238,31 +227,30 @@ if isinstance(type_, AbstractNestedType):
238227 type_ = type_ .value_type
239228}@
240229 { // @ (member .name )
241- PyObject * field = PyObject_GetAttrString (_pymsg, " @(member.name)" );
230+ @ [ if not isinstance (member .type , BasicType)]@
231+ PyObject * field = base_msg-> _@ (member .name );
242232 if (! field) {
243233 return false ;
244234 }
235+ @ [ end if ]@
245236@ [ if isinstance (type_, NamespacedType)]@
246237@ {
247238nested_type = ' __' .join (type_ .namespaced_name ())
248239}@
249240@ [ if isinstance (member .type , AbstractNestedType)]@
250241 PyObject * seq_field = PySequence_Fast (field, " expected a sequence in '@(member.name)'" );
251242 if (! seq_field) {
252- Py_DECREF (field);
253243 return false ;
254244 }
255245@ [ if isinstance (member .type , AbstractSequence)]@
256246 Py_ssize_t size = PySequence_Size (field);
257247 if (- 1 == size) {
258248 Py_DECREF (seq_field);
259- Py_DECREF (field);
260249 return false ;
261250 }
262251 if (! @ (nested_type)__Sequence__init (& (ros_message-> @ (member .name )), size)) {
263252 PyErr_SetString (PyExc_RuntimeError, " unable to create @(nested_type)__Sequence ros_message" );
264253 Py_DECREF (seq_field);
265- Py_DECREF (field);
266254 return false ;
267255 }
268256 @ (nested_type) * dest = ros_message-> @ (member .name ).data ;
@@ -273,14 +261,12 @@ nested_type = '__'.join(type_.namespaced_name())
273261 for (Py_ssize_t i = 0 ; i < size; ++ i) {
274262 if (! @ (' __' .join (type_ .namespaces + [convert_camel_case_to_lower_case_underscore (type_ .name )]))__convert_from_py (PySequence_Fast_GET_ITEM (seq_field, i), & dest[i])) {
275263 Py_DECREF (seq_field);
276- Py_DECREF (field);
277264 return false ;
278265 }
279266 }
280267 Py_DECREF (seq_field);
281268@ [ else ]@
282269 if (! @ (' __' .join (type_ .namespaces + [convert_camel_case_to_lower_case_underscore (type_ .name )]))__convert_from_py (field, & ros_message-> @ (member .name ))) {
283- Py_DECREF (field);
284270 return false ;
285271 }
286272@ [ end if ]@
@@ -291,21 +277,18 @@ nested_type = '__'.join(type_.namespaced_name())
291277 Py_buffer view;
292278 int rc = PyObject_GetBuffer (field, & view, PyBUF_SIMPLE);
293279 if (rc < 0 ) {
294- Py_DECREF (field);
295280 return false ;
296281 }
297282 Py_ssize_t size = view .len / sizeof (@ primitive_msg_type_to_c (member .type .value_type ));
298283 if (! rosidl_runtime_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), size)) {
299284 PyErr_SetString (PyExc_RuntimeError, " unable to create @(member.type.value_type.typename)__Sequence ros_message" );
300285 PyBuffer_Release (& view);
301- Py_DECREF (field);
302286 return false ;
303287 }
304288 @ primitive_msg_type_to_c (member .type .value_type ) * dest = ros_message-> @ (member .name ).data ;
305289 rc = PyBuffer_ToContiguous (dest, & view, view .len , ' C' );
306290 if (rc < 0 ) {
307291 PyBuffer_Release (& view);
308- Py_DECREF (field);
309292 return false ;
310293 }
311294 PyBuffer_Release (& view);
@@ -325,36 +308,31 @@ nested_type = '__'.join(type_.namespaced_name())
325308@ [ else ]@
326309 PyObject * seq_field = PySequence_Fast (field, " expected a sequence in '@(member.name)'" );
327310 if (! seq_field) {
328- Py_DECREF (field);
329311 return false ;
330312 }
331313@ [ end if ]@
332314@ [ if isinstance (member .type , AbstractSequence)]@
333315 Py_ssize_t size = PySequence_Size (field);
334316 if (- 1 == size) {
335317 Py_DECREF (seq_field);
336- Py_DECREF (field);
337318 return false ;
338319 }
339320@ [ if isinstance (member .type .value_type , AbstractString)]@
340321 if (! rosidl_runtime_c__String__Sequence__init (& (ros_message-> @ (member .name )), size)) {
341322 PyErr_SetString (PyExc_RuntimeError, " unable to create String__Sequence ros_message" );
342323 Py_DECREF (seq_field);
343- Py_DECREF (field);
344324 return false ;
345325 }
346326@ [ elif isinstance (member .type .value_type , AbstractWString)]@
347327 if (! rosidl_runtime_c__U16String__Sequence__init (& (ros_message-> @ (member .name )), size)) {
348328 PyErr_SetString (PyExc_RuntimeError, " unable to create U16String__Sequence ros_message" );
349329 Py_DECREF (seq_field);
350- Py_DECREF (field);
351330 return false ;
352331 }
353332@ [ else ]@
354333 if (! rosidl_runtime_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), size)) {
355334 PyErr_SetString (PyExc_RuntimeError, " unable to create @(member.type.value_type.typename)__Sequence ros_message" );
356335 Py_DECREF (seq_field);
357- Py_DECREF (field);
358336 return false ;
359337 }
360338@ [ end if ]@
@@ -368,7 +346,6 @@ nested_type = '__'.join(type_.namespaced_name())
368346 PyObject * item = PySequence_Fast_GET_ITEM (seq_field, i);
369347 if (! item) {
370348 Py_DECREF (seq_field);
371- Py_DECREF (field);
372349 return false ;
373350 }
374351@ [ end if ]@
@@ -392,7 +369,6 @@ nested_type = '__'.join(type_.namespaced_name())
392369 PyObject * encoded_item = PyUnicode_AsUTF8String (item);
393370 if (! encoded_item) {
394371 Py_DECREF (seq_field);
395- Py_DECREF (field);
396372 return false ;
397373 }
398374 rosidl_runtime_c__String__assign (& dest[i], PyBytes_AS_STRING (encoded_item));
@@ -403,7 +379,6 @@ nested_type = '__'.join(type_.namespaced_name())
403379 PyObject * encoded_item = PyUnicode_AsUTF16String (item);
404380 if (! encoded_item) {
405381 Py_DECREF (seq_field);
406- Py_DECREF (field);
407382 return false ;
408383 }
409384 char * buffer;
@@ -412,15 +387,13 @@ nested_type = '__'.join(type_.namespaced_name())
412387 if (rc) {
413388 Py_DECREF (encoded_item);
414389 Py_DECREF (seq_field);
415- Py_DECREF (field);
416390 return false ;
417391 }
418392 // use offset of 2 to skip BOM mark
419393 bool succeeded = rosidl_runtime_c__U16String__assignn_from_char (& dest[i], buffer + 2 , length - 2 );
420394 Py_DECREF (encoded_item);
421395 if (! succeeded) {
422396 Py_DECREF (seq_field);
423- Py_DECREF (field);
424397 return false ;
425398 }
426399@ [ elif isinstance (member .type .value_type , BasicType) and member .type .value_type .typename == ' boolean' ]@
@@ -464,18 +437,6 @@ nested_type = '__'.join(type_.namespaced_name())
464437 }
465438 Py_DECREF (seq_field);
466439 }
467- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' char' ]@
468- assert (PyUnicode_Check (field));
469- PyObject * encoded_field = PyUnicode_AsUTF8String (field);
470- if (! encoded_field) {
471- Py_DECREF (field);
472- return false ;
473- }
474- ros_message-> @ (member .name ) = PyBytes_AS_STRING (encoded_field)[0 ];
475- Py_DECREF (encoded_field);
476- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' octet' ]@
477- assert (PyBytes_Check (field));
478- ros_message-> @ (member .name ) = PyBytes_AS_STRING (field)[0 ];
479440@ [ elif isinstance (member .type , AbstractString)]@
480441 assert (PyUnicode_Check (field));
481442 PyObject * encoded_field = PyUnicode_AsUTF8String (field);
@@ -490,78 +451,38 @@ nested_type = '__'.join(type_.namespaced_name())
490451 // the returned string starts with a BOM mark and uses native byte order
491452 PyObject * encoded_field = PyUnicode_AsUTF16String (field);
492453 if (! encoded_field) {
493- Py_DECREF (field);
494454 return false ;
495455 }
496456 char * buffer;
497457 Py_ssize_t length;
498458 int rc = PyBytes_AsStringAndSize (encoded_field, & buffer, & length);
499459 if (rc) {
500460 Py_DECREF (encoded_field);
501- Py_DECREF (field);
502461 return false ;
503462 }
504463 // use offset of 2 to skip BOM mark
505464 {
506465 bool succeeded = rosidl_runtime_c__U16String__assignn_from_char (& ros_message-> @ (member .name ), buffer + 2 , length - 2 );
507466 Py_DECREF (encoded_field);
508467 if (! succeeded) {
509- Py_DECREF (field);
510468 return false ;
511469 }
512470 }
513- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' boolean' ]@
514- assert (PyBool_Check (field));
515- ros_message-> @ (member .name ) = (Py_True == field);
516- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (' float' , ' double' )]@
517- assert (PyFloat_Check (field));
471+ @ [ elif isinstance (member .type , BasicType)]@
518472@ [ if member .type .typename == ' float' ]@
519- ros_message-> @ (member .name ) = (float)PyFloat_AS_DOUBLE (field);
520- @ [ else ]@
521- ros_message-> @ (member .name ) = PyFloat_AS_DOUBLE (field);
522- @ [ end if ]@
523- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (
524- ' int8' ,
525- ' int16' ,
526- ' int32' ,
527- )]@
528- assert (PyLong_Check (field));
529- ros_message-> @ (member .name ) = (@ (primitive_msg_type_to_c (member .type )))PyLong_AsLong (field);
530- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (
531- ' uint8' ,
532- ' uint16' ,
533- ' uint32' ,
534- )]@
535- assert (PyLong_Check (field));
536- @ [ if member .type .typename == ' uint32' ]@
537- ros_message-> @ (member .name ) = PyLong_AsUnsignedLong (field);
473+ ros_message-> @ (member .name ) = (float)base_msg-> _@ (member .name );
538474@ [ else ]@
539- ros_message-> @ (member .name ) = ( @ ( primitive_msg_type_to_c ( member .type ))) PyLong_AsUnsignedLong (field );
475+ ros_message-> @ (member .name ) = base_msg -> _ @ ( member .name );
540476@ [ end if ]@
541- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' int64' ]@
542- assert (PyLong_Check (field));
543- ros_message-> @ (member .name ) = PyLong_AsLongLong (field);
544- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' uint64' ]@
545- assert (PyLong_Check (field));
546- ros_message-> @ (member .name ) = PyLong_AsUnsignedLongLong (field);
547477@ [ else ]@
548478 assert (false );
549479@ [ end if ]@
550- Py_DECREF (field);
551480 }
552481@ [end for ]@
553482
554483 return true ;
555484}
556485
557- @ {
558- full_type_name = ' .' .join (message .structure .namespaced_type .namespaces + [module_name, message .structure .namespaced_type .name ])
559- import_func_name = ' lazy_import_' + convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )
560- TEMPLATE (
561- ' _import_type.c.em' ,
562- full_type_name = full_type_name, func_name = import_func_name, ensure_is_type = True)
563- }@
564-
565486ROSIDL_GENERATOR_C_EXPORT
566487PyObject * @ (' __' .join (message .structure .namespaced_type .namespaces + [convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )]))__convert_to_py (void * raw_ros_message)
567488{
@@ -587,13 +508,13 @@ PyObject * @('__'.join(message.structure.namespaced_type.namespaces + [convert_c
587508 return NULL;
588509 }
589510 }
590- @ [if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
511+ @ [if no_fields ]@
591512 (void )raw_ros_message;
592513@ [else ]@
593514 @ (msg_typename) * ros_message = (@ (msg_typename) * )raw_ros_message;
594515@ [end if ]@
595516@ [for member in message .structure .members ]@
596- @ [ if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
517+ @ [ if no_fields ]@
597518@ [ continue ]@
598519@ [ end if ]@
599520@ {
0 commit comments