From 84220f42890c672b78c2c2b8bff5d824373dffc7 Mon Sep 17 00:00:00 2001 From: eboasson Date: Wed, 10 Apr 2024 10:34:34 +0200 Subject: [PATCH] Make `cyclonedds typeof` work on derived types (#243) * Make `cyclonedds typeof` work on derived types This solves File "/usr/lib64/python3.11/site-packages/cyclonedds/idl/init.py", line 39, \ in make_idl_struct \ bases = tuple(list(*bases) + [IdlStruct]) ^^^^^^^^^^^^ TypeError: 'IdlMeta' object is not iterable when `cyclonedds typeof` is used to print a derived type. Signed-off-by: Erik Boasson --- cyclonedds/idl/__init__.py | 2 +- cyclonedds/tools/cli/idl.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cyclonedds/idl/__init__.py b/cyclonedds/idl/__init__.py index 493e2301..fb667b94 100644 --- a/cyclonedds/idl/__init__.py +++ b/cyclonedds/idl/__init__.py @@ -39,7 +39,7 @@ def deserialize_key(cls: Type[_TIS], data: bytes, has_header: bool = True, use_v def make_idl_struct(class_name: str, typename: str, fields: Dict[str, Any], *, dataclassify=True, field_annotations: Optional[Dict[str, Dict[str, Any]]] = None, bases: Tuple[Type[IdlStruct], ...] = ()) -> Type[IdlStruct]: - bases = tuple(list(*bases) + [IdlStruct]) + bases = tuple(list(bases) + [IdlStruct]) namespace = IdlMeta.__prepare__(class_name, bases, typename=typename) for fieldname, _type in fields.items(): diff --git a/cyclonedds/tools/cli/idl.py b/cyclonedds/tools/cli/idl.py index 85290305..8c7d9762 100644 --- a/cyclonedds/tools/cli/idl.py +++ b/cyclonedds/tools/cli/idl.py @@ -1,4 +1,4 @@ -from inspect import isclass +from inspect import isclass, getmro from textwrap import indent from typing import Any, Type, List @@ -161,9 +161,22 @@ def _proc_type(cls, state, _type, top_level=False): out = cls._annot(_type) scope, enname = cls._scoped_name(_type.__idl__.idl_transformed_typename) - out += f"struct {enname} {{" + out += f"struct {enname} " + basefields = [] + for base in getmro(_type)[1:]: + if not issubclass(base, IdlStruct) or base is IdlStruct: + continue + + cls._proc_type(state, base) + basefields.extend(get_extended_type_hints(base).keys()) + _, basename = cls._scoped_name(base.__idl__.idl_transformed_typename) + out += f": {basename} " + break + out += "{" field_annot = get_idl_field_annotations(_type) for name, _type in get_extended_type_hints(_type).items(): + if name in basefields: + continue out += "\n " if "key" in field_annot.get(name, {}): out += "@key "