Compare commits

..

2 commits

13 changed files with 61 additions and 66 deletions

View file

@ -1,3 +1,9 @@
## 1.2.0a0 (2024-11-08)
### Feat
- add force_optional option to allow charging structure even if all variables are not available
## 1.1.1 (2024-11-06)
### Fix

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project]
name = "rougail"
version = "1.1.1"
version = "1.2.0a0"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md"
description = "A consistency handling system that was initially designed in the configuration management"

View file

@ -120,7 +120,7 @@ class Annotator(Walk):
else:
value = []
for calculation in frozen:
calculation_copy = calculation.copy()
calculation_copy = calculation.model_copy()
calculation_copy.attribute_name = "frozen"
calculation_copy.ori_path = calculation_copy.path
calculation_copy.path = path

View file

@ -182,6 +182,7 @@ class FakeRougailConvert(RougailConvert):
self.base_option_name = "baseoption"
self.export_with_import = True
self.internal_functions = []
self.force_optional = False
self.plugins = ["structural_commandline"]
self.add_extra_options = self.add_extra_options
@ -387,6 +388,11 @@ suffix:
default: ''
mandatory: false
commandline: false
force_optional:
description: Every variable in calculation are optional
negative_description: Variable in calculation are not optional by default
default: False
"""
processes = {
"structural": [],

View file

@ -390,6 +390,7 @@ class ParserVariable:
self.base_option_name = rougailconfig["base_option_name"]
self.export_with_import = rougailconfig["export_with_import"]
self.internal_functions = rougailconfig["internal_functions"]
self.force_optional = rougailconfig["force_optional"]
self.add_extra_options = rougailconfig[
"structural_commandline.add_extra_options"
]

View file

@ -432,8 +432,10 @@ class _VariableCalculation(Calculation):
needs_multi: Optional[bool] = None,
):
if not variable:
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 88, self.xmlfiles)
if not objectspace.force_optional:
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 88, self.xmlfiles)
return {None: [['example']]}
param = {
"type": "variable",
"variable": variable,
@ -503,7 +505,7 @@ class VariableCalculation(_VariableCalculation):
msg = f'"{self.attribute_name}" variable shall not have an "optional" attribute for variable "{self.variable}"'
raise DictConsistencyError(msg, 33, self.xmlfiles)
variable, identifier = self.get_variable(objectspace)
if not variable and self.optional:
if not variable and self.optional or (objectspace.force_optional and self.attribute_name == "default"):
raise VariableCalculationDependencyError()
params = self.get_params(
objectspace,
@ -532,30 +534,31 @@ class VariablePropertyCalculation(_VariableCalculation):
identifier,
needs_multi=False,
)
variable = params[None][0]["variable"]
if self.when is not undefined:
if self.version == "1.0":
msg = f'when is not allowed in format version 1.0 for attribute "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 103, variable.xmlfiles)
if self.when_not is not undefined:
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", when and when_not cannot set together'
raise DictConsistencyError(msg, 31, variable.xmlfiles)
when = self.when
inverse = False
elif self.when_not is not undefined:
if self.version == "1.0":
msg = f'when_not is not allowed in format version 1.0 for attribute "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 104, variable.xmlfiles)
when = self.when_not
inverse = True
else:
if variable.type != "boolean":
raise Exception("only boolean!")
when = True
inverse = False
if params[None] and "variable" in params[None][0]:
variable = params[None][0]["variable"]
if self.when is not undefined:
if self.version == "1.0":
msg = f'when is not allowed in format version 1.0 for attribute "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 103, variable.xmlfiles)
if self.when_not is not undefined:
msg = f'the variable "{self.path}" has an invalid attribute "{self.attribute_name}", when and when_not cannot set together'
raise DictConsistencyError(msg, 31, variable.xmlfiles)
when = self.when
inverse = False
elif self.when_not is not undefined:
if self.version == "1.0":
msg = f'when_not is not allowed in format version 1.0 for attribute "{self.attribute_name}" for variable "{self.path}"'
raise DictConsistencyError(msg, 104, variable.xmlfiles)
when = self.when_not
inverse = True
else:
if variable.type != "boolean":
raise Exception("only boolean!")
when = True
inverse = False
params["when"] = when
params["inverse"] = inverse
params[None].insert(0, self.attribute_name)
params["when"] = when
params["inverse"] = inverse
return {
"function": "variable_to_property",
"params": params,
@ -593,9 +596,15 @@ class InformationCalculation(Calculation):
self.namespace,
self.xmlfiles,
)
if variable is None or identifier is not None:
raise Exception("pfff")
params[None][0]["variable"] = variable
if variable is None:
if not objectspace.force_optional:
msg = f'cannot find variable "{self.variable}" for the information "{self.information}" when calculating "{self.attribute_name}"'
raise DictConsistencyError(msg, 40, variable.xmlfiles)
if identifier is not None:
msg = f'identifier not allowed for the information "{self.information}" when calculating "{self.attribute_name}"'
raise DictConsistencyError(msg, 41, variable.xmlfiles)
if variable:
params[None][0]["variable"] = variable
if self.default_values:
params["__default_value"] = self.default_values
return {

View file

@ -1,17 +1,6 @@
{
"rougail.var": {
"owner": "default",
"value": [
"val1",
"val2"
]
},
"rougail.dynval1.var": {
"owner": "default",
"value": null
},
"rougail.dynval2.var": {
"owner": "default",
"value": null
"value": []
}
}

View file

@ -1,8 +1,3 @@
{
"rougail.var": [
"val1",
"val2"
],
"rougail.dynval1.var": null,
"rougail.dynval2.var": null
"rougail.var": []
}

View file

@ -1,17 +1,6 @@
{
"rougail.var": {
"owner": "default",
"value": [
"val1",
"val2"
]
},
"rougail.dynval1.var": {
"owner": "default",
"value": null
},
"rougail.dynval2.var": {
"owner": "default",
"value": null
"value": []
}
}

View file

@ -1 +1 @@
["rougail.dynval1.var", "rougail.dynval2.var"]
["rougail.var"]

View file

@ -10,7 +10,7 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="var", doc="A suffix variable", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string', 'test': ('val1', 'val2')})
option_4 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_3 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_2)))), children=[option_4], properties=frozenset({"basic"}), informations={'dynamic_variable': 'rougail.var'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, optiondescription_3], properties=frozenset({"basic"}))

View file

@ -10,12 +10,12 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="var", doc="A suffix variable", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string', 'test': ('val1', 'val2')})
option_5 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_4 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_3)))), children=[option_5], properties=frozenset({"basic"}), informations={'dynamic_variable': '1.rougail.var'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, optiondescription_4], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_8 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_8 = StrOption(name="var", doc="A suffix variable", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string', 'test': ('val1', 'val2')})
option_10 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_9 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_8)))), children=[option_10], properties=frozenset({"basic"}), informations={'dynamic_variable': '2.rougail.var'})
optiondescription_7 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_8, optiondescription_9], properties=frozenset({"basic"}))

View file

@ -6,7 +6,7 @@ load_functions('tests/dictionaries/../eosfunc/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = StrOption(name="var", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_1 = StrOption(name="var", doc="A suffix variable", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'string', 'test': ('val1', 'val2')})
option_3 = StrOption(name="var", doc="A dynamic variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_2 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="A dynamic family", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_1)))), children=[option_3], properties=frozenset({"basic"}), informations={'dynamic_variable': 'var'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2])