fix: better support for identifier calculation
This commit is contained in:
parent
130bb4d8da
commit
f7aad40ee7
11 changed files with 163 additions and 10 deletions
|
|
@ -248,10 +248,14 @@ class Annotator(Walk): # pylint: disable=R0903
|
||||||
).format(variable.path)
|
).format(variable.path)
|
||||||
raise DictConsistencyError(msg, 75, variable.xmlfiles)
|
raise DictConsistencyError(msg, 75, variable.xmlfiles)
|
||||||
self._convert_variable_multi(calculated_variable)
|
self._convert_variable_multi(calculated_variable)
|
||||||
|
identifier_is_a_calculation = False
|
||||||
|
if isinstance(variable.default, Calculation):
|
||||||
|
identifier_is_a_calculation = isinstance(variable.default.identifier, Calculation)
|
||||||
variable.multi = calc_multi_for_type_variable(
|
variable.multi = calc_multi_for_type_variable(
|
||||||
variable,
|
variable,
|
||||||
calculated_variable_path,
|
calculated_variable_path,
|
||||||
calculated_variable,
|
calculated_variable,
|
||||||
|
identifier_is_a_calculation,
|
||||||
self.objectspace,
|
self.objectspace,
|
||||||
)[1]
|
)[1]
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ class ParserVariable:
|
||||||
set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
|
set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
|
||||||
)
|
)
|
||||||
self.variable_calculations = self.search_calculation( # pylint: disable=W0201
|
self.variable_calculations = self.search_calculation( # pylint: disable=W0201
|
||||||
hint
|
hint, variable=True,
|
||||||
)
|
)
|
||||||
self.is_init = True
|
self.is_init = True
|
||||||
|
|
||||||
|
|
@ -969,6 +969,9 @@ class ParserVariable:
|
||||||
return value["type"] in CALCULATION_TYPES
|
return value["type"] in CALCULATION_TYPES
|
||||||
# auto set type
|
# auto set type
|
||||||
typ = set(CALCULATION_TYPES) & set(value)
|
typ = set(CALCULATION_TYPES) & set(value)
|
||||||
|
# XXX variable could have identifier
|
||||||
|
if typ == {"variable", "identifier"}:
|
||||||
|
typ = {"variable"}
|
||||||
# XXX variable is also set to information
|
# XXX variable is also set to information
|
||||||
if typ == {"variable", "information"}:
|
if typ == {"variable", "information"}:
|
||||||
typ = {"information"}
|
typ = {"information"}
|
||||||
|
|
@ -1002,7 +1005,12 @@ class ParserVariable:
|
||||||
#
|
#
|
||||||
if attribute == "default" and "identifier" in calculation_object:
|
if attribute == "default" and "identifier" in calculation_object:
|
||||||
identifier = calculation_object["identifier"]
|
identifier = calculation_object["identifier"]
|
||||||
if isinstance(identifier, dict):
|
if isinstance(identifier, dict) and self.is_calculation(
|
||||||
|
"identifier",
|
||||||
|
identifier,
|
||||||
|
self.variable_calculations,
|
||||||
|
inside_list,
|
||||||
|
):
|
||||||
self.set_calculation(calculation_object, "identifier", identifier, path, family_is_dynamic, xmlfiles, inside_list=inside_list, index=index)
|
self.set_calculation(calculation_object, "identifier", identifier, path, family_is_dynamic, xmlfiles, inside_list=inside_list, index=index)
|
||||||
if "params" in calculation_object:
|
if "params" in calculation_object:
|
||||||
if not isinstance(calculation_object["params"], dict):
|
if not isinstance(calculation_object["params"], dict):
|
||||||
|
|
@ -1091,10 +1099,15 @@ class RougailConvert(ParserVariable):
|
||||||
def search_calculation(
|
def search_calculation(
|
||||||
self,
|
self,
|
||||||
hint: dict,
|
hint: dict,
|
||||||
|
variable: bool=False,
|
||||||
) -> Tuple[List[Any], List[Any]]:
|
) -> Tuple[List[Any], List[Any]]:
|
||||||
"""attribute is calculated if typing is like: Union[Calculation, xxx]"""
|
"""attribute is calculated if typing is like: Union[Calculation, xxx]"""
|
||||||
inside_list = []
|
if variable:
|
||||||
outside_list = []
|
inside_list = ["identifier"]
|
||||||
|
outside_list = ["identifier"]
|
||||||
|
else:
|
||||||
|
inside_list = []
|
||||||
|
outside_list = []
|
||||||
for key, value in hint.items():
|
for key, value in hint.items():
|
||||||
if "Union" in value.__class__.__name__ and (
|
if "Union" in value.__class__.__name__ and (
|
||||||
Calculation in value.__args__ or VariableCalculation in value.__args__
|
Calculation in value.__args__ or VariableCalculation in value.__args__
|
||||||
|
|
|
||||||
|
|
@ -575,10 +575,9 @@ class _VariableCalculation(Calculation):
|
||||||
params["__default_value"] = self.default_values
|
params["__default_value"] = self.default_values
|
||||||
if self.allow_none:
|
if self.allow_none:
|
||||||
params["allow_none"] = True
|
params["allow_none"] = True
|
||||||
if not identifier_is_a_calculation:
|
self.check_multi(
|
||||||
self.check_multi(
|
objectspace, path, variable_in_calculation_path, variable_in_calculation, identifier_is_a_calculation,
|
||||||
objectspace, path, variable_in_calculation_path, variable_in_calculation,
|
)
|
||||||
)
|
|
||||||
if path in objectspace.followers:
|
if path in objectspace.followers:
|
||||||
multi = objectspace.multis[path] == "submulti"
|
multi = objectspace.multis[path] == "submulti"
|
||||||
else:
|
else:
|
||||||
|
|
@ -588,7 +587,7 @@ class _VariableCalculation(Calculation):
|
||||||
return params
|
return params
|
||||||
|
|
||||||
def check_multi(
|
def check_multi(
|
||||||
self, objectspace, path, variable_in_calculation_path, variable_in_calculation
|
self, objectspace, path, variable_in_calculation_path, variable_in_calculation, identifier_is_a_calculation,
|
||||||
):
|
):
|
||||||
local_variable = objectspace.paths[path]
|
local_variable = objectspace.paths[path]
|
||||||
local_variable_multi, variable_in_calculation_multi = (
|
local_variable_multi, variable_in_calculation_multi = (
|
||||||
|
|
@ -596,6 +595,7 @@ class _VariableCalculation(Calculation):
|
||||||
local_variable,
|
local_variable,
|
||||||
variable_in_calculation_path,
|
variable_in_calculation_path,
|
||||||
variable_in_calculation,
|
variable_in_calculation,
|
||||||
|
identifier_is_a_calculation,
|
||||||
objectspace,
|
objectspace,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ def calc_multi_for_type_variable(
|
||||||
local_variable: "Variable",
|
local_variable: "Variable",
|
||||||
variable_in_calculation_path: str,
|
variable_in_calculation_path: str,
|
||||||
variable_in_calculation: "Variable",
|
variable_in_calculation: "Variable",
|
||||||
|
identifier_is_a_calculation: bool,
|
||||||
objectspace: "RougailConvert",
|
objectspace: "RougailConvert",
|
||||||
) -> Union[bool, str]:
|
) -> Union[bool, str]:
|
||||||
variable_in_calculation_multi = variable_in_calculation.multi
|
variable_in_calculation_multi = variable_in_calculation.multi
|
||||||
|
|
@ -192,7 +193,10 @@ def calc_multi_for_type_variable(
|
||||||
common_variable_path = variable_in_calculation_path
|
common_variable_path = variable_in_calculation_path
|
||||||
if common_path:
|
if common_path:
|
||||||
common_variable_path = common_variable_path[len(common_path) + 1 :]
|
common_variable_path = common_variable_path[len(common_path) + 1 :]
|
||||||
count_identifiers = common_variable_path.count("{{ identifier }}")
|
if identifier_is_a_calculation:
|
||||||
|
count_identifiers = 0
|
||||||
|
else:
|
||||||
|
count_identifiers = common_variable_path.count("{{ identifier }}")
|
||||||
if count_identifiers == 1:
|
if count_identifiers == 1:
|
||||||
if variable_in_calculation_multi is False:
|
if variable_in_calculation_multi is False:
|
||||||
variable_in_calculation_multi = True
|
variable_in_calculation_multi = True
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"rougail.var1": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1",
|
||||||
|
"val2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.var2": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": "val1"
|
||||||
|
},
|
||||||
|
"rougail.dynval1.var": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.dynval2.var": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.var3": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"rougail.var1": [
|
||||||
|
"val1",
|
||||||
|
"val2"
|
||||||
|
],
|
||||||
|
"rougail.var2": "val1",
|
||||||
|
"rougail.dynval1.var": [
|
||||||
|
"val1"
|
||||||
|
],
|
||||||
|
"rougail.dynval2.var": [
|
||||||
|
"val2"
|
||||||
|
],
|
||||||
|
"rougail.var3": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"rougail.var1": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1",
|
||||||
|
"val2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.var2": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": "val1"
|
||||||
|
},
|
||||||
|
"rougail.dynval1.var": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.dynval2.var": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rougail.var3": {
|
||||||
|
"owner": "default",
|
||||||
|
"value": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
[]
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"rougail.var1": [
|
||||||
|
"val1",
|
||||||
|
"val2"
|
||||||
|
],
|
||||||
|
"rougail.var2": "val1",
|
||||||
|
"rougail.dynval1.var": [
|
||||||
|
"val1"
|
||||||
|
],
|
||||||
|
"rougail.dynval2.var": [
|
||||||
|
"val2"
|
||||||
|
],
|
||||||
|
"rougail.var3": [
|
||||||
|
"val1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
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_2 = StrOption(name="var1", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
option_3 = StrOption(name="var2", doc="A suffix variable2", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
option_5 = StrOption(name="var", doc="A dynamic variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamIdentifier())))], default_multi=Calculation(func['calc_value'], Params((ParamIdentifier()))), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
optiondescription_4 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="dyn{{ identifier }}", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_2)))), children=[option_5], properties=frozenset({"standard"}), informations={'dynamic_variable': 'rougail.var1', 'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml']})
|
||||||
|
option_6 = StrOption(name="var3", doc="A variable calculated", multi=True, default=Calculation(func['calc_value'], Params((ParamDynOption(option_5, Calculation(func['calc_value'], Params((ParamOption(option_3)), kwargs={'__internal_multi': ParamValue(True)})))), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3, optiondescription_4, option_6], properties=frozenset({"standard"}))
|
||||||
|
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
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_1 = StrOption(name="var1", doc="A suffix variable", multi=True, default=["val1", "val2"], default_multi="val1", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
option_2 = StrOption(name="var2", doc="A suffix variable2", default="val1", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
option_4 = StrOption(name="var", doc="A dynamic variable", multi=True, default=[Calculation(func['calc_value'], Params((ParamIdentifier())))], default_multi=Calculation(func['calc_value'], Params((ParamIdentifier()))), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
optiondescription_3 = ConvertDynOptionDescription(name="dyn{{ identifier }}", doc="dyn{{ identifier }}", identifiers=Calculation(func['calc_value'], Params((ParamOption(option_1)))), children=[option_4], properties=frozenset({"standard"}), informations={'dynamic_variable': 'var1', 'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml']})
|
||||||
|
option_5 = StrOption(name="var3", doc="A variable calculated", multi=True, default=Calculation(func['calc_value'], Params((ParamDynOption(option_4, Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)})))), kwargs={'__internal_multi': ParamValue(True)})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/60_5family_dynamic_calc_identifier_multi/rougail/00-base.yml'], 'type': 'string'})
|
||||||
|
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2, optiondescription_3, option_5])
|
||||||
Loading…
Reference in a new issue