From 5a4bb343b0f48749922b0999a9d706fc971a1f11 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Mon, 12 May 2025 08:45:39 +0200 Subject: [PATCH] fix: black --- src/rougail/__init__.py | 4 +- src/rougail/annotator/family.py | 4 +- src/rougail/annotator/value.py | 8 +- src/rougail/annotator/variable.py | 55 +++- src/rougail/config.py | 11 +- src/rougail/convert.py | 20 +- src/rougail/object_model.py | 281 ++++++++++++++---- src/rougail/tiramisu.py | 34 ++- src/rougail/tiramisureflector.py | 11 +- src/rougail/user_datas.py | 203 ++++++++++--- src/rougail/utils.py | 34 ++- .../makedict/after.json | 1 + .../makedict/base.json | 1 + .../makedict/before.json | 1 + .../makedict/mandatory.json | 1 + .../makedict/read_write.json | 1 + .../makedict/after.json | 1 + .../makedict/base.json | 1 + .../makedict/before.json | 1 + .../makedict/mandatory.json | 1 + .../makedict/read_write.json | 1 + .../40_0leadership_reduce/makedict/after.json | 22 ++ .../40_0leadership_reduce/makedict/base.json | 16 + .../makedict/before.json | 22 ++ .../makedict/mandatory.json | 1 + .../makedict/read_write.json | 16 + .../40_0leadership_reduce/tiramisu/base.py | 17 ++ .../tiramisu/no_namespace.py | 12 + .../makedict/after.json | 2 +- .../makedict/before.json | 2 +- tests/test_2_makedict.py | 2 +- 31 files changed, 628 insertions(+), 159 deletions(-) create mode 100644 tests/dictionaries/00_0no_variable_default_version/makedict/after.json create mode 100644 tests/dictionaries/00_0no_variable_default_version/makedict/base.json create mode 100644 tests/dictionaries/00_0no_variable_default_version/makedict/before.json create mode 100644 tests/dictionaries/00_0no_variable_default_version/makedict/mandatory.json create mode 100644 tests/dictionaries/00_0no_variable_default_version/makedict/read_write.json create mode 100644 tests/dictionaries/00_0no_variable_remove_version/makedict/after.json create mode 100644 tests/dictionaries/00_0no_variable_remove_version/makedict/base.json create mode 100644 tests/dictionaries/00_0no_variable_remove_version/makedict/before.json create mode 100644 tests/dictionaries/00_0no_variable_remove_version/makedict/mandatory.json create mode 100644 tests/dictionaries/00_0no_variable_remove_version/makedict/read_write.json create mode 100644 tests/dictionaries/40_0leadership_reduce/makedict/after.json create mode 100644 tests/dictionaries/40_0leadership_reduce/makedict/base.json create mode 100644 tests/dictionaries/40_0leadership_reduce/makedict/before.json create mode 100644 tests/dictionaries/40_0leadership_reduce/makedict/mandatory.json create mode 100644 tests/dictionaries/40_0leadership_reduce/makedict/read_write.json create mode 100644 tests/dictionaries/40_0leadership_reduce/tiramisu/base.py create mode 100644 tests/dictionaries/40_0leadership_reduce/tiramisu/no_namespace.py diff --git a/src/rougail/__init__.py b/src/rougail/__init__.py index 1ab04f32d..e7b1fd50c 100644 --- a/src/rougail/__init__.py +++ b/src/rougail/__init__.py @@ -50,7 +50,9 @@ def tiramisu_display_name( comment = doc if doc and doc != kls.impl_getname() else "" if "{{ identifier }}" in comment and subconfig.identifiers: comment = comment.replace("{{ identifier }}", str(subconfig.identifiers[-1])) - path_in_description = values.get_information(context_subconfig, 'path_in_description', True) + path_in_description = values.get_information( + context_subconfig, "path_in_description", True + ) if path_in_description or not comment: comment = f" ({comment})" if comment else "" if path_in_description is False: diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index 0ca445744..7c1c8db4a 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -140,9 +140,7 @@ class Annotator(Walk): family.path ) self.objectspace.informations.add(family.path, "dynamic_variable", path) - self.objectspace.informations.add( - family.path, "ymlfiles", family.xmlfiles - ) + self.objectspace.informations.add(family.path, "ymlfiles", family.xmlfiles) def change_modes(self): """change the mode of variables""" diff --git a/src/rougail/annotator/value.py b/src/rougail/annotator/value.py index c231a3d82..b61c4b202 100644 --- a/src/rougail/annotator/value.py +++ b/src/rougail/annotator/value.py @@ -115,7 +115,9 @@ class Annotator(Walk): # pylint: disable=R0903 if isinstance(variable.choices, Calculation): continue if variable.choices is None: - msg = _('the variable "{0}" is a "choice" variable but don\'t have any choice').format(variable.path) + msg = _( + 'the variable "{0}" is a "choice" variable but don\'t have any choice' + ).format(variable.path) raise DictConsistencyError(msg, 19, variable.xmlfiles) if not variable.mandatory and not variable.multi: self.add_choice_nil(variable) @@ -132,5 +134,7 @@ class Annotator(Walk): # pylint: disable=R0903 if variable.type != "regexp": continue if variable.regexp is None: - msg = _('the variable "{0}" is a "regexp" variable but don\'t have any regexp').format(variable.path) + msg = _( + 'the variable "{0}" is a "regexp" variable but don\'t have any regexp' + ).format(variable.path) raise DictConsistencyError(msg, 66, variable.xmlfiles) diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index c9f480d60..55d4a5d89 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -83,13 +83,21 @@ class Annotator(Walk): # pylint: disable=R0903 continue path = variable.path if variable.type not in ["unix_user", "secret"]: - msg = _('only "unix_user" or "secret" variable type can have "secret_manager" attribute, but "{0}" has type "{1}"') - raise DictConsistencyError(msg.format(path, variable.type), 56, variable.xmlfiles) + msg = _( + 'only "unix_user" or "secret" variable type can have "secret_manager" attribute, but "{0}" has type "{1}"' + ) + raise DictConsistencyError( + msg.format(path, variable.type), 56, variable.xmlfiles + ) if variable.multi and path not in self.objectspace.leaders: - msg = _('the variable "{0}" has attribute "secret_manager" but is a multi variable') + msg = _( + 'the variable "{0}" has attribute "secret_manager" but is a multi variable' + ) raise DictConsistencyError(msg.format(path), 57, variable.xmlfiles) if variable.default is not None: - msg = _('the variable "{0}" has attribute "secret_manager" so must not have default value') + msg = _( + 'the variable "{0}" has attribute "secret_manager" so must not have default value' + ) raise DictConsistencyError(msg.format(path), 59, variable.xmlfiles) def convert_variable(self): @@ -106,9 +114,11 @@ class Annotator(Walk): # pylint: disable=R0903 self.objectspace.informations.add( variable.path, "ymlfiles", variable.xmlfiles ) - if variable.version != '1.0' and isinstance(variable.default, VariableCalculation): - calculated_variable_path, calculated_variable, identifier = variable.default.get_variable( - self.objectspace + if variable.version != "1.0" and isinstance( + variable.default, VariableCalculation + ): + calculated_variable_path, calculated_variable, identifier = ( + variable.default.get_variable(self.objectspace) ) else: calculated_variable = None @@ -144,15 +154,27 @@ class Annotator(Walk): # pylint: disable=R0903 return if variable.path in self.objectspace.leaders: variable.multi = self.objectspace.multis[variable.path] = True - elif variable.version != "1.0" and isinstance(variable.default, VariableCalculation): - calculated_variable_path, calculated_variable, identifier = variable.default.get_variable( - self.objectspace + elif variable.version != "1.0" and isinstance( + variable.default, VariableCalculation + ): + calculated_variable_path, calculated_variable, identifier = ( + variable.default.get_variable(self.objectspace) ) if calculated_variable is not None: if calculated_variable.multi is None: self._convert_variable_multi(calculated_variable) - variable.multi = calc_multi_for_type_variable(variable, calculated_variable_path, calculated_variable, self.objectspace)[1] - if calculated_variable.path in self.objectspace.followers and variable.mandatory is calculated_variable.mandatory is False and calculated_variable.path.rsplit(".", 1)[0] != variable.path.rsplit(".", 1)[0]: + variable.multi = calc_multi_for_type_variable( + variable, + calculated_variable_path, + calculated_variable, + self.objectspace, + )[1] + if ( + calculated_variable.path in self.objectspace.followers + and variable.mandatory is calculated_variable.mandatory is False + and calculated_variable.path.rsplit(".", 1)[0] + != variable.path.rsplit(".", 1)[0] + ): variable.empty = False else: variable.multi = isinstance(variable.default, list) @@ -163,15 +185,18 @@ class Annotator(Walk): # pylint: disable=R0903 calculated_variable, ) -> None: # if a variable has a variable as default value, that means the type/params or multi should has same value - if not isinstance(variable.default, VariableCalculation) or variable.type is not None: + if ( + not isinstance(variable.default, VariableCalculation) + or variable.type is not None + ): return # copy type and params variable.type = calculated_variable.type if variable.params is None and calculated_variable.params is not None: variable.params = calculated_variable.params - if variable.type == 'choice' and variable.choices is None: + if variable.type == "choice" and variable.choices is None: variable.choices = calculated_variable.choices - if variable.type == 'regexp' and variable.regexp is None: + if variable.type == "regexp" and variable.regexp is None: variable.regexp = calculated_variable.regexp def _convert_variable( diff --git a/src/rougail/config.py b/src/rougail/config.py index d11d4ae53..f77989abc 100644 --- a/src/rougail/config.py +++ b/src/rougail/config.py @@ -381,8 +381,8 @@ secret_manager: rougail_process += """ alternative_name: {NAME[0]} """.format( - NAME=normalize_family(process), - ) + NAME=normalize_family(process), + ) rougail_process += """ choices: """ @@ -409,8 +409,9 @@ secret_manager: rougail_process += """ {% if _.output is not propertyerror and _.output == 'NAME' %} Cannot load structural for NAME output {% endif %} -""".replace("NAME", hidden_output - ) +""".replace( + "NAME", hidden_output + ) elif process == "user data": rougail_process += """ multi: true mandatory: false""" @@ -475,7 +476,7 @@ default_params: mandatory: false default: {value} """ -# print(rougail_process) + # print(rougail_process) rougail_options += rougail_process convert = FakeRougailConvert(add_extra_options) convert.init() diff --git a/src/rougail/convert.py b/src/rougail/convert.py index ff78a4023..2d0509fbe 100644 --- a/src/rougail/convert.py +++ b/src/rougail/convert.py @@ -188,7 +188,7 @@ class ParserVariable: self.output = None self.tiramisu_cache = rougailconfig["tiramisu_cache"] self.load_unexist_redefine = rougailconfig["load_unexist_redefine"] - self.secret_pattern = rougailconfig['secret_manager.pattern'] + self.secret_pattern = rougailconfig["secret_manager.pattern"] # change default initkwargs in CONVERT_OPTION if hasattr(rougailconfig, "config"): for sub_od in rougailconfig.config.option("default_params"): @@ -505,7 +505,7 @@ class ParserVariable: for key, value in obj.items(): if not isinstance(key, str): raise DictConsistencyError( - f'a key is not in string format: {key}', + f"a key is not in string format: {key}", 103, [filename], ) @@ -648,7 +648,8 @@ class ParserVariable: raise DictConsistencyError( f'"{path}" is not a valid variable, there are additional ' f'attributes: "{", ".join(extra_attrs)}"', - 65, [filename] + 65, + [filename], ) self.parse_parameters( path, @@ -687,9 +688,7 @@ class ParserVariable: msg = f'cannot redefine the inexisting variable "{path}"' raise DictConsistencyError(msg, 46, [filename]) obj["path"] = path - self.add_variable( - name, obj, filename, family_is_dynamic, parent_dynamic - ) + self.add_variable(name, obj, filename, family_is_dynamic, parent_dynamic) if family_is_leadership: if first_variable: self.leaders.append(path) @@ -803,10 +802,11 @@ class ParserVariable: 64, [filename], ) - secret_manager = {"type": "jinja", - "jinja": self.secret_pattern, - "params": obj["secret_manager"], - } + secret_manager = { + "type": "jinja", + "jinja": self.secret_pattern, + "params": obj["secret_manager"], + } self.set_calculation( obj, "secret_manager", diff --git a/src/rougail/object_model.py b/src/rougail/object_model.py index 063c46464..db4779b9d 100644 --- a/src/rougail/object_model.py +++ b/src/rougail/object_model.py @@ -151,7 +151,9 @@ class Param(BaseModel): ) -> None: super().__init__(**kwargs) - def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict: + def to_param( + self, attribute_name, objectspace, path, version, namespace, xmlfiles + ) -> dict: return self.model_dump() @@ -167,8 +169,12 @@ class VariableParam(Param): whole: bool = False optional: bool = False - def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict: - param = super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles) + def to_param( + self, attribute_name, objectspace, path, version, namespace, xmlfiles + ) -> dict: + param = super().to_param( + attribute_name, objectspace, path, version, namespace, xmlfiles + ) variable, identifier = objectspace.paths.get_with_dynamic( param["variable"], path, @@ -178,14 +184,20 @@ class VariableParam(Param): ) if not variable: if not param.get("optional"): - msg = _('cannot find variable "{0}" defined in attribute "{1}" for "{2}"').format(param["variable"], attribute_name, path) + msg = _( + 'cannot find variable "{0}" defined in attribute "{1}" for "{2}"' + ).format(param["variable"], attribute_name, path) raise DictConsistencyError(msg, 22, xmlfiles) return None if isinstance(variable, objectspace.family): - msg = _('the variable "{0}" is in fact a family in attribute "{1}" for "{2}"').format(variable["name"], attribute_name, path) + msg = _( + 'the variable "{0}" is in fact a family in attribute "{1}" for "{2}"' + ).format(variable["name"], attribute_name, path) raise DictConsistencyError(msg, 42, xmlfiles) if not isinstance(variable, objectspace.variable): - msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(variable, attribute_name, path) + msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format( + variable, attribute_name, path + ) raise DictConsistencyError(msg, 44, xmlfiles) param["variable"] = variable if identifier: @@ -202,7 +214,9 @@ class IdentifierParam(Param): **kwargs, ) -> None: if not kwargs["family_is_dynamic"]: - msg = _('identifier parameter for "{0}" in "{1}" cannot be set none dynamic family').format(kwargs["attribute"], kwargs["path"]) + msg = _( + 'identifier parameter for "{0}" in "{1}" cannot be set none dynamic family' + ).format(kwargs["attribute"], kwargs["path"]) raise DictConsistencyError(msg, 10, kwargs["xmlfiles"]) super().__init__(**kwargs) @@ -212,8 +226,12 @@ class InformationParam(Param): information: str variable: Optional[str] = None - def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict: - param = super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles) + def to_param( + self, attribute_name, objectspace, path, version, namespace, xmlfiles + ) -> dict: + param = super().to_param( + attribute_name, objectspace, path, version, namespace, xmlfiles + ) if not param["variable"]: del param["variable"] return param @@ -225,10 +243,14 @@ class InformationParam(Param): xmlfiles, ) if not variable: - msg = _('cannot find variable "{0}" defined in "{1}" for "{2}"').format(param["variable"], attribute_name, path) + msg = _('cannot find variable "{0}" defined in "{1}" for "{2}"').format( + param["variable"], attribute_name, path + ) raise DictConsistencyError(msg, 14, xmlfiles) if identifier: - msg = _('variable "{0}" defined in "{1}" for "{2}" is a dynamic variable').format(param["variable"], attribute_name, path) + msg = _( + 'variable "{0}" defined in "{1}" for "{2}" is a dynamic variable' + ).format(param["variable"], attribute_name, path) raise DictConsistencyError(msg, 15, xmlfiles) param["variable"] = variable return param @@ -237,25 +259,37 @@ class InformationParam(Param): class IndexParam(Param): type: str - def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict: - if path not in objectspace.followers and (attribute_name != 'validators' or path not in objectspace.multis): - msg = _('the variable "{0}" is not a follower, so cannot have index type for param in "{1}"').format(path, attribute) + def to_param( + self, attribute_name, objectspace, path, version, namespace, xmlfiles + ) -> dict: + if path not in objectspace.followers and ( + attribute_name != "validators" or path not in objectspace.multis + ): + msg = _( + 'the variable "{0}" is not a follower, so cannot have index type for param in "{1}"' + ).format(path, attribute) raise DictConsistencyError(msg, 25, xmlfiles) - return super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles) + return super().to_param( + attribute_name, objectspace, path, version, namespace, xmlfiles + ) class NamespaceParam(Param): type: str namespace: str - def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict: + def to_param( + self, attribute_name, objectspace, path, version, namespace, xmlfiles + ) -> dict: namespace = self.namespace if namespace: namespace = objectspace.paths[namespace].description - return {'type': 'any', - 'value': namespace, - 'key': self.key, - } + return { + "type": "any", + "value": namespace, + "key": self.key, + } + PARAM_TYPES = { "any": AnyParam, @@ -287,7 +321,14 @@ class Calculation(BaseModel): path = self.ori_path params = {} for param_obj in self.params: - param = param_obj.to_param(self.attribute_name, objectspace, path, self.version, self.namespace, self.xmlfiles) + param = param_obj.to_param( + self.attribute_name, + objectspace, + path, + self.version, + self.namespace, + self.xmlfiles, + ) if param is None: continue params[param.pop("key")] = param @@ -454,13 +495,17 @@ class _VariableCalculation(Calculation): path = self.path else: path = self.ori_path - if self.version != "1.0" and objectspace.paths.regexp_relative.search(self.variable): + if self.version != "1.0" and objectspace.paths.regexp_relative.search( + self.variable + ): variable_full_path = objectspace.paths.get_full_path( self.variable, path, ) elif self.version == "1.0" and "{{ suffix }}" in self.variable: - variable_full_path = self.variable.replace("{{ suffix }}", "{{ identifier }}") + variable_full_path = self.variable.replace( + "{{ suffix }}", "{{ identifier }}" + ) else: variable_full_path = self.variable variable, identifier = objectspace.paths.get_with_dynamic( @@ -472,10 +517,14 @@ class _VariableCalculation(Calculation): ) if variable and not isinstance(variable, objectspace.variable): if isinstance(variable, objectspace.family): - msg = _('a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family').format(variable_full_path, self.attribute_name, self.path) + msg = _( + 'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family' + ).format(variable_full_path, self.attribute_name, self.path) raise DictConsistencyError(msg, 47, self.xmlfiles) else: - msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(variable, self.attribute_name, self.path) + msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format( + variable, self.attribute_name, self.path + ) raise DictConsistencyError(msg, 48, self.xmlfiles) return variable_full_path, variable, identifier @@ -492,7 +541,9 @@ class _VariableCalculation(Calculation): path = self.path else: path = self.ori_path - msg = _('variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"').format(path, self.attribute_name, self.variable) + msg = _( + 'variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"' + ).format(path, self.attribute_name, self.variable) raise DictConsistencyError(msg, 88, self.xmlfiles) return {None: [["example"]]} param = { @@ -509,7 +560,9 @@ class _VariableCalculation(Calculation): params["__default_value"] = self.default_values if self.allow_none: params["allow_none"] = True - self.check_multi(objectspace, variable_in_calculation_path, variable_in_calculation) + self.check_multi( + objectspace, variable_in_calculation_path, variable_in_calculation + ) if self.path in objectspace.followers: multi = objectspace.multis[self.path] == "submulti" else: @@ -518,51 +571,123 @@ class _VariableCalculation(Calculation): params["__internal_multi"] = True return params - def check_multi(self, objectspace, variable_in_calculation_path, variable_in_calculation): + def check_multi( + self, objectspace, variable_in_calculation_path, variable_in_calculation + ): if self.ori_path is None: path = self.path else: path = self.ori_path local_variable = objectspace.paths[path] - local_variable_multi, variable_in_calculation_multi = calc_multi_for_type_variable(local_variable, variable_in_calculation_path, variable_in_calculation, objectspace) + local_variable_multi, variable_in_calculation_multi = ( + calc_multi_for_type_variable( + local_variable, + variable_in_calculation_path, + variable_in_calculation, + objectspace, + ) + ) if self.attribute_name == "default": - if variable_in_calculation_multi == 'submulti': + if variable_in_calculation_multi == "submulti": if objectspace.paths.is_dynamic(variable_in_calculation.path): - msg = _('the variable "{0}" has an invalid "{1}" the variable "{2}" is in a sub dynamic option').format(local_variable.path, self.attribute_name, variable_in_calculation.path) + msg = _( + 'the variable "{0}" has an invalid "{1}" the variable "{2}" is in a sub dynamic option' + ).format( + local_variable.path, + self.attribute_name, + variable_in_calculation.path, + ) raise DictConsistencyError(msg, 69, self.xmlfiles) else: - msg = _('the leader "{0}" has an invalid "{1}" the follower "{2}" is a multi').format(local_variable.path, self.attribute_name, variable_in_calculation.path) + msg = _( + 'the leader "{0}" has an invalid "{1}" the follower "{2}" is a multi' + ).format( + local_variable.path, + self.attribute_name, + variable_in_calculation.path, + ) raise DictConsistencyError(msg, 74, self.xmlfiles) if not self.inside_list: if local_variable_multi != variable_in_calculation_multi: if local_variable_multi: - self.check_variable_in_calculation_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi) - self.check_variable_in_calculation_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi) + self.check_variable_in_calculation_multi( + local_variable.path, + variable_in_calculation_path, + variable_in_calculation_multi, + ) + self.check_variable_in_calculation_not_multi( + local_variable.path, + variable_in_calculation_path, + variable_in_calculation_multi, + ) else: - self.check_variable_in_calculation_in_list_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi) + self.check_variable_in_calculation_in_list_not_multi( + local_variable.path, + variable_in_calculation_path, + variable_in_calculation_multi, + ) elif self.attribute_name in ["choices", "dynamic"]: # calculated variable must be a multi if not self.inside_list: - self.check_variable_in_calculation_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi) + self.check_variable_in_calculation_multi( + local_variable.path, + variable_in_calculation_path, + variable_in_calculation_multi, + ) else: - self.check_variable_in_calculation_in_list_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi) + self.check_variable_in_calculation_in_list_not_multi( + local_variable.path, + variable_in_calculation_path, + variable_in_calculation_multi, + ) elif variable_in_calculation_multi is True: - msg = _('the variable "{0}" has an invalid attribute "{1}", the variable "{2}" must not be multi').format(local_variable.path, self.attribute_name, variable_in_calculation_path) + msg = _( + 'the variable "{0}" has an invalid attribute "{1}", the variable "{2}" must not be multi' + ).format( + local_variable.path, self.attribute_name, variable_in_calculation_path + ) raise DictConsistencyError(msg, 23, self.xmlfiles) - def check_variable_in_calculation_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi): + def check_variable_in_calculation_multi( + self, + local_variable_path, + variable_in_calculation_path, + variable_in_calculation_multi, + ): if variable_in_calculation_multi is False: - msg = _('the variable "{0}" has an invalid attribute "{1}", the variable must not be a multi or the variable "{2}" must be multi').format(local_variable_path, self.attribute_name, variable_in_calculation_path) + msg = _( + 'the variable "{0}" has an invalid attribute "{1}", the variable must not be a multi or the variable "{2}" must be multi' + ).format( + local_variable_path, self.attribute_name, variable_in_calculation_path + ) raise DictConsistencyError(msg, 20, self.xmlfiles) - def check_variable_in_calculation_not_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi): + def check_variable_in_calculation_not_multi( + self, + local_variable_path, + variable_in_calculation_path, + variable_in_calculation_multi, + ): if variable_in_calculation_multi is True: - msg = _('the variable "{0}" has an invalid attribute "{1}", the variable must be a multi or the variable "{2}" must not be multi').format(local_variable_path, self.attribute_name, variable_in_calculation_path) + msg = _( + 'the variable "{0}" has an invalid attribute "{1}", the variable must be a multi or the variable "{2}" must not be multi' + ).format( + local_variable_path, self.attribute_name, variable_in_calculation_path + ) raise DictConsistencyError(msg, 21, self.xmlfiles) - def check_variable_in_calculation_in_list_not_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi): + def check_variable_in_calculation_in_list_not_multi( + self, + local_variable_path, + variable_in_calculation_path, + variable_in_calculation_multi, + ): if variable_in_calculation_multi is True: - msg = _('the variable "{0}" has an invalid attribute "{1}", the variable "{2}" is multi but is inside a list').format(local_variable_path, self.attribute_name, variable_in_calculation_path) + msg = _( + 'the variable "{0}" has an invalid attribute "{1}", the variable "{2}" is multi but is inside a list' + ).format( + local_variable_path, self.attribute_name, variable_in_calculation_path + ) raise DictConsistencyError(msg, 18, self.xmlfiles) @@ -576,9 +701,15 @@ class VariableCalculation(_VariableCalculation): objectspace, ) -> dict: if self.attribute_name != "default" and self.optional: - msg = _('"{0}" attribut shall not have an "optional" attribute for variable "{1}"').format(self.attribute_name, self.variable) + msg = _( + '"{0}" attribut shall not have an "optional" attribute for variable "{1}"' + ).format(self.attribute_name, self.variable) raise DictConsistencyError(msg, 33, self.xmlfiles) - variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier = self.get_variable(objectspace) + ( + variable_in_calculation_path, + variable_in_calculation, + variable_in_calculation_identifier, + ) = self.get_variable(objectspace) if ( not variable_in_calculation and self.optional @@ -587,8 +718,12 @@ class VariableCalculation(_VariableCalculation): raise VariableCalculationDependencyError() if variable_in_calculation and self.attribute_name == "default": local_variable = objectspace.paths[self.path] - if CONVERT_OPTION.get(local_variable.type, {}).get("func", str) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str): - msg = _('variable "{0}" has a default value calculated with "{1}" which has incompatible type').format(self.path, self.variable) + if CONVERT_OPTION.get(local_variable.type, {}).get( + "func", str + ) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str): + msg = _( + 'variable "{0}" has a default value calculated with "{1}" which has incompatible type' + ).format(self.path, self.variable) raise DictConsistencyError(msg, 67, self.xmlfiles) params = self.get_params( objectspace, @@ -613,29 +748,41 @@ class VariablePropertyCalculation(_VariableCalculation): self, objectspace, ) -> dict: - variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier = self.get_variable(objectspace) + ( + variable_in_calculation_path, + variable_in_calculation, + variable_in_calculation_identifier, + ) = self.get_variable(objectspace) params = self.get_params( objectspace, variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier, ) - if objectspace.force_optional and (not params[None] or "variable" not in params[None][0]): + if objectspace.force_optional and ( + not params[None] or "variable" not in params[None][0] + ): params = {None: [None, None, False]} else: variable = params[None][0]["variable"] if self.when is not undefined: if self.version == "1.0": - msg = _('"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"').format(self.attribute_name, self.path) + msg = _( + '"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"' + ).format(self.attribute_name, self.path) raise DictConsistencyError(msg, 103, variable.xmlfiles) if self.when_not is not undefined: - msg = _('the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together').format(self.path, self.attribute_name) + msg = _( + 'the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together' + ).format(self.path, self.attribute_name) raise DictConsistencyError(msg, 31, variable.xmlfiles) when = self.when inverse = False elif self.when_not is not undefined: if self.version == "1.0": - msg = _('"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"').format(self.attribute_name, self.path) + msg = _( + '"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"' + ).format(self.attribute_name, self.path) raise DictConsistencyError(msg, 104, variable.xmlfiles) when = self.when_not inverse = True @@ -650,7 +797,7 @@ class VariablePropertyCalculation(_VariableCalculation): params["when"] = when params["inverse"] = inverse params[None].insert(0, self.attribute_name) - func = 'variable_to_property' + func = "variable_to_property" return { "function": func, "params": params, @@ -690,10 +837,14 @@ class InformationCalculation(Calculation): ) if variable is None: if not objectspace.force_optional: - msg = _('cannot find variable "{0}" for the information "{1}" when calculating "{2}"').format(self.variable, self.information, self.attribute_name) + msg = _( + 'cannot find variable "{0}" for the information "{1}" when calculating "{2}"' + ).format(self.variable, self.information, self.attribute_name) raise DictConsistencyError(msg, 40, variable.xmlfiles) if identifier is not None: - msg = _('identifier not allowed for the information "{0}" when calculating "{1}"').format(self.information, self.attribute_name) + msg = _( + 'identifier not allowed for the information "{0}" when calculating "{1}"' + ).format(self.information, self.attribute_name) raise DictConsistencyError(msg, 41, variable.xmlfiles) if variable: params[None][0]["variable"] = variable @@ -744,11 +895,15 @@ class IdentifierPropertyCalculation(_IdentifierCalculation): objectspace, ) -> dict: if self.version == "1.0": - msg = _('"when" is not allowed in format version 1.0 for attribute "{0}"').format(self.attribute_name) + msg = _( + '"when" is not allowed in format version 1.0 for attribute "{0}"' + ).format(self.attribute_name) raise DictConsistencyError(msg, 105, variable.xmlfiles) if self.when is not undefined: if self.when_not is not undefined: - msg = _('the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together').format(self.attribute_name) + msg = _( + 'the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together' + ).format(self.attribute_name) raise DictConsistencyError(msg, 35, variable.xmlfiles) when = self.when inverse = False @@ -756,7 +911,9 @@ class IdentifierPropertyCalculation(_IdentifierCalculation): when = self.when_not inverse = True else: - msg = _('the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together').format(self.attribute_name) + msg = _( + 'the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together' + ).format(self.attribute_name) raise DictConsistencyError params = { None: [self.attribute_name, self.get_identifier()], @@ -779,7 +936,9 @@ class IndexCalculation(Calculation): objectspace, ) -> dict: if self.path not in objectspace.followers: - msg = _('the variable "{0}" is not a follower, so cannot have index type for "{1}"').format(self.path, self.attribute_name) + msg = _( + 'the variable "{0}" is not a follower, so cannot have index type for "{1}"' + ).format(self.path, self.attribute_name) raise DictConsistencyError(msg, 60, self.xmlfiles) return { "function": "calc_value", @@ -809,7 +968,7 @@ CALCULATION_TYPES = { "information": InformationCalculation, "variable": VariableCalculation, "identifier": IdentifierCalculation, -# FOR VERSION 1.0 + # FOR VERSION 1.0 "suffix": IdentifierCalculation, "index": IndexCalculation, "namespace": NamespaceCalculation, diff --git a/src/rougail/tiramisu.py b/src/rougail/tiramisu.py index 61531e18c..29f68fb93 100644 --- a/src/rougail/tiramisu.py +++ b/src/rougail/tiramisu.py @@ -37,17 +37,29 @@ from jinja2.sandbox import SandboxedEnvironment from rougail.object_model import CONVERT_OPTION from rougail.error import display_xmlfiles from tiramisu import DynOptionDescription, calc_value, function_waiting_for_error -from tiramisu.error import ValueWarning, ConfigError, PropertiesOptionError, CancelParam, errors +from tiramisu.error import ( + ValueWarning, + ConfigError, + PropertiesOptionError, + CancelParam, + errors, +) from .utils import normalize_family from .i18n import _ ori_raise_carry_out_calculation_error = errors.raise_carry_out_calculation_error + + def raise_carry_out_calculation_error(subconfig, *args, **kwargs): try: ori_raise_carry_out_calculation_error(subconfig, *args, **kwargs) except ConfigError as err: - ymlfiles = subconfig.config_bag.context.get_values().get_information(subconfig, 'ymlfiles', []) - raise ConfigError(_('{0} in {1}').format(err, display_xmlfiles(ymlfiles))) + ymlfiles = subconfig.config_bag.context.get_values().get_information( + subconfig, "ymlfiles", [] + ) + raise ConfigError(_("{0} in {1}").format(err, display_xmlfiles(ymlfiles))) + + errors.raise_carry_out_calculation_error = raise_carry_out_calculation_error @@ -124,7 +136,7 @@ def kw_to_string(kw, root=None): if root is None: path = name else: - path = root + '.' + name + path = root + "." + name if isinstance(data, dict): yield from kw_to_string(data, root=path) else: @@ -172,11 +184,21 @@ def jinja_to_function( except Exception as err: kw_str = ", ".join(kw_to_string(kw)) raise ConfigError( - _('cannot calculating "{0}" attribute for variable "{1}" in {2} with parameters "{3}": {4}').format(__internal_attribute, __internal_variable, display_xmlfiles(__internal_files), kw_str, err) + _( + 'cannot calculating "{0}" attribute for variable "{1}" in {2} with parameters "{3}": {4}' + ).format( + __internal_attribute, + __internal_variable, + display_xmlfiles(__internal_files), + kw_str, + err, + ) ) from err convert = CONVERT_OPTION[__internal_type].get("func", str) if __internal_multi: - values = [convert(val.strip()) for val in values.split("\n") if val.strip() != ""] + values = [ + convert(val.strip()) for val in values.split("\n") if val.strip() != "" + ] if not values and __default_value is not None: return __default_value return values diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py index de65ee040..57434c60e 100644 --- a/src/rougail/tiramisureflector.py +++ b/src/rougail/tiramisureflector.py @@ -290,9 +290,10 @@ class Common: ): """Populate variable parameters""" if not isinstance(param, dict): - param = {"type": "any", - "value": param, - } + param = { + "type": "any", + "value": param, + } if param["type"] == "value": return f"ParamValue({param['value']})" if param["type"] == "information": @@ -331,9 +332,7 @@ class Common: return f'ParamInformation("{param["information"]}", {default}, option={option_name})' else: # if we want to get information from the a parent family - information = ( - f'ParamInformation("{param["information"]}", {default})' - ) + information = f'ParamInformation("{param["information"]}", {default})' information_name = self.tiramisu.get_information_name() self.tiramisu.text["option"].append( f"{information_name} = {information}" diff --git a/src/rougail/user_datas.py b/src/rougail/user_datas.py index 7df24661f..ccd67503c 100644 --- a/src/rougail/user_datas.py +++ b/src/rougail/user_datas.py @@ -26,6 +26,7 @@ from rougail.utils import normalize_family, undefined from tiramisu import Calculation from tiramisu.error import ( PropertiesOptionError, + AttributeOptionError, LeadershipError, ConfigError, CancelParam, @@ -44,6 +45,7 @@ class UserDatas: self.values = {} self.errors = [] self.warnings = [] + self.show_secrets = False self._populate_values(user_datas) self._auto_configure_dynamics() self._populate_config() @@ -113,7 +115,9 @@ class UserDatas: continue identifier = self._get_identifier(tconfig.name(), name) if identifier != normalize_family(identifier): - msg = _('cannot load variable path "{0}", the identifier "{1}" is not valid in {2}').format(path, identifier, data["source"]) + msg = _( + 'cannot load variable path "{0}", the identifier "{1}" is not valid in {2}' + ).format(path, identifier, data["source"]) self.warnings.append(msg) continue if identifier is None: @@ -155,6 +159,27 @@ class UserDatas: cache[current_path] = config, identifier break + def convert_value(self, path, option, options, value): + # converted value + needs_convert = options.get("needs_convert", False) + if option.ismulti(): + if options.get("multi_separator") and not isinstance(value, list): + value = value.split(options["multi_separator"]) + self.values[path]["values"] = value + if option.issubmulti(): + value = [[val] for val in value] + if needs_convert: + if option.issubmulti(): + for idx, val in enumerate(value): + value[idx] = [convert_value(option, v) for v in val] + else: + value = [convert_value(option, val) for val in value] + self.values[path]["values"] = value + self.values[path]["options"]["needs_convert"] = False + elif needs_convert: + value = convert_value(option, value) + return value + def _populate_config(self): while self.values: value_is_set = False @@ -173,33 +198,25 @@ class UserDatas: ).format(path, self.values[path]["source"]) ) continue - value = self.values[path]["values"] - needs_convert = options.get("needs_convert", False) + value = self.convert_value( + path, option, options, self.values[path]["values"] + ) - # converted value - if option.ismulti(): - if options.get("multi_separator") and not isinstance(value, list): - value = value.split(options["multi_separator"]) - self.values[path]["values"] = value - if option.issubmulti(): - value = [[val] for val in value] - if needs_convert: - if option.issubmulti(): - for idx, val in enumerate(value): - value[idx] = [convert_value(option, v) for v in val] - else: - value = [convert_value(option, val) for val in value] - self.values[path]["values"] = value - self.values[path]["options"]["needs_convert"] = False - elif needs_convert: - value = convert_value(option, value) index = option.index() if index is not None: if not isinstance(value, list) or index >= len(value): continue value = value[index] + if option.isleader(): + len_leader = len(option.value.get()) + if len_leader: + for idx in range(len_leader - 1, -1, -1): + option.value.pop(idx) try: option.value.set(value) + option.information.set( + "loaded_from", _("loaded from {0}").format(options["source"]) + ) value_is_set = True # value is correctly set, remove variable to the set if index is not None: @@ -224,33 +241,144 @@ class UserDatas: return None return finded[0] + def _display_value(self, option, value): + if not self.show_secrets and option.type() == "password": + return "*" * 10 + return value + def _populate_error_warnings(self): # we don't find variable, apply value just to get error or warning messages - for path, data in self.values.items(): + for path, options in self.values.items(): + value = options["values"] + option = self.config.option(path) try: - option = self.config.option(path) - value = data["values"] if option.isoptiondescription(): if value: self.warnings.append( - _('the variable "{0}" is a family, so cannot set the value "{1}" in {2}').format( - option.path(), - value, - data["source"], + _( + 'cannot set the value "{0}" to the family {1}, it will be ignored when loading from {2}' + ).format( + self._display_value(option, value), + option.description(with_quote=True), + options["source"], ) ) continue - if option.isfollower(): - for index, val in enumerate(value): + except AttributeOptionError as err: + if err.code == "option-not-found": + self.warnings.append( + _( + 'variable or family "{0}" does not exist, it will be ignored when loading from {1}' + ).format(err.path, options["source"]) + ) + elif err.code == "option-dynamic": + self.warnings.append( + _( + '"{0}" is the name of a dynamic family, it will be ignored when loading from {1}' + ).format(option.description(with_quote=True), options["source"]) + ) + else: + self.warnings.append( + _("{0} loaded from {1}").format(err, options["source"]) + ) + continue + value = self.convert_value( + path, option, self.values[path].get("options", {}), value + ) + if option.isfollower(): + indexes = range(len(value)) + else: + indexes = [None] + for index in indexes: + try: + if option.isfollower(): + val = value[index] if val is undefined or isinstance(val, CancelParam): continue self.config.option(path, index).value.set(val) - else: - option.value.set(value) - except AttributeError as err: - self.warnings.append(_('{0} loaded from {1}').format(err, data["source"])) - except (ValueError, LeadershipError, PropertiesOptionError) as err: - self.warnings.append(_('{0} in {1}').format(err, data["source"])) + else: + option.value.set(value) + except PropertiesOptionError as err: + if err.code == "property-error": + properties = err.display_properties( + force_property=True, add_quote=False + ) + err_path = err._subconfig.path + display_name = option.description(with_quote=True) + if index is not None: + if path == err_path: + self.warnings.append( + _( + 'variable {0} at index "{1}" is {2}, it will be ignored when loading from {3}' + ).format( + display_name, + index, + properties, + options["source"], + ) + ) + else: + self.warnings.append( + _( + 'family {0} is {1}, {2} at index "{3}" will be ignored when loading from {4}' + ).format( + err._name, + properties, + display_name, + index, + options["source"], + ) + ) + else: + if path == err_path: + self.warnings.append( + _( + "variable {0} is {1}, it will be ignored when loading from {2}" + ).format( + display_name, properties, options["source"] + ) + ) + else: + self.warnings.append( + _( + "family {0} is {1}, {2} will be ignored when loading from {3}" + ).format( + err._name, + properties, + display_name, + options["source"], + ) + ) + else: + self.warnings.append( + _("{0} in {1}").format(err, options["source"]) + ) + except LeadershipError as err: + self.warnings.append(_("{0} in {1}").format(err, options["source"])) + except ValueError as err: + err.prefix = "" + if index is not None: + self.warnings.append( + _( + 'the value "{0}" is invalid for {1} at index "{2}", {3}, it will be ignored when loading from {4}' + ).format( + self._display_value(option, value), + option.description(with_quote=True), + err, + options["source"], + ) + ) + else: + self.warnings.append( + _( + 'the value "{0}" is invalid for {1}, {2}, it will be ignored when loading from {3}' + ).format( + self._display_value(option, value), + option.description(with_quote=True), + err, + options["source"], + ) + ) def convert_value(option, value): @@ -265,5 +393,8 @@ def convert_value(option, value): value = int(value) func = CONVERT_OPTION.get(option_type, {}).get("func") if func: - return func(value) + try: + return func(value) + except: + pass return value diff --git a/src/rougail/utils.py b/src/rougail/utils.py index 3db019afc..71140e64d 100644 --- a/src/rougail/utils.py +++ b/src/rougail/utils.py @@ -162,7 +162,13 @@ def get_jinja_variable_to_param( for variable_path, data in founded_variables.items(): yield data[1], data[0], variable_path -def calc_multi_for_type_variable(local_variable: 'Variable', variable_in_calculation_path: str, variable_in_calculation: 'Variable', objectspace: 'RougailConvert') -> Union[bool, str]: + +def calc_multi_for_type_variable( + local_variable: "Variable", + variable_in_calculation_path: str, + variable_in_calculation: "Variable", + objectspace: "RougailConvert", +) -> Union[bool, str]: variable_in_calculation_multi = variable_in_calculation.multi if local_variable.path in objectspace.families: # it's a family @@ -171,33 +177,39 @@ def calc_multi_for_type_variable(local_variable: 'Variable', variable_in_calcula local_variable_multi = local_variable.multi # variable is a leader if variable_in_calculation.path in objectspace.leaders: - local_variable_parent = local_variable.path.rsplit('.', 1)[0] - variable_in_calculation_parent = variable_in_calculation.path.rsplit('.', 1)[0] + local_variable_parent = local_variable.path.rsplit(".", 1)[0] + variable_in_calculation_parent = variable_in_calculation.path.rsplit( + ".", 1 + )[0] if local_variable_parent == variable_in_calculation_parent: variable_in_calculation_multi = False # variable is a follower elif variable_in_calculation.path in objectspace.followers: - local_variable_parent = local_variable.path.rsplit('.', 1)[0] - variable_in_calculation_parent = variable_in_calculation.path.rsplit('.', 1)[0] + local_variable_parent = local_variable.path.rsplit(".", 1)[0] + variable_in_calculation_parent = variable_in_calculation.path.rsplit( + ".", 1 + )[0] if local_variable_parent != variable_in_calculation_parent: if variable_in_calculation_multi: - variable_in_calculation_multi = 'submulti' + variable_in_calculation_multi = "submulti" else: variable_in_calculation_multi = True # variable is in a dynamic family if objectspace.paths.is_dynamic(variable_in_calculation.path): - common_path = get_common_path(local_variable.path, variable_in_calculation_path) + common_path = get_common_path( + local_variable.path, variable_in_calculation_path + ) common_variable_path = variable_in_calculation_path if common_path: - common_variable_path = common_variable_path[len(common_path) + 1:] - count_identifiers = common_variable_path.count('{{ identifier }}') + common_variable_path = common_variable_path[len(common_path) + 1 :] + count_identifiers = common_variable_path.count("{{ identifier }}") if count_identifiers == 1: if variable_in_calculation_multi is False: variable_in_calculation_multi = True else: - variable_in_calculation_multi = 'submulti' + variable_in_calculation_multi = "submulti" elif count_identifiers > 1: - variable_in_calculation_multi = 'submulti' + variable_in_calculation_multi = "submulti" return local_variable_multi, variable_in_calculation_multi diff --git a/tests/dictionaries/00_0no_variable_default_version/makedict/after.json b/tests/dictionaries/00_0no_variable_default_version/makedict/after.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_default_version/makedict/after.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_default_version/makedict/base.json b/tests/dictionaries/00_0no_variable_default_version/makedict/base.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_default_version/makedict/base.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_default_version/makedict/before.json b/tests/dictionaries/00_0no_variable_default_version/makedict/before.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_default_version/makedict/before.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_default_version/makedict/mandatory.json b/tests/dictionaries/00_0no_variable_default_version/makedict/mandatory.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/tests/dictionaries/00_0no_variable_default_version/makedict/mandatory.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/dictionaries/00_0no_variable_default_version/makedict/read_write.json b/tests/dictionaries/00_0no_variable_default_version/makedict/read_write.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_default_version/makedict/read_write.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_remove_version/makedict/after.json b/tests/dictionaries/00_0no_variable_remove_version/makedict/after.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_remove_version/makedict/after.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_remove_version/makedict/base.json b/tests/dictionaries/00_0no_variable_remove_version/makedict/base.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_remove_version/makedict/base.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_remove_version/makedict/before.json b/tests/dictionaries/00_0no_variable_remove_version/makedict/before.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_remove_version/makedict/before.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/00_0no_variable_remove_version/makedict/mandatory.json b/tests/dictionaries/00_0no_variable_remove_version/makedict/mandatory.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/tests/dictionaries/00_0no_variable_remove_version/makedict/mandatory.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/dictionaries/00_0no_variable_remove_version/makedict/read_write.json b/tests/dictionaries/00_0no_variable_remove_version/makedict/read_write.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/dictionaries/00_0no_variable_remove_version/makedict/read_write.json @@ -0,0 +1 @@ +{} diff --git a/tests/dictionaries/40_0leadership_reduce/makedict/after.json b/tests/dictionaries/40_0leadership_reduce/makedict/after.json new file mode 100644 index 000000000..f1f6b35ac --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/makedict/after.json @@ -0,0 +1,22 @@ +{ + "rougail.leadership.leader": { + "owner": "default", + "value": [ + "value_1", + "value_2", + "value_3" + ] + }, + "rougail.leadership.follower": { + "owner": [ + "default", + "default", + "default" + ], + "value": [ + null, + null, + null + ] + } +} diff --git a/tests/dictionaries/40_0leadership_reduce/makedict/base.json b/tests/dictionaries/40_0leadership_reduce/makedict/base.json new file mode 100644 index 000000000..518aa751e --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/makedict/base.json @@ -0,0 +1,16 @@ +{ + "rougail.leadership.leader": [ + { + "rougail.leadership.leader": "value_1", + "rougail.leadership.follower": null + }, + { + "rougail.leadership.leader": "value_2", + "rougail.leadership.follower": null + }, + { + "rougail.leadership.leader": "value_3", + "rougail.leadership.follower": null + } + ] +} diff --git a/tests/dictionaries/40_0leadership_reduce/makedict/before.json b/tests/dictionaries/40_0leadership_reduce/makedict/before.json new file mode 100644 index 000000000..f1f6b35ac --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/makedict/before.json @@ -0,0 +1,22 @@ +{ + "rougail.leadership.leader": { + "owner": "default", + "value": [ + "value_1", + "value_2", + "value_3" + ] + }, + "rougail.leadership.follower": { + "owner": [ + "default", + "default", + "default" + ], + "value": [ + null, + null, + null + ] + } +} diff --git a/tests/dictionaries/40_0leadership_reduce/makedict/mandatory.json b/tests/dictionaries/40_0leadership_reduce/makedict/mandatory.json new file mode 100644 index 000000000..5f4ade798 --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/makedict/mandatory.json @@ -0,0 +1 @@ +["rougail.leadership.follower", "rougail.leadership.follower", "rougail.leadership.follower"] \ No newline at end of file diff --git a/tests/dictionaries/40_0leadership_reduce/makedict/read_write.json b/tests/dictionaries/40_0leadership_reduce/makedict/read_write.json new file mode 100644 index 000000000..518aa751e --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/makedict/read_write.json @@ -0,0 +1,16 @@ +{ + "rougail.leadership.leader": [ + { + "rougail.leadership.leader": "value_1", + "rougail.leadership.follower": null + }, + { + "rougail.leadership.leader": "value_2", + "rougail.leadership.follower": null + }, + { + "rougail.leadership.leader": "value_3", + "rougail.leadership.follower": null + } + ] +} diff --git a/tests/dictionaries/40_0leadership_reduce/tiramisu/base.py b/tests/dictionaries/40_0leadership_reduce/tiramisu/base.py new file mode 100644 index 000000000..5596fe656 --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/tiramisu/base.py @@ -0,0 +1,17 @@ +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('../rougail-tests/funcs/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="leader", doc="a leader", multi=True, default=["value_1", "value_2", "value_3"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string', 'test': ('val1', 'val2')}) +option_4 = StrOption(name="follower", doc="a follower", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string'}) +optiondescription_2 = Leadership(name="leadership", doc="a leadership", children=[option_3, option_4], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml']}) +optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2], properties=frozenset({"basic"}), informations={'ymlfiles': ['']}) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/40_0leadership_reduce/tiramisu/no_namespace.py b/tests/dictionaries/40_0leadership_reduce/tiramisu/no_namespace.py new file mode 100644 index 000000000..ce1b20304 --- /dev/null +++ b/tests/dictionaries/40_0leadership_reduce/tiramisu/no_namespace.py @@ -0,0 +1,12 @@ +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('../rougail-tests/funcs/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +option_2 = StrOption(name="leader", doc="a leader", multi=True, default=["value_1", "value_2", "value_3"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string', 'test': ('val1', 'val2')}) +option_3 = StrOption(name="follower", doc="a follower", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string'}) +optiondescription_1 = Leadership(name="leadership", doc="a leadership", children=[option_2, option_3], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml']}) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/after.json b/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/after.json index a20cae471..0da9315e8 100644 --- a/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/after.json +++ b/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/after.json @@ -12,7 +12,7 @@ "default" ], "value": [ - "cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")", + "cannot access to option \"a follower\" at index \"0\" because has property \"disabled\" (the value of \"leader\" is \"a\")", "b" ] } diff --git a/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/before.json b/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/before.json index a20cae471..0da9315e8 100644 --- a/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/before.json +++ b/tests/dictionaries/44_9calculated_default_leadership_leader/makedict/before.json @@ -12,7 +12,7 @@ "default" ], "value": [ - "cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")", + "cannot access to option \"a follower\" at index \"0\" because has property \"disabled\" (the value of \"leader\" is \"a\")", "b" ] } diff --git a/tests/test_2_makedict.py b/tests/test_2_makedict.py index d4445ba26..470dffd9e 100644 --- a/tests/test_2_makedict.py +++ b/tests/test_2_makedict.py @@ -31,7 +31,7 @@ excludes = set([]) # excludes = set(['60_5family_dynamic_variable_outside_sub_suffix']) test_ok -= excludes -# test_ok = ['04_5validators_multi3'] +test_ok = ['44_9calculated_default_leadership_leader'] test_ok = list(test_ok)