fix: better custom types support

This commit is contained in:
egarette@silique.fr 2026-01-15 08:15:18 +01:00
parent bc27a98229
commit f495642e39
6 changed files with 91 additions and 4 deletions

View file

@ -344,6 +344,8 @@ class ParserVariable:
family_is_leadership: bool = False,
family_is_dynamic: bool = False,
parent_dynamic: Optional[str] = None,
copy_before_set: bool = False,
force_redefine: bool = False,
) -> None:
if name.startswith("_"):
msg = f'the variable or family name "{name}" is incorrect, it must not starts with "_" character'
@ -377,6 +379,8 @@ class ParserVariable:
family_is_leadership=family_is_leadership,
family_is_dynamic=family_is_dynamic,
parent_dynamic=parent_dynamic,
copy_before_set=copy_before_set,
force_redefine=force_redefine,
)
def parse_family(
@ -392,6 +396,8 @@ class ParserVariable:
family_is_leadership: bool = False,
family_is_dynamic: bool = False,
parent_dynamic: Optional[str] = None,
copy_before_set: bool = False,
force_redefine: Union[bool, str] = False,
) -> None:
"""Parse a family"""
if obj is None:
@ -402,7 +408,7 @@ class ParserVariable:
exists = obj.pop("exists", None)
else:
exists = None
redefine = obj.pop("redefine", False)
redefine = obj.pop("redefine", False) or force_redefine is True
obj_type = self.get_family_or_variable_type(obj)
force_to_attrs = list(self.list_attributes(obj, sources, obj_type))
for key, value in obj.items():
@ -427,7 +433,9 @@ class ParserVariable:
"", # comment
family_is_dynamic=family_is_dynamic,
parent_dynamic=parent_dynamic,
copy_before_set=True,
)
force_redefine=True
family_obj["type"] = self.paths[path].type
if path in self.paths:
# it's just for modify subfamily or subvariable, do not redefine
@ -494,7 +502,10 @@ class ParserVariable:
if self.paths[path].type == "leadership":
family_is_leadership = True
for idx, key in enumerate(subfamily_obj):
value = subfamily_obj[key]
if copy_before_set:
value = subfamily_obj[key].copy()
else:
value = subfamily_obj[key]
first_variable = not force_not_first and idx == 0
if isinstance(obj, CommentedMap):
comment = self.get_comment(key, obj)
@ -510,6 +521,8 @@ class ParserVariable:
family_is_leadership=family_is_leadership,
family_is_dynamic=family_is_dynamic,
parent_dynamic=parent_dynamic,
force_redefine=force_redefine,
copy_before_set=copy_before_set,
)
def list_attributes(
@ -657,6 +670,8 @@ class ParserVariable:
family_is_leadership: bool = False,
family_is_dynamic: bool = False,
parent_dynamic: Optional[str] = None,
copy_before_set: bool = False,
force_redefine: bool = False,
) -> None:
"""Parse variable"""
if self.version == "1.0" or isinstance(obj, dict):
@ -684,7 +699,7 @@ class ParserVariable:
self.parse_params(path, obj, sources)
self.parse_secret_manager(path, obj, sources, family_is_dynamic)
exists = obj.pop("exists", None)
redefine = obj.pop("redefine", False)
redefine = obj.pop("redefine", False) or force_redefine is True
if not redefine and not exists:
obj_type = obj.get("type")
if obj_type in self.custom_variable_types:
@ -786,7 +801,16 @@ class ParserVariable:
"""Parse variable params"""
if "params" not in obj:
return
if not isinstance(obj["params"], dict):
if isinstance(obj["params"], list):
for v in obj["params"]:
if not isinstance(v, AnyParam):
raise DictConsistencyError(
_("params must be a dict for {0}").format(path),
55,
sources,
)
return
elif not isinstance(obj["params"], dict):
raise DictConsistencyError(
_("params must be a dict for {0}").format(path),
55,

View file

@ -64,6 +64,8 @@ except ModuleNotFoundError:
def display_xmlfiles(xmlfiles: list) -> str:
"""The function format xmlfiles informations to generate errors"""
if not isinstance(xmlfiles, list):
xmlfiles = [xmlfiles]
if len(xmlfiles) == 1:
return '"' + xmlfiles[0] + '"'
return '"' + '", "'.join(xmlfiles[:-1]) + '"' + " and " + '"' + xmlfiles[-1] + '"'

View file

@ -55,3 +55,15 @@ def test_type_variables():
def test_type_family():
type_variable("family")
def test_type_family_redefine():
type_variable("family_redefine")
def test_type_family_subfamily():
type_variable("family_subfamily")
def test_type_variable_hidden():
type_variable("variable_hidden")

View file

@ -0,0 +1,22 @@
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
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="a_first_variable", doc="a first variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
option_4 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
optiondescription_2 = OptionDescription(name="my_family_1", doc="My family type", children=[option_3, option_4], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
option_6 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml'], 'type': 'string'})
option_7 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml'], 'type': 'string'})
optiondescription_5 = OptionDescription(name="my_family_2", doc="My family type", children=[option_6, option_7], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
option_9 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml'], 'type': 'string'})
option_10 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
optiondescription_8 = OptionDescription(name="my_family_3", doc="My family type", children=[option_9, option_10], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
optiondescription_1 = OptionDescription(name="rougail", doc="rougail", group_type=groups.namespace, children=[optiondescription_2, optiondescription_5, optiondescription_8], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -0,0 +1,8 @@
{
"rougail.my_family_1.a_first_variable": "a modified value",
"rougail.my_family_1.a_second_variable": "a modified value",
"rougail.my_family_2.a_first_variable": "a value",
"rougail.my_family_2.a_second_variable": null,
"rougail.my_family_3.a_first_variable": "a value",
"rougail.my_family_3.a_second_variable": "a modified value 2"
}

View file

@ -0,0 +1,19 @@
%YAML 1.2
---
version: 1.1
my_family_1:
type: my_family_type
a_first_variable: a modified value
a_second_variable: a modified value
my_family_2:
type: my_family_type
my_family_3:
type: my_family_type
a_second_variable: a modified value 2
...