From c25a66f0cbe91c60a1eba39bf0638eb760b045db Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 27 Nov 2024 10:14:42 +0100 Subject: [PATCH] feat: add "exists" attribut for a family --- src/rougail/convert.py | 27 +++++++++++-------- .../16_6exists_redefine_family/__init__.py | 0 .../dictionaries/rougail/00-base.yml | 10 +++++++ .../dictionaries/rougail/01-base.yml | 16 +++++++++++ .../makedict/after.json | 10 +++++++ .../makedict/base.json | 4 +++ .../makedict/before.json | 10 +++++++ .../makedict/mandatory.json | 1 + .../tiramisu/base.py | 18 +++++++++++++ .../tiramisu/multi.py | 25 +++++++++++++++++ .../tiramisu/no_namespace.py | 13 +++++++++ 11 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 tests/dictionaries/16_6exists_redefine_family/__init__.py create mode 100644 tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/00-base.yml create mode 100644 tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/01-base.yml create mode 100644 tests/dictionaries/16_6exists_redefine_family/makedict/after.json create mode 100644 tests/dictionaries/16_6exists_redefine_family/makedict/base.json create mode 100644 tests/dictionaries/16_6exists_redefine_family/makedict/before.json create mode 100644 tests/dictionaries/16_6exists_redefine_family/makedict/mandatory.json create mode 100644 tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py create mode 100644 tests/dictionaries/16_6exists_redefine_family/tiramisu/multi.py create mode 100644 tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py diff --git a/src/rougail/convert.py b/src/rougail/convert.py index ff5863fe6..e808243da 100644 --- a/src/rougail/convert.py +++ b/src/rougail/convert.py @@ -428,7 +428,7 @@ class ParserVariable: # FIXME: only for format 1.0 self.family_types = hint["type"].__args__ # pylint: disable=W0201 self.family_attrs = frozenset( # pylint: disable=W0201 - set(hint) - {"name", "path", "xmlfiles"} | {"redefine"} + set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"} ) self.family_calculations = self.search_calculation( # pylint: disable=W0201 hint @@ -590,6 +590,10 @@ class ParserVariable: return family_obj = {} subfamily_obj = {} + if version != '1.0': + exists = obj.pop("exists", None) + else: + exists = None force_to_attrs = list(self.list_attributes(obj)) for key, value in obj.items(): if key in force_to_attrs: @@ -601,9 +605,9 @@ class ParserVariable: if path in self.paths: # it's just for modify subfamily or subvariable, do not redefine if family_obj: - if not obj.pop("redefine", False): + if exists is None and not obj.pop("redefine", False): raise DictConsistencyError( - f'The family "{path}" already exists and it is not redefined', + _('The family "{0}" already exists and it is not redefined').format(path), 32, [filename], ) @@ -617,20 +621,21 @@ class ParserVariable: version, typ="family", ) - self.paths.add( - path, - self.paths[path].model_copy(update=obj), - family_is_dynamic, - parent_dynamic, - force=True, - ) + if exists in [None, True]: + self.paths.add( + path, + self.paths[path].model_copy(update=obj), + family_is_dynamic, + parent_dynamic, + force=True, + ) self.paths[path].xmlfiles.append(filename) force_not_first = True if self.paths[path].type == "dynamic": family_is_dynamic = True parent_dynamic = path else: - if "redefine" in obj and obj["redefine"]: + if exists is None and "redefine" in obj and obj["redefine"]: raise Exception( f'cannot redefine the inexisting family "{path}" in {filename}' ) diff --git a/tests/dictionaries/16_6exists_redefine_family/__init__.py b/tests/dictionaries/16_6exists_redefine_family/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/00-base.yml b/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/00-base.yml new file mode 100644 index 000000000..daadc02d2 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/00-base.yml @@ -0,0 +1,10 @@ +--- +version: '1.1' + +family1: # a family + + variable1: # a variable + +family2: # a second family + + variable2: # a second variable diff --git a/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/01-base.yml b/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/01-base.yml new file mode 100644 index 000000000..2e045ab0b --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/dictionaries/rougail/01-base.yml @@ -0,0 +1,16 @@ +--- +version: '1.1' + +family1: + exists: true + redefine: true + description: new description + +family2: + exists: false + description: new description + +family3: + exists: true + redefine: true + description: new description diff --git a/tests/dictionaries/16_6exists_redefine_family/makedict/after.json b/tests/dictionaries/16_6exists_redefine_family/makedict/after.json new file mode 100644 index 000000000..f9132c6be --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/makedict/after.json @@ -0,0 +1,10 @@ +{ + "rougail.family1.variable1": { + "owner": "default", + "value": null + }, + "rougail.family2.variable2": { + "owner": "default", + "value": null + } +} diff --git a/tests/dictionaries/16_6exists_redefine_family/makedict/base.json b/tests/dictionaries/16_6exists_redefine_family/makedict/base.json new file mode 100644 index 000000000..34aedc369 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/makedict/base.json @@ -0,0 +1,4 @@ +{ + "rougail.family1.variable1": null, + "rougail.family2.variable2": null +} diff --git a/tests/dictionaries/16_6exists_redefine_family/makedict/before.json b/tests/dictionaries/16_6exists_redefine_family/makedict/before.json new file mode 100644 index 000000000..f9132c6be --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/makedict/before.json @@ -0,0 +1,10 @@ +{ + "rougail.family1.variable1": { + "owner": "default", + "value": null + }, + "rougail.family2.variable2": { + "owner": "default", + "value": null + } +} diff --git a/tests/dictionaries/16_6exists_redefine_family/makedict/mandatory.json b/tests/dictionaries/16_6exists_redefine_family/makedict/mandatory.json new file mode 100644 index 000000000..99be4b389 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/makedict/mandatory.json @@ -0,0 +1 @@ +["rougail.family1.variable1", "rougail.family2.variable2"] \ No newline at end of file diff --git a/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py b/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py new file mode 100644 index 000000000..c65b32699 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py @@ -0,0 +1,18 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from re import compile as re_compile +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +try: + groups.namespace +except: + groups.addgroup('namespace') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +option_3 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_2 = OptionDescription(name="family1", doc="new description", children=[option_3], properties=frozenset({"basic"})) +option_5 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_4 = OptionDescription(name="family2", doc="a second family", children=[option_5], properties=frozenset({"basic"})) +optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2, optiondescription_4], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/16_6exists_redefine_family/tiramisu/multi.py b/tests/dictionaries/16_6exists_redefine_family/tiramisu/multi.py new file mode 100644 index 000000000..fb06a2668 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/tiramisu/multi.py @@ -0,0 +1,25 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from re import compile as re_compile +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +try: + groups.namespace +except: + groups.addgroup('namespace') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +option_4 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_3 = OptionDescription(name="family1", doc="new description", children=[option_4], properties=frozenset({"basic"})) +option_6 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_5 = OptionDescription(name="family2", doc="a second family", children=[option_6], properties=frozenset({"basic"})) +optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_3, optiondescription_5], properties=frozenset({"basic"})) +optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"})) +option_10 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_9 = OptionDescription(name="family1", doc="new description", children=[option_10], properties=frozenset({"basic"})) +option_12 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_11 = OptionDescription(name="family2", doc="a second family", children=[option_12], properties=frozenset({"basic"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_9, optiondescription_11], properties=frozenset({"basic"})) +optiondescription_7 = OptionDescription(name="2", doc="2", children=[optiondescription_8], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_7]) diff --git a/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py b/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py new file mode 100644 index 000000000..b43c16e92 --- /dev/null +++ b/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py @@ -0,0 +1,13 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from re import compile as re_compile +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +option_2 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_1 = OptionDescription(name="family1", doc="new description", children=[option_2], properties=frozenset({"basic"})) +option_4 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'}) +optiondescription_3 = OptionDescription(name="family2", doc="a second family", children=[option_4], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_3])