From f9e9b03609b6f0354b5b7020dcd4418598caef4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernst=20W=C3=BCrger?= Date: Thu, 23 Jan 2025 15:47:51 +0100 Subject: [PATCH] refactor: Apply suggestions from code review Co-authored-by: micha91 --- .../converters/converter_config.py | 132 ++++++++++-------- .../converters/element_converter.py | 7 +- tests/test_elements.py | 4 +- 3 files changed, 75 insertions(+), 68 deletions(-) diff --git a/capella2polarion/converters/converter_config.py b/capella2polarion/converters/converter_config.py index 22fcd76..c7d7413 100644 --- a/capella2polarion/converters/converter_config.py +++ b/capella2polarion/converters/converter_config.py @@ -44,9 +44,10 @@ class LinkConfig: reverse_field: str = "" @staticmethod - def _force_config( + def generate_links_configs( links: list[str | dict[str, t.Any]], role_prefix: str = "" ) -> list[LinkConfig]: + """Generate LinkConfigs based on a list dict.""" result: list[LinkConfig] = [] for link in links: if isinstance(link, str): @@ -87,55 +88,6 @@ class CapellaTypeConfig: is_actor: bool | None = None nature: str | None = None - @staticmethod - def _force_dict( - converters: str | list[str] | ConvertersType | None, - ) -> dict[str, dict[str, t.Any]]: - match converters: - case None: - return {} - case str(): - return {converters: {}} - case list(): - return {c: {} for c in converters} - case dict(): - return CapellaTypeConfig._filter_config(converters) - case _: - raise TypeError("Unsupported Type") - - @staticmethod - def _filter_config( - converters: dict[str, t.Any], - ) -> dict[str, dict[str, t.Any]]: - custom_converters = ( - "include_pre_and_post_condition", - "linked_text_as_description", - "add_attributes", - "add_context_diagram", - "add_tree_diagram", - "add_jinja_fields", - "jinja_as_description", - ) - filtered_config = {} - assert isinstance(converters, dict) - for name, params in converters.items(): - params = params or {} - if name not in custom_converters: - logger.error("Unknown converter in config %r", name) - continue - - if name in ("add_context_diagram", "add_tree_diagram"): - assert isinstance(params, dict) - params = _filter_context_diagram_config(params) - - if name in ("add_attributes",): - assert isinstance(params, list) # type: ignore[unreachable] - params = {"attributes": params} # type: ignore[unreachable] - - filtered_config[name] = params - - return filtered_config - def _default_type_conversion(c_type: str) -> str: return c_type[0].lower() + c_type[1:] @@ -163,10 +115,10 @@ def read_config_file( global_config_dict = config_dict.pop("*", {}) all_type_config = global_config_dict.pop("*", {}) global_links = all_type_config.get("links", []) - self.__global_config.links = LinkConfig._force_config( + self.__global_config.links = LinkConfig.generate_links_configs( global_links, role_prefix ) - self.__global_config.converters = CapellaTypeConfig._force_dict( + self.__global_config.converters = self._force_dict( all_type_config.get("serializer", {}) ) @@ -228,12 +180,10 @@ def set_layer_config( type_prefix, ) self.polarion_types.add(p_type) - links = LinkConfig._force_config( + links = LinkConfig.generate_links_configs( type_config.get("links", []), role_prefix ) - converters = CapellaTypeConfig._force_dict( - type_config.get("serializer") - ) + converters = self._force_dict(type_config.get("serializer")) assert self.__global_config.converters is not None assert closest_config.converters is not None self._layer_configs[layer][c_type].append( @@ -261,12 +211,10 @@ def set_global_config( type_prefix, ) self.polarion_types.add(p_type) - link_config = LinkConfig._force_config( + link_config = LinkConfig.generate_links_configs( type_config.get("links", []), role_prefix ) - converters = CapellaTypeConfig._force_dict( - type_config.get("serializer") - ) + converters = self._force_dict(type_config.get("serializer")) assert self.__global_config.converters is not None self._global_configs[c_type] = CapellaTypeConfig( p_type, @@ -289,11 +237,11 @@ def set_diagram_config( diagram_config.get("polarion_type") or "diagram", type_prefix ) self.polarion_types.add(p_type) - link_config = LinkConfig._force_config( + link_config = LinkConfig.generate_links_configs( diagram_config.get("links", []), role_prefix ) links = _filter_links(c_type, link_config) - converters = CapellaTypeConfig._force_dict( + converters = self._force_dict( diagram_config.get("serializer") or "diagram" ) self.diagram_config = CapellaTypeConfig( @@ -332,6 +280,66 @@ def layers_and_types(self) -> cabc.Iterator[tuple[str, str]]: if c_type not in layer_types: yield layer, c_type + def _force_dict( + self, + converters: str | list[str] | ConvertersType | None, + ) -> dict[str, dict[str, t.Any]]: + match converters: + case None: + return {} + case str(): + return {converters: {}} + case list(): + return {c: {} for c in converters} + case dict(): + return self._filter_config(converters) + case _: + raise TypeError("Unsupported Type") + + def _filter_config( + self, converters: dict[str, t.Any] + ) -> dict[str, dict[str, t.Any]]: + custom_converters = ( + "include_pre_and_post_condition", + "linked_text_as_description", + "add_attributes", + "add_context_diagram", + "add_tree_diagram", + "add_jinja_fields", + "jinja_as_description", + ) + filtered_config: dict[str, dict[str, t.Any]] = {} + assert isinstance(converters, dict) + for name, params in converters.items(): + if name not in custom_converters: + logger.error("Unknown converter in config: %r", name) + continue + + match name: + case "add_context_diagram" | "add_tree_diagram": + params = params or {} + if isinstance(params, dict): + filtered_config[name] = _filter_context_diagram_config( + params + ) + else: + logger.error( + "Converter %r must be configured with dict type parameters", + name, + ) + case "add_attributes": + if isinstance(params, list): + filtered_config[name] = {"attributes": params} + else: + logger.error( + "Converter %r must be configured with list type parameters", + name, + ) + case _: + filtered_config[name] = params + + return filtered_config + def config_matches(config: CapellaTypeConfig | None, **kwargs: t.Any) -> bool: """Check whether the given ``config`` matches the given ``kwargs``.""" diff --git a/capella2polarion/converters/element_converter.py b/capella2polarion/converters/element_converter.py index 5c9d787..ecb5451 100644 --- a/capella2polarion/converters/element_converter.py +++ b/capella2polarion/converters/element_converter.py @@ -487,10 +487,9 @@ def _add_attributes( assert converter_data.work_item is not None for attribute in attributes: try: - value = _resolve_capella_attribute(converter_data, attribute) - setattr( - converter_data.work_item, attribute["polarion_id"], value - ) + converter_data.work_item.additional_attributes[ + attribute["polarion_id"] + ] = _resolve_capella_attribute(converter_data, attribute) except AttributeError: logger.error( "Attribute %r not found on %r", diff --git a/tests/test_elements.py b/tests/test_elements.py index 523be02..75b72a5 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -1874,7 +1874,7 @@ def test_add_attributes(self, model: capellambse.MelodyModel): } type_config = converter_config.CapellaTypeConfig( "PhysicalComponent", - converter_config.CapellaTypeConfig._force_dict(converters), + converter_config.ConverterConfig()._force_dict(converters), [], ) serializer = element_converter.CapellaWorkItemSerializer( @@ -1960,7 +1960,7 @@ def test_add_context_diagram_with_params( "systemFunction", config, [] ) type_config.converters = ( - converter_config.CapellaTypeConfig._force_dict(config) + converter_config.ConverterConfig()._force_dict(config) ) expected_filter = getattr(filters, context_diagram_filter) monkeypatch.setattr(