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) ## 1.1.1 (2024-11-06)
### Fix ### Fix

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "rougail" name = "rougail"
version = "1.1.1" version = "1.2.0a0"
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"

View file

@ -120,7 +120,7 @@ class Annotator(Walk):
else: else:
value = [] value = []
for calculation in frozen: for calculation in frozen:
calculation_copy = calculation.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

View file

@ -182,6 +182,7 @@ class FakeRougailConvert(RougailConvert):
self.base_option_name = "baseoption" self.base_option_name = "baseoption"
self.export_with_import = True self.export_with_import = True
self.internal_functions = [] self.internal_functions = []
self.force_optional = False
self.plugins = ["structural_commandline"] self.plugins = ["structural_commandline"]
self.add_extra_options = self.add_extra_options self.add_extra_options = self.add_extra_options
@ -387,6 +388,11 @@ suffix:
default: '' default: ''
mandatory: false mandatory: false
commandline: 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 = { processes = {
"structural": [], "structural": [],

View file

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

View file

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

View file

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

View file

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

View file

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

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("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") 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'}) 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_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"})) 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("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") 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'}) 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_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_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"})) 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'}) 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_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"})) 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("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") 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'}) 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'}) 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]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2])