fix: black
This commit is contained in:
parent
bb1f117ed1
commit
5a4bb343b0
31 changed files with 628 additions and 159 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
[]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
[]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
22
tests/dictionaries/40_0leadership_reduce/makedict/after.json
Normal file
22
tests/dictionaries/40_0leadership_reduce/makedict/after.json
Normal file
|
|
@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
16
tests/dictionaries/40_0leadership_reduce/makedict/base.json
Normal file
16
tests/dictionaries/40_0leadership_reduce/makedict/base.json
Normal file
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
["rougail.leadership.follower", "rougail.leadership.follower", "rougail.leadership.follower"]
|
||||
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
17
tests/dictionaries/40_0leadership_reduce/tiramisu/base.py
Normal file
17
tests/dictionaries/40_0leadership_reduce/tiramisu/base.py
Normal file
|
|
@ -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])
|
||||
|
|
@ -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])
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue