WIP: Expand the developer documentation #27
12 changed files with 120 additions and 81 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
## 1.2.0a57 (2026-01-16)
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- add transition
|
||||||
|
|
||||||
## 1.2.0a56 (2026-01-15)
|
## 1.2.0a56 (2026-01-15)
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "rougail"
|
name = "rougail"
|
||||||
version = "1.2.0a56"
|
version = "1.2.0a57"
|
||||||
|
|
||||||
[tool.commitizen]
|
[tool.commitizen]
|
||||||
name = "cz_conventional_commits"
|
name = "cz_conventional_commits"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "rougail-base"
|
name = "rougail-base"
|
||||||
version = "1.2.0a56"
|
version = "1.2.0a57"
|
||||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "A consistency handling system that was initially designed in the configuration management"
|
description = "A consistency handling system that was initially designed in the configuration management"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "rougail"
|
name = "rougail"
|
||||||
version = "1.2.0a56"
|
version = "1.2.0a57"
|
||||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||||
description = "A consistency handling system that was initially designed in the configuration management"
|
description = "A consistency handling system that was initially designed in the configuration management"
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
|
@ -18,7 +18,7 @@ classifiers = [
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruamel.yaml ~= 0.18.6",
|
"ruamel.yaml ~= 0.18.6",
|
||||||
"pydantic ~= 2.9.2",
|
"pydantic ~= 2.9.2",
|
||||||
"rougail-base == 1.2.0a56",
|
"rougail-base == 1.2.0a57",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.flit.sdist]
|
[tool.flit.sdist]
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
__version__ = "1.2.0a56"
|
__version__ = "1.2.0a57"
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ class Annotator(Walk):
|
||||||
for calculation in frozen:
|
for calculation in frozen:
|
||||||
calculation_copy = calculation.model_copy()
|
calculation_copy = calculation.model_copy()
|
||||||
calculation_copy.attribute_name = "frozen"
|
calculation_copy.attribute_name = "frozen"
|
||||||
calculation_copy.ori_path = calculation_copy.path
|
# calculation_copy.ori_path = calculation_copy.path
|
||||||
calculation_copy.path = path
|
# calculation_copy.path = path
|
||||||
value.append(calculation_copy)
|
value.append(calculation_copy)
|
||||||
if len(value) == 1:
|
if len(value) == 1:
|
||||||
value = value[0]
|
value = value[0]
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ class Annotator(Walk): # pylint: disable=R0903
|
||||||
variable.type = "integer"
|
variable.type = "integer"
|
||||||
elif isinstance(variable.default, VariableCalculation):
|
elif isinstance(variable.default, VariableCalculation):
|
||||||
calculated_variable_path, calculated_variable, identifier = (
|
calculated_variable_path, calculated_variable, identifier = (
|
||||||
variable.default.get_variable(self.objectspace)
|
variable.default.get_variable(self.objectspace, variable.path)
|
||||||
)
|
)
|
||||||
if calculated_variable is not None:
|
if calculated_variable is not None:
|
||||||
self._default_variable_copy_informations(
|
self._default_variable_copy_informations(
|
||||||
|
|
@ -236,7 +236,7 @@ class Annotator(Walk): # pylint: disable=R0903
|
||||||
variable.default, VariableCalculation
|
variable.default, VariableCalculation
|
||||||
):
|
):
|
||||||
calculated_variable_path, calculated_variable, identifier = (
|
calculated_variable_path, calculated_variable, identifier = (
|
||||||
variable.default.get_variable(self.objectspace)
|
variable.default.get_variable(self.objectspace, variable.path)
|
||||||
)
|
)
|
||||||
if calculated_variable is not None:
|
if calculated_variable is not None:
|
||||||
if calculated_variable.multi is None:
|
if calculated_variable.multi is None:
|
||||||
|
|
|
||||||
|
|
@ -586,6 +586,7 @@ def _rougail_config(
|
||||||
|
|
||||||
tiram_obj = convert.save()
|
tiram_obj = convert.save()
|
||||||
optiondescription = {}
|
optiondescription = {}
|
||||||
|
print(tiram_obj)
|
||||||
exec(tiram_obj, {}, optiondescription) # pylint: disable=W0122
|
exec(tiram_obj, {}, optiondescription) # pylint: disable=W0122
|
||||||
return optiondescription["option_0"], extra_vars
|
return optiondescription["option_0"], extra_vars
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -989,7 +989,7 @@ class ParserVariable:
|
||||||
typ = calculation_object.pop("type")
|
typ = calculation_object.pop("type")
|
||||||
|
|
||||||
calculation_object["attribute_name"] = attribute
|
calculation_object["attribute_name"] = attribute
|
||||||
calculation_object["path"] = path
|
# calculation_object["path"] = path
|
||||||
calculation_object["inside_list"] = inside_list
|
calculation_object["inside_list"] = inside_list
|
||||||
calculation_object["version"] = self.version
|
calculation_object["version"] = self.version
|
||||||
calculation_object["namespace"] = self.namespace
|
calculation_object["namespace"] = self.namespace
|
||||||
|
|
|
||||||
|
|
@ -247,10 +247,10 @@ PARAM_TYPES = {
|
||||||
|
|
||||||
|
|
||||||
class Calculation(BaseModel):
|
class Calculation(BaseModel):
|
||||||
path: str
|
# path: str
|
||||||
inside_list: bool
|
inside_list: bool
|
||||||
version: str
|
version: str
|
||||||
ori_path: Optional[str] = None
|
# ori_path: Optional[str] = None
|
||||||
default_values: Any = None
|
default_values: Any = None
|
||||||
namespace: Optional[str]
|
namespace: Optional[str]
|
||||||
warnings: Optional[bool] = None
|
warnings: Optional[bool] = None
|
||||||
|
|
@ -258,7 +258,7 @@ class Calculation(BaseModel):
|
||||||
|
|
||||||
model_config = ConfigDict(extra="forbid")
|
model_config = ConfigDict(extra="forbid")
|
||||||
|
|
||||||
def get_params(self, objectspace):
|
def get_params(self, objectspace, path):
|
||||||
if self.warnings is not None and self.attribute_name != "validators":
|
if self.warnings is not None and self.attribute_name != "validators":
|
||||||
msg = _(
|
msg = _(
|
||||||
'"warnings" are only available with attribute "{self.attribute_name}" for variable "{self.ori_path}"'
|
'"warnings" are only available with attribute "{self.attribute_name}" for variable "{self.ori_path}"'
|
||||||
|
|
@ -266,10 +266,10 @@ class Calculation(BaseModel):
|
||||||
raise DictConsistencyError(msg, 83, xmlfiles)
|
raise DictConsistencyError(msg, 83, xmlfiles)
|
||||||
if not self.params:
|
if not self.params:
|
||||||
return {}
|
return {}
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
params = {}
|
params = {}
|
||||||
for param_obj in self.params:
|
for param_obj in self.params:
|
||||||
param = param_obj.to_param(
|
param = param_obj.to_param(
|
||||||
|
|
@ -310,21 +310,22 @@ class JinjaCalculation(Calculation):
|
||||||
return_type,
|
return_type,
|
||||||
multi,
|
multi,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
*,
|
*,
|
||||||
add_help=False,
|
add_help=False,
|
||||||
params: Optional[dict] = None,
|
params: Optional[dict] = None,
|
||||||
):
|
):
|
||||||
variable = objectspace.paths[self.path]
|
variable = objectspace.paths[path]
|
||||||
jinja_path = f"{self.attribute_name}_{self.path}"
|
jinja_path = f"{self.attribute_name}_{path}"
|
||||||
idx = 0
|
idx = 0
|
||||||
while jinja_path in objectspace.jinja:
|
while jinja_path in objectspace.jinja:
|
||||||
jinja_path = f"{self.attribute_name}_{self.path}_{idx}"
|
jinja_path = f"{self.attribute_name}_{path}_{idx}"
|
||||||
idx += 1
|
idx += 1
|
||||||
objectspace.jinja[jinja_path] = self.jinja
|
objectspace.jinja[jinja_path] = self.jinja
|
||||||
if return_type in RENAME_TYPE:
|
if return_type in RENAME_TYPE:
|
||||||
warning = _('the variable "{0}" has a depreciated return_type "{1}", please use "{2}" instead in {3}')
|
warning = _('the variable "{0}" has a depreciated return_type "{1}", please use "{2}" instead in {3}')
|
||||||
warn(
|
warn(
|
||||||
warning.format(self.path, return_type, RENAME_TYPE[return_type], display_xmlfiles(self.xmlfiles)),
|
warning.format(path, return_type, RENAME_TYPE[return_type], display_xmlfiles(self.xmlfiles)),
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
stacklevel=2,
|
stacklevel=2,
|
||||||
)
|
)
|
||||||
|
|
@ -337,7 +338,7 @@ class JinjaCalculation(Calculation):
|
||||||
"__internal_multi": multi,
|
"__internal_multi": multi,
|
||||||
"__internal_files": self.xmlfiles,
|
"__internal_files": self.xmlfiles,
|
||||||
"__internal_attribute": self.attribute_name,
|
"__internal_attribute": self.attribute_name,
|
||||||
"__internal_variable": self.path,
|
"__internal_variable": path,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if self.default_values:
|
if self.default_values:
|
||||||
|
|
@ -345,13 +346,13 @@ class JinjaCalculation(Calculation):
|
||||||
if add_help:
|
if add_help:
|
||||||
default["help"] = function + "_help"
|
default["help"] = function + "_help"
|
||||||
if self.params:
|
if self.params:
|
||||||
default["params"] |= self.get_params(objectspace)
|
default["params"] |= self.get_params(objectspace, path)
|
||||||
if params:
|
if params:
|
||||||
default["params"] |= params
|
default["params"] |= params
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
if self.warnings:
|
if self.warnings:
|
||||||
default["warnings_only"] = True
|
default["warnings_only"] = True
|
||||||
for sub_variable, identifier, true_path in get_jinja_variable_to_param(
|
for sub_variable, identifier, true_path in get_jinja_variable_to_param(
|
||||||
|
|
@ -385,33 +386,35 @@ class JinjaCalculation(Calculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
if self.attribute_name in ["default", "secret_manager"]:
|
if self.attribute_name in ["default", "secret_manager"]:
|
||||||
if self.return_type:
|
if self.return_type:
|
||||||
raise Exception("return_type not allowed!")
|
raise Exception("return_type not allowed!")
|
||||||
variable = objectspace.paths[self.path]
|
variable = objectspace.paths[path]
|
||||||
return_type = variable.type
|
return_type = variable.type
|
||||||
if self.inside_list:
|
if self.inside_list:
|
||||||
multi = False
|
multi = False
|
||||||
elif self.path in objectspace.followers:
|
elif path in objectspace.followers:
|
||||||
multi = objectspace.multis[self.path] == "submulti"
|
multi = objectspace.multis[path] == "submulti"
|
||||||
else:
|
else:
|
||||||
multi = self.path in objectspace.multis
|
multi = path in objectspace.multis
|
||||||
return self._jinja_to_function(
|
return self._jinja_to_function(
|
||||||
"jinja_to_function",
|
"jinja_to_function",
|
||||||
return_type,
|
return_type,
|
||||||
multi,
|
multi,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
)
|
)
|
||||||
elif self.attribute_name == "validators":
|
elif self.attribute_name == "validators":
|
||||||
return_type = self.return_type
|
return_type = self.return_type
|
||||||
if return_type is None:
|
if return_type is None:
|
||||||
return_type = "string"
|
return_type = "string"
|
||||||
if return_type not in ["string", "boolean"]:
|
if return_type not in ["string", "boolean"]:
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
msg = _(
|
msg = _(
|
||||||
'variable "{0}" has a calculating "{1}" with an invalid return_type, should be boolean or string, not "{2}"'
|
'variable "{0}" has a calculating "{1}" with an invalid return_type, should be boolean or string, not "{2}"'
|
||||||
).format(path, self.attribute_name, return_type)
|
).format(path, self.attribute_name, return_type)
|
||||||
|
|
@ -421,7 +424,7 @@ class JinjaCalculation(Calculation):
|
||||||
if description is None:
|
if description is None:
|
||||||
warning = _('the variable "{0}" has a return_type "{1}", for attribute "{2}" but has not description in {3}')
|
warning = _('the variable "{0}" has a return_type "{1}", for attribute "{2}" but has not description in {3}')
|
||||||
warn(
|
warn(
|
||||||
warning.format(self.path, return_type, self.attribute_name, display_xmlfiles(self.xmlfiles)),
|
warning.format(path, return_type, self.attribute_name, display_xmlfiles(self.xmlfiles)),
|
||||||
RougailWarning,
|
RougailWarning,
|
||||||
)
|
)
|
||||||
self.description = _('value is invalid')
|
self.description = _('value is invalid')
|
||||||
|
|
@ -432,17 +435,18 @@ class JinjaCalculation(Calculation):
|
||||||
return_type,
|
return_type,
|
||||||
False,
|
False,
|
||||||
objectspace,
|
objectspace,
|
||||||
params={'description': description}
|
path,
|
||||||
|
params={'description': description},
|
||||||
)
|
)
|
||||||
elif self.attribute_name in PROPERTY_ATTRIBUTE:
|
elif self.attribute_name in PROPERTY_ATTRIBUTE:
|
||||||
return_type = self.return_type
|
return_type = self.return_type
|
||||||
if return_type is None:
|
if return_type is None:
|
||||||
return_type = "string"
|
return_type = "string"
|
||||||
if return_type not in ["string", "boolean"]:
|
if return_type not in ["string", "boolean"]:
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = .path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
msg = _(
|
msg = _(
|
||||||
'variable "{0}" has a calculating "{1}" with an invalid return_type, should be boolean or string, not "{2}"'
|
'variable "{0}" has a calculating "{1}" with an invalid return_type, should be boolean or string, not "{2}"'
|
||||||
).format(path, self.attribute_name, return_type)
|
).format(path, self.attribute_name, return_type)
|
||||||
|
|
@ -453,6 +457,7 @@ class JinjaCalculation(Calculation):
|
||||||
return_type,
|
return_type,
|
||||||
False,
|
False,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
add_help=True,
|
add_help=True,
|
||||||
params={
|
params={
|
||||||
None: [self.attribute_name, description],
|
None: [self.attribute_name, description],
|
||||||
|
|
@ -469,6 +474,7 @@ class JinjaCalculation(Calculation):
|
||||||
return_type,
|
return_type,
|
||||||
not self.inside_list,
|
not self.inside_list,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
)
|
)
|
||||||
elif self.attribute_name == "dynamic":
|
elif self.attribute_name == "dynamic":
|
||||||
return_type = self.return_type
|
return_type = self.return_type
|
||||||
|
|
@ -479,6 +485,7 @@ class JinjaCalculation(Calculation):
|
||||||
return_type,
|
return_type,
|
||||||
True,
|
True,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
)
|
)
|
||||||
raise Exception("hu?")
|
raise Exception("hu?")
|
||||||
|
|
||||||
|
|
@ -492,11 +499,12 @@ class _VariableCalculation(Calculation):
|
||||||
def get_variable(
|
def get_variable(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> "Variable":
|
) -> "Variable":
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
if self.version != "1.0" and objectspace.paths.regexp_relative.search(
|
if self.version != "1.0" and objectspace.paths.regexp_relative.search(
|
||||||
self.variable
|
self.variable
|
||||||
):
|
):
|
||||||
|
|
@ -521,11 +529,11 @@ class _VariableCalculation(Calculation):
|
||||||
if isinstance(variable, objectspace.family):
|
if isinstance(variable, objectspace.family):
|
||||||
msg = _(
|
msg = _(
|
||||||
'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family'
|
'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family'
|
||||||
).format(variable_full_path, self.attribute_name, self.path)
|
).format(variable_full_path, self.attribute_name, path)
|
||||||
raise DictConsistencyError(msg, 47, self.xmlfiles)
|
raise DictConsistencyError(msg, 47, self.xmlfiles)
|
||||||
else:
|
else:
|
||||||
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(
|
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(
|
||||||
variable, self.attribute_name, self.path
|
variable, self.attribute_name, path
|
||||||
)
|
)
|
||||||
raise DictConsistencyError(msg, 48, self.xmlfiles)
|
raise DictConsistencyError(msg, 48, self.xmlfiles)
|
||||||
return variable_full_path, variable, identifier
|
return variable_full_path, variable, identifier
|
||||||
|
|
@ -533,6 +541,7 @@ class _VariableCalculation(Calculation):
|
||||||
def get_params(
|
def get_params(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
variable_in_calculation_path: str,
|
variable_in_calculation_path: str,
|
||||||
variable_in_calculation: "Variable",
|
variable_in_calculation: "Variable",
|
||||||
variable_in_calculation_identifier: Optional[str],
|
variable_in_calculation_identifier: Optional[str],
|
||||||
|
|
@ -540,10 +549,10 @@ class _VariableCalculation(Calculation):
|
||||||
):
|
):
|
||||||
if not variable_in_calculation:
|
if not variable_in_calculation:
|
||||||
if not objectspace.force_optional:
|
if not objectspace.force_optional:
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
msg = _(
|
msg = _(
|
||||||
'variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"'
|
'variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"'
|
||||||
).format(path, self.attribute_name, self.variable)
|
).format(path, self.attribute_name, self.variable)
|
||||||
|
|
@ -567,23 +576,23 @@ class _VariableCalculation(Calculation):
|
||||||
if self.allow_none:
|
if self.allow_none:
|
||||||
params["allow_none"] = True
|
params["allow_none"] = True
|
||||||
self.check_multi(
|
self.check_multi(
|
||||||
objectspace, variable_in_calculation_path, variable_in_calculation
|
objectspace, path, variable_in_calculation_path, variable_in_calculation
|
||||||
)
|
)
|
||||||
if self.path in objectspace.followers:
|
if path in objectspace.followers:
|
||||||
multi = objectspace.multis[self.path] == "submulti"
|
multi = objectspace.multis[path] == "submulti"
|
||||||
else:
|
else:
|
||||||
multi = self.path in objectspace.multis
|
multi = path in objectspace.multis
|
||||||
if multi and not self.inside_list:
|
if multi and not self.inside_list:
|
||||||
params["__internal_multi"] = True
|
params["__internal_multi"] = True
|
||||||
return params
|
return params
|
||||||
|
|
||||||
def check_multi(
|
def check_multi(
|
||||||
self, objectspace, variable_in_calculation_path, variable_in_calculation
|
self, objectspace, path, variable_in_calculation_path, variable_in_calculation
|
||||||
):
|
):
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
local_variable = objectspace.paths[path]
|
local_variable = objectspace.paths[path]
|
||||||
local_variable_multi, variable_in_calculation_multi = (
|
local_variable_multi, variable_in_calculation_multi = (
|
||||||
calc_multi_for_type_variable(
|
calc_multi_for_type_variable(
|
||||||
|
|
@ -696,14 +705,14 @@ class _VariableCalculation(Calculation):
|
||||||
)
|
)
|
||||||
raise DictConsistencyError(msg, 18, self.xmlfiles)
|
raise DictConsistencyError(msg, 18, self.xmlfiles)
|
||||||
|
|
||||||
def get_default_value_optional(self, objectspace, default):
|
def get_default_value_optional(self, objectspace, path, default):
|
||||||
if self.attribute_name == "default":
|
if self.attribute_name == "default":
|
||||||
if self.inside_list:
|
if self.inside_list:
|
||||||
expected_multiple_value = False
|
expected_multiple_value = False
|
||||||
elif self.path in objectspace.followers:
|
elif path in objectspace.followers:
|
||||||
expected_multiple_value = objectspace.multis[self.path] == "submulti"
|
expected_multiple_value = objectspace.multis[path] == "submulti"
|
||||||
else:
|
else:
|
||||||
expected_multiple_value = self.path in objectspace.multis
|
expected_multiple_value = path in objectspace.multis
|
||||||
elif self.attribute_name in PROPERTY_ATTRIBUTE:
|
elif self.attribute_name in PROPERTY_ATTRIBUTE:
|
||||||
expected_multiple_value = False
|
expected_multiple_value = False
|
||||||
else:
|
else:
|
||||||
|
|
@ -718,7 +727,7 @@ class _VariableCalculation(Calculation):
|
||||||
msg = _(
|
msg = _(
|
||||||
'the variable "{0}" is not waiting for a list as "{1}" but the attribute "default" is a list ("{2}")'
|
'the variable "{0}" is not waiting for a list as "{1}" but the attribute "default" is a list ("{2}")'
|
||||||
)
|
)
|
||||||
msg = msg.format(self.path, self.attribute_name, default)
|
msg = msg.format(path, self.attribute_name, default)
|
||||||
raise DictConsistencyError(msg, 77, self.xmlfiles)
|
raise DictConsistencyError(msg, 77, self.xmlfiles)
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
@ -731,6 +740,7 @@ class VariableCalculation(_VariableCalculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
if (
|
if (
|
||||||
self.attribute_name != "default"
|
self.attribute_name != "default"
|
||||||
|
|
@ -745,7 +755,7 @@ class VariableCalculation(_VariableCalculation):
|
||||||
variable_in_calculation_path,
|
variable_in_calculation_path,
|
||||||
variable_in_calculation,
|
variable_in_calculation,
|
||||||
variable_in_calculation_identifier,
|
variable_in_calculation_identifier,
|
||||||
) = self.get_variable(objectspace)
|
) = self.get_variable(objectspace, path)
|
||||||
if not variable_in_calculation and (
|
if not variable_in_calculation and (
|
||||||
self.optional or objectspace.force_optional
|
self.optional or objectspace.force_optional
|
||||||
):
|
):
|
||||||
|
|
@ -755,16 +765,17 @@ class VariableCalculation(_VariableCalculation):
|
||||||
return self.default_values
|
return self.default_values
|
||||||
raise VariableCalculationDependencyError()
|
raise VariableCalculationDependencyError()
|
||||||
if variable_in_calculation and self.attribute_name == "default":
|
if variable_in_calculation and self.attribute_name == "default":
|
||||||
local_variable = objectspace.paths[self.path]
|
local_variable = objectspace.paths[path]
|
||||||
if CONVERT_OPTION.get(local_variable.type, {}).get(
|
if CONVERT_OPTION.get(local_variable.type, {}).get(
|
||||||
"func", str
|
"func", str
|
||||||
) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str):
|
) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str):
|
||||||
msg = _(
|
msg = _(
|
||||||
'variable "{0}" has a default value calculated with "{1}" which has incompatible type'
|
'variable "{0}" has a default value calculated with "{1}" which has incompatible type'
|
||||||
).format(self.path, self.variable)
|
).format(path, self.variable)
|
||||||
raise DictConsistencyError(msg, 67, self.xmlfiles)
|
raise DictConsistencyError(msg, 67, self.xmlfiles)
|
||||||
params = self.get_params(
|
params = self.get_params(
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
variable_in_calculation_path,
|
variable_in_calculation_path,
|
||||||
variable_in_calculation,
|
variable_in_calculation,
|
||||||
variable_in_calculation_identifier,
|
variable_in_calculation_identifier,
|
||||||
|
|
@ -785,12 +796,13 @@ class VariablePropertyCalculation(_VariableCalculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
(
|
(
|
||||||
variable_in_calculation_path,
|
variable_in_calculation_path,
|
||||||
variable_in_calculation,
|
variable_in_calculation,
|
||||||
variable_in_calculation_identifier,
|
variable_in_calculation_identifier,
|
||||||
) = self.get_variable(objectspace)
|
) = self.get_variable(objectspace, path)
|
||||||
if (
|
if (
|
||||||
# self.default is not undefined and
|
# self.default is not undefined and
|
||||||
not variable_in_calculation
|
not variable_in_calculation
|
||||||
|
|
@ -804,11 +816,12 @@ class VariablePropertyCalculation(_VariableCalculation):
|
||||||
msg = _(
|
msg = _(
|
||||||
'the variable "{0}" is waiting for a boolean as "{1}" but the attribute "default" is not a boolean ("{2}")'
|
'the variable "{0}" is waiting for a boolean as "{1}" but the attribute "default" is not a boolean ("{2}")'
|
||||||
)
|
)
|
||||||
msg = msg.format(self.path, self.attribute_name, default)
|
msg = msg.format(path, self.attribute_name, default)
|
||||||
raise DictConsistencyError(msg, 79, self.xmlfiles)
|
raise DictConsistencyError(msg, 79, self.xmlfiles)
|
||||||
return self.get_default_value_optional(objectspace, default)
|
return self.get_default_value_optional(objectspace, default)
|
||||||
params = self.get_params(
|
params = self.get_params(
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
variable_in_calculation_path,
|
variable_in_calculation_path,
|
||||||
variable_in_calculation,
|
variable_in_calculation,
|
||||||
variable_in_calculation_identifier,
|
variable_in_calculation_identifier,
|
||||||
|
|
@ -825,12 +838,12 @@ class VariablePropertyCalculation(_VariableCalculation):
|
||||||
if self.version == "1.0":
|
if self.version == "1.0":
|
||||||
msg = _(
|
msg = _(
|
||||||
'"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
|
'"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
|
||||||
).format(self.attribute_name, self.path)
|
).format(self.attribute_name, path)
|
||||||
raise DictConsistencyError(msg, 103, variable.xmlfiles)
|
raise DictConsistencyError(msg, 103, variable.xmlfiles)
|
||||||
if self.when_not is not undefined:
|
if self.when_not is not undefined:
|
||||||
msg = _(
|
msg = _(
|
||||||
'the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together'
|
'the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together'
|
||||||
).format(self.path, self.attribute_name)
|
).format(path, self.attribute_name)
|
||||||
raise DictConsistencyError(msg, 31, variable.xmlfiles)
|
raise DictConsistencyError(msg, 31, variable.xmlfiles)
|
||||||
when = self.when
|
when = self.when
|
||||||
inverse = False
|
inverse = False
|
||||||
|
|
@ -838,7 +851,7 @@ class VariablePropertyCalculation(_VariableCalculation):
|
||||||
if self.version == "1.0":
|
if self.version == "1.0":
|
||||||
msg = _(
|
msg = _(
|
||||||
'"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
|
'"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
|
||||||
).format(self.attribute_name, self.path)
|
).format(self.attribute_name, path)
|
||||||
raise DictConsistencyError(msg, 104, variable.xmlfiles)
|
raise DictConsistencyError(msg, 104, variable.xmlfiles)
|
||||||
when = self.when_not
|
when = self.when_not
|
||||||
inverse = True
|
inverse = True
|
||||||
|
|
@ -849,7 +862,7 @@ class VariablePropertyCalculation(_VariableCalculation):
|
||||||
if variable.type != "boolean":
|
if variable.type != "boolean":
|
||||||
msg = _(
|
msg = _(
|
||||||
'"when" or "when_not" is mandatory for the not boolean variable "{0}" in attribute "{1}"'
|
'"when" or "when_not" is mandatory for the not boolean variable "{0}" in attribute "{1}"'
|
||||||
).format(self.path, self.attribute_name)
|
).format(path, self.attribute_name)
|
||||||
raise DictConsistencyError(msg, 106, variable.xmlfiles)
|
raise DictConsistencyError(msg, 106, variable.xmlfiles)
|
||||||
when = True
|
when = True
|
||||||
inverse = False
|
inverse = False
|
||||||
|
|
@ -872,6 +885,7 @@ class InformationCalculation(Calculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
params = {
|
params = {
|
||||||
None: [
|
None: [
|
||||||
|
|
@ -882,10 +896,10 @@ class InformationCalculation(Calculation):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
if self.variable:
|
if self.variable:
|
||||||
if self.ori_path is None:
|
# if self.ori_path is None:
|
||||||
path = self.path
|
# path = self.path
|
||||||
else:
|
# else:
|
||||||
path = self.ori_path
|
# path = self.ori_path
|
||||||
variable, identifier = objectspace.paths.get_with_dynamic(
|
variable, identifier = objectspace.paths.get_with_dynamic(
|
||||||
self.variable,
|
self.variable,
|
||||||
path,
|
path,
|
||||||
|
|
@ -931,6 +945,7 @@ class IdentifierCalculation(_IdentifierCalculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
identifier = {"type": "identifier"}
|
identifier = {"type": "identifier"}
|
||||||
if self.identifier is not None:
|
if self.identifier is not None:
|
||||||
|
|
@ -992,11 +1007,12 @@ class IndexCalculation(Calculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
if self.path not in objectspace.followers:
|
if path not in objectspace.followers:
|
||||||
msg = _(
|
msg = _(
|
||||||
'the variable "{0}" is not a follower, so cannot have index type for "{1}"'
|
'the variable "{0}" is not a follower, so cannot have index type for "{1}"'
|
||||||
).format(self.path, self.attribute_name)
|
).format(path, self.attribute_name)
|
||||||
raise DictConsistencyError(msg, 60, self.xmlfiles)
|
raise DictConsistencyError(msg, 60, self.xmlfiles)
|
||||||
return {
|
return {
|
||||||
"function": "calc_value",
|
"function": "calc_value",
|
||||||
|
|
@ -1011,6 +1027,7 @@ class NamespaceCalculation(Calculation):
|
||||||
def to_function(
|
def to_function(
|
||||||
self,
|
self,
|
||||||
objectspace,
|
objectspace,
|
||||||
|
path,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
namespace = self.namespace
|
namespace = self.namespace
|
||||||
if namespace:
|
if namespace:
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,7 @@ class Common:
|
||||||
function,
|
function,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Generate calculated value"""
|
"""Generate calculated value"""
|
||||||
child = function.to_function(self.objectspace)
|
child = function.to_function(self.objectspace, self.elt.path)
|
||||||
if isinstance(child, str):
|
if isinstance(child, str):
|
||||||
return self.convert_str(child)
|
return self.convert_str(child)
|
||||||
elif not isinstance(child, dict):
|
elif not isinstance(child, dict):
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,21 @@ def type_variable(test_name):
|
||||||
with variables_file.open('r') as fh:
|
with variables_file.open('r') as fh:
|
||||||
loaded_configuration = load(fh)
|
loaded_configuration = load(fh)
|
||||||
assert loaded_configuration == loads(dumps(configuration)), f"error in file {variables_file}"
|
assert loaded_configuration == loads(dumps(configuration)), f"error in file {variables_file}"
|
||||||
|
#
|
||||||
|
print('--------------')
|
||||||
|
print('--------------')
|
||||||
|
print('--------------')
|
||||||
|
print(config.value.get())
|
||||||
|
config.property.read_write()
|
||||||
|
print(config.value.get())
|
||||||
|
variables_file = result / "variables_rw.json"
|
||||||
|
configuration = dict(config_to_dict(config.value.get()))
|
||||||
|
if not variables_file.is_file():
|
||||||
|
with variables_file.open('w') as fh:
|
||||||
|
dump(configuration, fh, indent=4)
|
||||||
|
with variables_file.open('r') as fh:
|
||||||
|
loaded_configuration = load(fh)
|
||||||
|
assert loaded_configuration == loads(dumps(configuration)), f"error in file {variables_file}"
|
||||||
|
|
||||||
|
|
||||||
def test_type_variable():
|
def test_type_variable():
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue