From 3b236c125e4ec8a9109cc9a13849b8a66621b521 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Tue, 6 Aug 2024 09:51:29 +0200 Subject: [PATCH] copy type/params and multi if default value is a variable calculation (#9 and #31) --- docs/fill.rst | 18 ++++++++++ src/rougail/annotator/family.py | 1 - src/rougail/annotator/variable.py | 34 +++++++++++++++++-- .../__init__.py | 0 .../dictionaries/rougail/00-base.yml | 13 +++++++ .../makedict/after.json | 10 ++++++ .../makedict/base.json | 4 +++ .../makedict/before.json | 10 ++++++ .../makedict/mandatory.json | 1 + .../tiramisu/base.py | 11 ++++++ .../tiramisu/multi.py | 16 +++++++++ .../tiramisu/no_namespace.py | 10 ++++++ tests/test_1_flattener.py | 2 ++ 13 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/__init__.py create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/dictionaries/rougail/00-base.yml create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/makedict/after.json create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/makedict/base.json create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/makedict/before.json create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/makedict/mandatory.json create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/base.py create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/multi.py create mode 100644 tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/no_namespace.py diff --git a/docs/fill.rst b/docs/fill.rst index af3ba0b54..d796bff25 100644 --- a/docs/fill.rst +++ b/docs/fill.rst @@ -394,6 +394,24 @@ Copy a variable in another: type: variable variable: _.my_variable +Copy the default value from a variable, means copy type, params and multi attribute too if not define in second variable. + +.. code-block:: yaml + + --- + version: 1.1 + my_variable: + multi: true + type: domainname + params: + allow_ip: true + my_calculated_variable: + default: + type: variable + variable: _.var1 + +Here my_calculated_variable is a domainname variable with parameter allow_ip=True and multi to true. + Copy one variable to another if the source has no `property` problem: .. code-block:: yaml diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index 6f327517d..4ce8d7602 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -30,7 +30,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from typing import Optional from rougail.i18n import _ from rougail.error import DictConsistencyError -from rougail.utils import get_realpath from rougail.annotator.variable import Walk from rougail.object_model import VariableCalculation diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index 474899c38..72f7f7b07 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from rougail.i18n import _ from rougail.error import DictConsistencyError -from rougail.object_model import Calculation +from rougail.object_model import Calculation, VariableCalculation from tiramisu.error import display_list @@ -82,11 +82,16 @@ class Annotator(Walk): # pylint: disable=R0903 def convert_variable(self): """convert variable""" + for variable in self.get_variables(): + if variable.version != "1.0": + if variable.type == "symlink": + continue + self._convert_variable_inference(variable) for variable in self.get_variables(): if variable.type == "symlink": continue if variable.version != "1.0": - self._convert_variable_inference(variable) + self._default_variable_copy_informations(variable) if variable.multi is None: variable.multi = False if variable.type is None: @@ -112,12 +117,35 @@ class Annotator(Walk): # pylint: disable=R0903 tested_value = variable.default variable.type = self.basic_types.get(type(tested_value), None) # variable has no multi attribute - if variable.multi is None: + if variable.multi is None and not (variable.type is None and isinstance(variable.default, VariableCalculation)): if variable.path in self.objectspace.leaders: variable.multi = True else: variable.multi = isinstance(variable.default, list) + def _default_variable_copy_informations( + self, + variable, + ) -> None: + # if a variable has a variable as default value, that means the type/params or multi should has same value + if variable.type is not None or not isinstance(variable.default, VariableCalculation): + return + # copy type and params + calculated_variable_path = variable.default.variable + calculated_variable, suffix = self.objectspace.paths.get_with_dynamic( + calculated_variable_path, variable.default.path_prefix, variable.path, variable.version, variable.namespace, variable.xmlfiles + ) + variable.type = calculated_variable.type + if variable.params is None and calculated_variable.params is not None: + variable.params = calculated_variable.params + # copy multi attribut + if variable.multi is None: + calculated_path = calculated_variable.path + if calculated_path in self.objectspace.leaders and variable.path in self.objectspace.followers and calculated_path.rsplit('.')[0] == variable.path.rsplit('.')[0]: + variable.multi = False + else: + variable.multi = calculated_variable.multi + def _convert_variable( self, variable: dict, diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/__init__.py b/tests/dictionaries/00_2default_calculated_variable_transitive/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/dictionaries/rougail/00-base.yml b/tests/dictionaries/00_2default_calculated_variable_transitive/dictionaries/rougail/00-base.yml new file mode 100644 index 000000000..81a09e501 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/dictionaries/rougail/00-base.yml @@ -0,0 +1,13 @@ +--- +version: 1.1 +var1: + description: a first variable + multi: true + type: domainname + params: + allow_ip: true +var2: + description: a second variable + default: + type: variable + variable: _.var1 diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/after.json b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/after.json new file mode 100644 index 000000000..2c76fb1fd --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/after.json @@ -0,0 +1,10 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [] + }, + "rougail.var2": { + "owner": "default", + "value": [] + } +} diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/base.json b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/base.json new file mode 100644 index 000000000..687890720 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/base.json @@ -0,0 +1,4 @@ +{ + "rougail.var1": [], + "rougail.var2": [] +} diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/before.json b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/before.json new file mode 100644 index 000000000..2c76fb1fd --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/before.json @@ -0,0 +1,10 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [] + }, + "rougail.var2": { + "owner": "default", + "value": [] + } +} diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/mandatory.json b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/mandatory.json new file mode 100644 index 000000000..8c67ac5f8 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/makedict/mandatory.json @@ -0,0 +1 @@ +["rougail.var1", "rougail.var2"] \ No newline at end of file diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/base.py b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/base.py new file mode 100644 index 000000000..50a814961 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/base.py @@ -0,0 +1,11 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +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 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory", "notempty"}), informations={'type': 'domainname'}) +option_3 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_2)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'domainname'}) +optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", children=[option_2, option_3], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/multi.py b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/multi.py new file mode 100644 index 000000000..87aa50795 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/multi.py @@ -0,0 +1,16 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +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_3 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory", "notempty"}), informations={'type': 'domainname'}) +option_4 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_3)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'domainname'}) +optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", children=[option_3, option_4], properties=frozenset({"basic"})) +optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"})) +option_7 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory", "notempty"}), informations={'type': 'domainname'}) +option_8 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_7)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'domainname'}) +optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", children=[option_7, option_8], properties=frozenset({"basic"})) +optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5]) diff --git a/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/no_namespace.py b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/no_namespace.py new file mode 100644 index 000000000..1b3e95c94 --- /dev/null +++ b/tests/dictionaries/00_2default_calculated_variable_transitive/tiramisu/no_namespace.py @@ -0,0 +1,10 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +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_1 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory", "notempty"}), informations={'type': 'domainname'}) +option_2 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_1)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'domainname'}) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2]) diff --git a/tests/test_1_flattener.py b/tests/test_1_flattener.py index 97cca2382..c91737020 100644 --- a/tests/test_1_flattener.py +++ b/tests/test_1_flattener.py @@ -46,8 +46,10 @@ test_multi = True #test_multi = False test_base = test_multi #test_base = True +#test_base = False test_no_namespace = test_multi #test_no_namespace = True +#test_no_namespace = False ORI_DIR = getcwd()