diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py
index 42e77bf9b..d9421d0da 100644
--- a/src/rougail/annotator/family.py
+++ b/src/rougail/annotator/family.py
@@ -26,6 +26,7 @@ along with this program. If not, see .
"""
from typing import Optional
+from tiramisu.error import display_list
from rougail.i18n import _
from rougail.error import DictConsistencyError
from rougail.annotator.variable import Walk
@@ -58,67 +59,35 @@ class Annotator(Walk):
objectspace,
*args,
):
- self.mode_auto = []
- self.objectspace = objectspace
- if not self.objectspace.paths:
+ if not objectspace.paths:
return
- self.check_leadership()
+ self.objectspace = objectspace
+ self.mode_auto = []
self.remove_empty_families()
- self.family_description()
- if self.objectspace.modes_level:
- self.modes = {
- name: Mode(idx) for idx, name in enumerate(self.objectspace.modes_level)
- }
- self.default_variable_mode = self.objectspace.default_variable_mode
- self.default_family_mode = self.objectspace.default_family_mode
- self.change_modes()
- else:
- for family in self.get_families():
- self.valid_mode(family)
- for variable in self.get_variables():
- self.valid_mode(variable)
+ self.check_leadership()
+ self.families_description()
+ self.set_modes()
self.convert_help()
+ def remove_empty_families(self) -> None:
+ """Remove all families without any variable"""
+ for family in reversed(list(self.get_families())):
+ path = family.path
+ if not self.objectspace.parents[path]:
+ self.objectspace.del_family(path)
+
def check_leadership(self) -> None:
"""No subfamily in a leadership"""
for family in self.get_families():
if family.type != "leadership":
continue
for variable_path in self.objectspace.parents[family.path]:
- variable = self.objectspace.paths[variable_path]
- if variable.type in self.objectspace.family_types:
- msg = f'the leadership "{family.path}" cannot have the { variable.type } "{ variable.path}"'
+ if variable_path in self.objectspace.families:
+ variable = self.objectspace.paths[variable_path]
+ msg = f'the leadership "{family.path}" cannot have the "{variable.type}" "{variable.path}"'
raise DictConsistencyError(msg, 24, variable.xmlfiles)
- def remove_empty_families(self) -> None:
- """Remove all families without any variable"""
- removed_families = []
- for family in self.get_families():
- if isinstance(family, self.objectspace.family) and not self._has_variable(
- family.path
- ):
- if (
- self.objectspace.paths.default_namespace is None
- or "." in family.path
- ):
- removed_families.append(family.path)
- removed_families.reverse()
- for family in removed_families:
- self.objectspace.del_family(family)
-
- def _has_variable(
- self,
- family: str,
- ) -> bool:
- for variable in self.objectspace.parents[family]:
- if variable in self.objectspace.families:
- if self._has_variable(variable):
- return True
- else:
- return True
- return False
-
- def family_description(self) -> None:
+ def families_description(self) -> None:
for family in self.get_families():
if not family.description:
family.description = family.name
@@ -144,28 +113,45 @@ class Annotator(Walk):
if family.xmlfiles:
self.objectspace.informations.add(family.path, "ymlfiles", family.xmlfiles)
- def change_modes(self):
- """change the mode of variables"""
- modes_level = self.objectspace.modes_level
- default_variable_mode = self.default_variable_mode
- if default_variable_mode not in modes_level:
+ def set_modes(self):
+ if self.objectspace.modes_level:
+ self.configure_modes()
+ self.change_modes()
+ else:
+ self.modes = {}
+ for family in self.get_families():
+ self.valid_mode(family)
+ for variable in self.get_variables():
+ self.valid_mode(variable)
+
+ def configure_modes(self):
+ modes = self.modes = {
+ name: Mode(idx) for idx, name in enumerate(self.objectspace.modes_level)
+ }
+ default_variable_mode = self.default_variable_mode = self.objectspace.default_variable_mode
+ default_family_mode = self.default_family_mode = self.objectspace.default_family_mode
+ list_modes = list(modes)
+ if default_variable_mode not in list_modes:
msg = _(
'default variable mode "{0}" is not a valid mode, valid modes are {1}'
- ).format(default_variable_mode, modes_level)
+ ).format(default_variable_mode, display_list(list_modes, add_quote=True))
raise DictConsistencyError(msg, 72, None)
- default_family_mode = self.default_family_mode
- if default_family_mode not in modes_level:
+ if default_family_mode not in list_modes:
msg = _(
'default family mode "{0}" is not a valid mode, valid modes are {1}'
- ).format(default_family_mode, modes_level)
+ ).format(default_family_mode, display_list(list_modes, add_quote=True))
raise DictConsistencyError(msg, 73, None)
+ self.lower_mode = list_modes[0]
+ self.higher_mode = list_modes[-1]
+
+ def change_modes(self):
+ """change the mode of variables and families"""
families = list(self.get_families())
for family in families:
self.valid_mode(family)
- self._set_default_mode(family)
- families.reverse()
- for family in families:
- self._change_family_mode(family)
+ self.set_default_mode(family)
+ for family in reversed(families):
+ self.change_family_mode(family)
if self.objectspace.paths.default_namespace is None:
for variable_path in self.objectspace.parents["."]:
variable = self.objectspace.paths[variable_path]
@@ -174,7 +160,8 @@ class Annotator(Walk):
or variable_path in self.objectspace.families
):
continue
- self._set_default_mode_variable(
+ self.valid_mode(variable)
+ self.set_default_mode_variable(
variable,
self.default_variable_mode,
check_level=False,
@@ -184,55 +171,55 @@ class Annotator(Walk):
self,
obj,
) -> None:
- modes_level = self.objectspace.modes_level
- if self._has_mode(obj) and obj.mode not in modes_level:
- if modes_level:
+ if not self.modes:
+ if self.has_mode(obj):
msg = _(
'mode "{0}" for "{1}" is not a valid mode, valid modes are {2}'
- ).format(obj.mode, obj.name, modes_level)
- else:
- msg = _(
- 'mode "{0}" for "{1}" is not a valid mode, no modes are available'
- ).format(obj.mode, obj.name)
+ ).format(obj.mode, obj.name, display_list(list(self.modes), add_quote=True))
+ raise DictConsistencyError(msg, 71, obj.xmlfiles)
+ elif self.has_mode(obj) and obj.mode not in self.modes:
+ msg = _(
+ 'mode "{0}" for "{1}" is not a valid mode, no modes are available'
+ ).format(obj.mode, obj.name)
raise DictConsistencyError(msg, 71, obj.xmlfiles)
- def _set_default_mode(
+ def set_default_mode(
self,
family: "self.objectspace.family",
) -> None:
- children = self.objectspace.parents[family.path]
- if not children:
- return
- if self._has_mode(family):
+ if self.has_mode(family):
family_mode = family.mode
else:
family_mode = None
- leader = None
- for variable_path in children:
- variable = self.objectspace.paths[variable_path]
- if variable.type == "symlink":
+ is_leadership = family.type == "leadership"
+ if is_leadership:
+ leader = None
+ for child_path in self.objectspace.parents[family.path]:
+ child = self.objectspace.paths[child_path]
+ if child.type == "symlink":
continue
- if leader is None and family.type == "leadership":
- leader = variable
+ if is_leadership and leader is None:
+ leader = child
leader_mode = leader.mode
- if variable_path in self.objectspace.families:
+ if child_path in self.objectspace.families:
# set default mode a subfamily
- if family_mode and not self._has_mode(variable):
- self._set_auto_mode(variable, family_mode)
+ if family_mode and not self.has_mode(child):
+ self.set_auto_mode(child, family_mode)
else:
# set default mode to a variable
- self.valid_mode(variable)
- if leader:
- self._set_default_mode_leader(leader, variable)
- self._set_default_mode_variable(variable, family_mode)
- if leader and leader_mode is not None:
- # here because follower can change leader mode
- self._set_auto_mode(family, leader_mode)
+ self.valid_mode(child)
+ if is_leadership and leader:
+ self.set_default_mode_leader(leader, child)
+ self.set_default_mode_variable(child, family_mode)
+ if is_leadership and leader_mode is not None:
+ # here because follower can change leadership mode
+ self.set_auto_mode(family, leader_mode)
- def _has_mode(self, obj) -> bool:
+ def has_mode(self, obj) -> bool:
+ # the mode is set in the structural file
return obj.mode and not obj.path in self.mode_auto
- def _set_default_mode_variable(
+ def set_default_mode_variable(
self,
variable: "self.objectspace.variable",
family_mode: Optional[str],
@@ -240,16 +227,16 @@ class Annotator(Walk):
) -> None:
# auto_save variable is set to 'basic' mode
# if its mode is not defined by the user
- if not self._has_mode(variable) and variable.auto_save is True:
- variable.mode = self.objectspace.modes_level[0]
+ if not self.has_mode(variable) and variable.auto_save is True:
+ variable.mode = self.lower_mode
# mandatory variable without value is a basic variable
elif (
- not self._has_mode(variable)
+ not self.has_mode(variable)
and variable.mandatory is True
and variable.default is None
and variable.path not in self.objectspace.default_multi
):
- variable_mode = self.objectspace.modes_level[0]
+ variable_mode = self.lower_mode
if (
check_level
and family_mode
@@ -261,18 +248,19 @@ class Annotator(Walk):
raise DictConsistencyError(msg, 36, variable.xmlfiles)
variable.mode = variable_mode
- elif family_mode and not self._has_mode(variable):
- self._set_auto_mode(variable, family_mode)
+ elif family_mode and not self.has_mode(variable):
+ self.set_auto_mode(variable, family_mode)
- def _set_auto_mode(
+ def set_auto_mode(
self,
obj,
mode: str,
) -> None:
+ # This mode is set automaticly
obj.mode = mode
self.mode_auto.append(obj.path)
- def _set_default_mode_leader(
+ def set_default_mode_leader(
self,
leader: "self.objectspace.variable",
follower: "self.objectspace.variable",
@@ -280,26 +268,26 @@ class Annotator(Walk):
if leader == follower:
# it's a leader
if not leader.mode:
- self._set_auto_mode(leader, self.default_variable_mode)
+ self.set_auto_mode(leader, self.default_variable_mode)
return
- if self._has_mode(follower):
+ if self.has_mode(follower):
follower_mode = follower.mode
else:
follower_mode = self.default_variable_mode
if self.modes[leader.mode] > self.modes[follower_mode]:
- if self._has_mode(follower) and not self._has_mode(leader):
+ if self.has_mode(follower) and not self.has_mode(leader):
# if follower has mode but not the leader
- self._set_auto_mode(leader, follower_mode)
+ self.set_auto_mode(leader, follower_mode)
else:
# leader's mode is minimum level
- if self._has_mode(follower):
+ if self.has_mode(follower):
msg = _(
'the follower "{0}" is in "{1}" mode but leader have the higher mode "{2}"'
).format(follower.name, follower_mode, leader.mode)
raise DictConsistencyError(msg, 63, follower.xmlfiles)
- self._set_auto_mode(follower, leader.mode)
+ self.set_auto_mode(follower, leader.mode)
- def _change_family_mode(
+ def change_family_mode(
self,
family: "self.objectspace.family",
) -> None:
@@ -307,31 +295,29 @@ class Annotator(Walk):
family_mode = family.mode
else:
family_mode = self.default_family_mode
- min_variable_mode = self.objectspace.modes_level[-1]
- # change variable mode, but not if variables are not in a family
+ min_variable_mode = self.higher_mode
is_leadership = family.type == "leadership"
- if family.path in self.objectspace.parents:
- for variable_path in self.objectspace.parents[family.path]:
- variable = self.objectspace.paths[variable_path]
- if variable.type == "symlink":
- continue
- if variable_path in self.objectspace.families:
- if not variable.mode:
- variable.mode = self.default_family_mode
- else:
- self._change_variable_mode(variable, family_mode, is_leadership)
- if self.modes[min_variable_mode] > self.modes[variable.mode]:
- min_variable_mode = variable.mode
+ for child_path in self.objectspace.parents[family.path]:
+ child = self.objectspace.paths[child_path]
+ if child.type == "symlink":
+ continue
+ if child_path in self.objectspace.families:
+ if not child.mode:
+ child.mode = self.default_family_mode
+ else:
+ self.change_variable_mode(child, family_mode, is_leadership)
+ if self.modes[min_variable_mode] > self.modes[child.mode]:
+ min_variable_mode = child.mode
if not family.mode:
# set the lower variable mode to family
- self._set_auto_mode(family, min_variable_mode)
+ self.set_auto_mode(family, min_variable_mode)
if self.modes[family.mode] < self.modes[min_variable_mode]:
msg = _(
'the family "{0}" is in "{1}" mode but variables and families inside have the higher modes "{2}"'
).format(family.name, family.mode, min_variable_mode)
raise DictConsistencyError(msg, 62, family.xmlfiles)
- def _change_variable_mode(
+ def change_variable_mode(
self,
variable,
family_mode: str,
@@ -343,12 +329,12 @@ class Annotator(Walk):
variable_mode = self.default_variable_mode
# none basic variable in high level family has to be in high level
if not is_follower and self.modes[variable_mode] < self.modes[family_mode]:
- if self._has_mode(variable):
+ if self.has_mode(variable):
msg = _(
'the variable "{0}" is in "{1}" mode but family has the higher family mode "{2}"'
).format(variable.path, variable_mode, family_mode)
raise DictConsistencyError(msg, 61, variable.xmlfiles)
- self._set_auto_mode(variable, family_mode)
+ self.set_auto_mode(variable, family_mode)
if not variable.mode:
variable.mode = variable_mode
diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py
index 25c73f2ad..737bc71a4 100644
--- a/src/rougail/annotator/variable.py
+++ b/src/rougail/annotator/variable.py
@@ -148,7 +148,7 @@ class Annotator(Walk): # pylint: disable=R0903
variable.default.get_variable(self.objectspace, variable.path)
)
if calculated_variable is not None:
- self._default_variable_copy_informations(
+ variable = self._default_variable_copy_informations(
variable, calculated_variable
)
self._convert_variable(variable)
@@ -210,12 +210,12 @@ class Annotator(Walk): # pylint: disable=R0903
# variable has no type
if variable.type is not None:
return
- # choice type inference from the `choices` attribute
- if variable.choices is not None:
- variable.type = "choice"
- elif variable.regexp is not None:
- variable.type = "regexp"
- elif variable.default not in [None, []]:
+ ## choice type inference from the `choices` attribute
+ #if variable.choices is not None:
+ # variable.type = "choice"
+ #elif variable.regexp is not None:
+ # variable.type = "regexp"
+ if variable.default not in [None, []]:
if isinstance(variable.default, list):
tested_value = variable.default[0]
else:
@@ -274,7 +274,14 @@ class Annotator(Walk): # pylint: disable=R0903
calculated_variable,
) -> None:
# copy type and params
- variable.type = calculated_variable.type
+ calculated_type = calculated_variable.__class__
+ if variable.__class__ == calculated_type:
+ variable.type = calculated_variable.type
+ else:
+ data = dict(variable)
+ data["type"] = calculated_variable.type
+ variable = calculated_type(**data)
+ self.objectspace.paths.replace(data["path"], variable)
if variable.params is None and calculated_variable.params is not None:
variable.params = calculated_variable.params
if variable.type == "choice" and variable.choices is None:
@@ -287,6 +294,7 @@ class Annotator(Walk): # pylint: disable=R0903
)
if variable.type == "regexp" and variable.regexp is None:
variable.regexp = calculated_variable.regexp
+ return variable
def _convert_variable(
self,
@@ -306,11 +314,11 @@ class Annotator(Walk): # pylint: disable=R0903
self.objectspace.multis[variable.path] = "submulti"
elif variable.multi:
self.objectspace.multis[variable.path] = True
- if variable.regexp is not None and variable.type != "regexp":
- msg = _(
- 'the variable "{0}" has regexp attribut but has not the "regexp" type'
- ).format(variable.path)
- raise DictConsistencyError(msg, 37, variable.xmlfiles)
+# if variable.regexp is not None and variable.type != "regexp":
+# msg = _(
+# 'the variable "{0}" has regexp attribut but has not the "regexp" type'
+# ).format(variable.path)
+# raise DictConsistencyError(msg, 37, variable.xmlfiles)
if variable.mandatory is None:
variable.mandatory = True
@@ -346,14 +354,10 @@ class Annotator(Walk): # pylint: disable=R0903
def verify_choices(self):
for variable in self.get_variables():
- if variable.type is None and variable.choices:
- # choice type inference from the `choices` attribute
- variable.type = "choice"
- if variable.choices is not None and variable.type != "choice":
- msg = _(
- 'the variable "{0}" has choices attribut but has not the "choice" type'
- ).format(variable.path)
- raise DictConsistencyError(msg, 11, variable.xmlfiles)
+ # FIXME
+# if variable.type is None and variable.choices:
+# # choice type inference from the `choices` attribute
+# variable.type = "choice"
if variable.type != "choice":
continue
if variable.default is None:
diff --git a/src/rougail/config/__init__.py b/src/rougail/config/__init__.py
index d213c0584..1869ca044 100644
--- a/src/rougail/config/__init__.py
+++ b/src/rougail/config/__init__.py
@@ -435,7 +435,7 @@ secret_manager: # {_("The secret manager")}
"output": [],
}
processes_tr = {"structural": _("structural"),
- "user data": _("user datas"),
+ "user data": _("user data"),
"output": _("output"),
}
processes_empty = []
@@ -469,10 +469,9 @@ secret_manager: # {_("The secret manager")}
for obj in objects:
rougail_process += f" - {obj['name']}\n"
if process == "structural":
- rougail_process += """ commandline: false
- multi: true
+ rougail_process += """ multi: true
default:
- - directory
+ - directory
"""
elif process == "user data":
rougail_process += """ multi: true
@@ -590,7 +589,7 @@ def _rougail_config(
options = obj["options"]
for option in options:
convert.parse_root_file(
- [f'rougail.config.{obj["name"]}'],
+ [f'rougail.{obj["process"].replace(" ", "_")}_{obj["name"]}.config'],
"",
"1.1",
YAML().load(option),
diff --git a/src/rougail/convert/__init__.py b/src/rougail/convert/__init__.py
index 5ccb5c64f..edbe10dec 100644
--- a/src/rougail/convert/__init__.py
+++ b/src/rougail/convert/__init__.py
@@ -41,7 +41,7 @@ class Rougail(UserData):
self.load_from_tiramisu_cache = load_from_tiramisu_cache and Path(self.rougailconfig["tiramisu_cache"]).is_file()
types = rougail_type(self.rougailconfig)
if not self.load_from_tiramisu_cache:
- self.converted = RougailConvert(self.rougailconfig, *types)
+ self.converted = RougailConvert(self.rougailconfig, **types)
self.config = None
def get_root_option(self):
diff --git a/src/rougail/convert/collect.py b/src/rougail/convert/collect.py
new file mode 100644
index 000000000..b6a682e1e
--- /dev/null
+++ b/src/rougail/convert/collect.py
@@ -0,0 +1,687 @@
+"""Takes a bunch of Rougail YAML dispatched in differents folders
+as an input and outputs a Tiramisu's file.
+
+Silique (https://www.silique.fr)
+Copyright (C) 2026
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see .
+"""
+import logging
+from warnings import warn
+from pydantic import ValidationError
+from copy import deepcopy
+from typing import (
+ Any,
+ Iterator,
+ Literal,
+ Optional,
+)
+from tiramisu.error import display_list
+from .object_model import (
+ CALCULATION_TYPES,
+ CALCULATION_PROPERTY_TYPES,
+ PROPERTY_ATTRIBUTE,
+ PARAM_TYPES,
+ AnyParam,
+)
+from ..i18n import _
+from ..error import DictConsistencyError
+
+
+class CollectFamily:
+ def family_collect(self) -> None:
+ if self.parameters is None:
+ self.parameters = {}
+ if self.user_type == "dynamic":
+ # FIXME code here only for support 1.0 dynamic flavor
+ # DictConsistencyError should be place in annotation
+ if "{{ identifier }}" not in self.name:
+ if "{{ suffix }}" in self.name:
+ self.name = self.name.replace("{{ suffix }}", "{{ identifier }}")
+ self.path = self.path.replace("{{ suffix }}", "{{ identifier }}")
+ elif "variable" in self.parameters:
+ self.name += "{{ identifier }}"
+ self.path += "{{ identifier }}"
+ else:
+ msg = f'dynamic family name must have "{{{{ identifier }}}}" in his name for "{self.path}"'
+ raise DictConsistencyError(msg, 13, self.sources)
+ if self.version == "1.0":
+ if "variable" not in self.parameters:
+ raise DictConsistencyError(
+ f'dynamic family must have "variable" attribute for "{self.path}"',
+ 101,
+ self.sources,
+ )
+ if "dynamic" in self.parameters:
+ raise DictConsistencyError(
+ 'variable and dynamic cannot be set together in the dynamic family "{self.path}"',
+ 100,
+ self.sources,
+ )
+ self.parameters["dynamic"] = {
+ "type": "variable",
+ "variable": self.parameters["variable"],
+ "propertyerror": False,
+ "allow_none": True,
+ }
+ del self.parameters["variable"]
+ if "variable" in self.parameters:
+ self.parameters["dynamic"] = {
+ "type": "variable",
+ "variable": self.parameters["variable"],
+ "propertyerror": False,
+ "allow_none": True,
+ }
+ del self.parameters["variable"]
+ if self.version != "1.0":
+ warning = f'"variable" attribute in dynamic family "{self.path}" is depreciated in {display_list(self.sources)}'
+ warn(
+ warning,
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ self.object = self.objectspace.family_objects[0]
+ else:
+ self.object = self.objectspace.family_objects[-1]
+ self.split_param_family_children()
+
+ def split_param_family_children(
+ self,
+ ) -> None:
+ """Family declaration mix variable object and family attributes
+ Here we separate attribute (which is the correct self.parameters content and variable declaration
+ """
+ new_parameters = {}
+ children = self.parameters
+ # when an attribute starts with "_", the variable name without this "_" is a variable
+ sub_variables = [key[1:] for key in self.parameters if key.startswith('_') and key[1:] in self.parameters]
+ # and known variables
+ if self.path in self.objectspace.paths:
+ sub_variables.extend([p.rsplit('.', 1)[-1] for p in self.objectspace.parents[self.path]])
+ attributes = self.object["attrs"]
+ attributes_types = self.object["attributes_types"]
+ if self.types:
+ types_children = list(self.types.children)
+ else:
+ types_children = []
+ for key, value in list(children.items()):
+ if not isinstance(key, str):
+ raise DictConsistencyError(
+ f'the key "{key}" is not in string format for family {self.path}',
+ 103,
+ self.sources,
+ )
+ if key.startswith("_"):
+ # if key starts with _, it's an attribute
+ if key == "_type" and self.types:
+ children.pop(key)
+ else:
+ new_parameters[key[1:]] = children.pop(key)
+ elif key in types_children or \
+ key not in attributes or \
+ key in sub_variables or \
+ not self.parameter_is_an_attributes(key, value, attributes_types):
+ if key == "type" and self.types and key not in types_children:
+ children.pop(key)
+ else:
+ new_parameters[key] = children.pop(key)
+ if self.version != "1.0" and not new_parameters and self.comment:
+ new_parameters["description"] = self.comment
+ self.children = children
+ self.parameters = new_parameters
+
+
+class CollectVariable:
+ def variable_collect(self) -> None:
+ obj = self.parameters
+ if self.version == "1.0" or isinstance(obj, dict):
+ if obj is None:
+ # only with self.version to 1.0
+ obj = {}
+ self.parameters = obj
+ self.parse_type_params()
+ self.parse_secret_manager()
+ if not self.check_no_extra_keys:
+ extra_attrs = set(obj) - self.object["attrs"]
+ if extra_attrs:
+ raise DictConsistencyError(
+ f'"{self.path}" is not a valid variable, there are additional '
+ f'attributes: "{", ".join(extra_attrs)}"',
+ 65,
+ self.sources,
+ )
+ else:
+ self.parameters = {"default": obj}
+ if self.comment:
+ self.parameters["description"] = self.comment
+
+ def parse_type_params(self):
+ """Parse variable params"""
+ if "params" not in self.parameters:
+ return
+ params = self.parameters["params"]
+ if isinstance(params, list):
+ # the conversion has already be done (in types purpose)
+ for param in params:
+ if not isinstance(param, AnyParam):
+ raise DictConsistencyError(
+ _("params must be a dict for {0}").format(self.path),
+ 55,
+ self.sources,
+ )
+ return
+ elif not isinstance(params, dict):
+ raise DictConsistencyError(
+ _("params must be a dict for {0}").format(self.path),
+ 55,
+ self.sources,
+ )
+ new_params = []
+ namespace = self.objectspace.namespace
+ for key, val in params.items():
+ try:
+ new_params.append(
+ AnyParam(
+ key=key,
+ value=val,
+ type="any",
+ path=None,
+ attribute=None,
+ family_is_dynamic=None,
+ namespace=namespace,
+ xmlfiles=self.sources,
+ )
+ )
+ except ValidationError as err:
+ raise DictConsistencyError(
+ _('"{0}" has an invalid "params" for {1}: {2}').format(
+ key, self.path, err
+ ),
+ 54,
+ self.sources,
+ ) from err
+ self.parameters["params"] = new_params
+
+ def parse_secret_manager(self):
+ """Parse variable secret_manager"""
+ if "secret_manager" not in self.parameters:
+ return
+ secret_manager = {
+ "type": "jinja",
+ "jinja": self.objectspace.secret_pattern,
+ "params": self.parameters["secret_manager"],
+ }
+ self.set_calculation(
+ "secret_manager",
+ secret_manager,
+ )
+
+class CollectType:
+ """Determine the option type
+ 1/ self.option_type must be "variable" or "family" option type
+ needs to determinate if the option is a variable or a family
+ an option is a family if:
+ - user specified a know family type: family, leadership (user must set it explicitly) or dynamic)
+ - has a family custom type
+ - has "dynamic" attribute (a variable could not has dynamic attribut)
+ - it's already a family (so we are certainly in redefine purpose
+ otherwise it's a variable
+ 2/ self.user_type must be a more specilized variable or family type defined by the user
+ """
+
+ def set_option_types(self):
+ if isinstance(self.parameters, dict):
+ self.set_user_type()
+ self.set_dynamic_user_type()
+ else:
+ self.short_hand_variable()
+ self.set_user_redefined()
+ self.variable_in_leadership()
+ self.family_or_variable()
+ if self.user_type:
+ logging.info("family_or_variable: %s is a %s (%s)", self.path, self.option_type, self.user_type)
+ else:
+ logging.info("family_or_variable: %s is a %s", self.path, self.option_type)
+
+ def set_user_type(
+ self,
+ ) -> None:
+ """Check 'type' attributes and determine the option type"""
+ for type_name in ["_type", "type"]:
+ if type_name not in self.parameters or not isinstance(self.parameters[type_name], str):
+ continue
+ self.user_type = self.parameters[type_name]
+ if self.user_type in self.objectspace.custom_family_types:
+ self.set_custom_type(self.objectspace.custom_family_types[self.user_type])
+ if self.user_type is None:
+ self.object = self.objectspace.family_objects[-1]
+ else:
+ self.set_object_user_type_family()
+ break
+ elif self.user_type in self.objectspace.custom_variable_types:
+ self.set_custom_type(self.objectspace.custom_variable_types[self.user_type])
+ if self.user_type is None:
+ self.object = self.objectspace.variable_objects[0]
+ else:
+ self.set_object_user_type_variable()
+ break
+ self.object = None
+ self.set_object_user_type_family()
+ if not self.object:
+ self.set_object_user_type_variable()
+ if not self.object:
+ msg = _('cannot determine the type of the {0} "{1}"').format(self.user_type, self.path)
+ raise DictConsistencyError(msg, 43, self.sources)
+ break
+
+ def set_custom_type(self, custom: dict) -> None:
+ if self.path in self.objectspace.paths:
+ msg = f'cannot redefine "{self.path}" object to a custom type'
+ raise DictConsistencyError(msg, 64, self.sources)
+ self.types = custom
+ self.types.name = self.name
+ self.types.path = self.path
+ self.types.namespace = self.namespace
+ self.option_type = self.types.option_type
+ self.user_type = self.types.user_type
+ self.sources = self.types.sources + self.sources
+ self.object = self.types.object
+ if self.option_type == "variable" and "type" in self.parameters:
+ self.parameters.pop("type")
+
+ def set_object_user_type_family(self):
+ for obj in self.objectspace.family_objects:
+ if self.user_type in obj["types"]:
+ self.option_type = "family"
+ self.object = obj
+ return
+
+ def set_object_user_type_variable(self):
+ for obj in self.objectspace.variable_objects:
+ if self.user_type in obj["types"]:
+ self.option_type = "variable"
+ self.object = obj
+ return
+
+ def set_dynamic_user_type(self) -> None:
+ if self.user_type:
+ return
+ for type_name in ["_dynamic", "dynamic"]:
+ if type_name in self.parameters and isinstance(self.parameters[type_name], (list, dict)):
+ self.user_type = "dynamic"
+ self.option_type = "family"
+ break
+
+ def set_user_redefined(self) -> None:
+ if self.path not in self.objectspace.paths:
+ return
+ # it's already a variable or a family
+ old_option_type = self.option_type if self.user_type else None
+ self.option_type = "family" if self.path in self.objectspace.families else "variable"
+ if old_option_type and self.option_type != old_option_type:
+ msg = f'the {old_option_type} "{self.path}" is redefine as a {self.option_type}, which is not allowed'
+ raise DictConsistencyError(msg, 11, self.sources)
+ if self.user_type:
+ return
+ self.user_type = self.objectspace.paths[self.path].type
+ if self.option_type == "family":
+ for obj in self.objectspace.family_objects:
+ if self.user_type in obj["types"]:
+ self.object = obj
+ break
+ else:
+ self.object = self.objectspace.variable_objects[0]
+ else:
+ for obj in self.objectspace.variable_objects:
+ if self.user_type in obj["types"]:
+ self.object = obj
+ break
+ else:
+ self.object = self.objectspace.variable_objects[-1]
+
+ def short_hand_variable(self):
+ if self.option_type:
+ return
+ # it's something like: "my_variable:" or "my_variable: True"
+ self.option_type = "variable"
+ self.object = self.objectspace.variable_objects[0]
+
+ def variable_in_leadership(self):
+ # in a leadership there have only variables
+ if not self.option_type and self.family_is_leadership:
+ self.option_type = "variable"
+ if not self.find_variable_object():
+ msg = f'"{self.path}" seems to be a family, which is not allowed in a family'
+ raise DictConsistencyError(msg, 17, self.sources)
+
+ def family_or_variable(
+ self,
+ ) -> Literal["variable", "family"]:
+ """check if all attributes are attributes of a variable"""
+ if self.option_type:
+ return
+ if not self.find_variable_object():
+ self.option_type = "family"
+
+ def find_variable_object(self) -> bool:
+ attrs = set(self.parameters)
+ for variable in self.objectspace.variable_objects:
+ if not attrs - variable["attrs"] and self.check_variable_parameters(variable):
+ self.option_type = "variable"
+ self.check_no_extra_keys = True
+ self.object = variable
+ return True
+ return False
+
+ def check_variable_parameters(self, variable):
+ attributes_types = variable["attributes_types"]
+ attrs = variable["attrs"]
+ for key, value in list(self.parameters.items()):
+ if key not in attrs:
+ return False
+ if not self.parameter_is_an_attributes(key, value, attributes_types):
+ return False
+ return True
+
+ def parameter_is_an_attributes(self, key: str, value: Any, attributes_types: dict) -> bool:
+ if value is None:
+ return True
+ if key in attributes_types["literals"] and value in attributes_types["literals"][key]:
+ return True
+ for k, typ in [("strings", str), ("booleans", bool), ("integers", int), ("floats", float)]:
+ if key in attributes_types[k] and isinstance(value, typ):
+ return True
+ if isinstance(value, dict):
+ if key in attributes_types["calculation"]:
+ return self.is_calculation(key, value, attributes_types=attributes_types)
+ if key in attributes_types["params"]:
+ return True
+ if isinstance(value, list):
+ current_value = value.copy()
+ for k, typ in [("strings", str), ("booleans", bool), ("integers", int), ("floats", float)]:
+ if key in attributes_types["lists"][k]:
+ for idx, val in reversed(list(enumerate(current_value))):
+ if val is not None and not isinstance(val, typ):
+ continue
+ del current_value[idx]
+ if not current_value:
+ return True
+ if key in attributes_types["lists"]["calculation"]:
+ for val in current_value:
+ if isinstance(val, dict) and not self.is_calculation(key, val, inside_list=True, attributes_types=attributes_types):
+ return False
+ return True
+ return False
+
+
+class Collect(CollectType, CollectFamily, CollectVariable):
+ def __init__(
+ self,
+ objectspace: "ParserVariable",
+ name: str,
+ subpath: Optional[str],
+ parameters: dict,
+ comment: Optional[str],
+ parent_option: Optional[Collect],
+ ) -> None:
+ self.sources_types = None
+ self.types = None
+ self.name = name
+ if not subpath:
+ path = name
+ else:
+ path = f"{subpath}.{name}"
+ if name.startswith("_"):
+ msg = f'the variable or family "{self.path}" is incorrect, it must not starts with "_" character'
+ raise DictConsistencyError(msg, 16, obj["sources"])
+ self.path = path
+ self.subpath = subpath
+ self.parameters = parameters
+ self.comment = comment
+ self.objectspace = objectspace
+ self.namespace = objectspace.namespace
+ self.sources = objectspace.sources.copy()
+ self.user_type = None
+ self.option_type = None
+ if parent_option is not None and parent_option.types is not None and self.name in parent_option.types.children:
+ self.set_custom_type(parent_option.types.children[self.name])
+ self.check_no_extra_keys = False
+ if path in objectspace.paths:
+ for source in reversed(self.objectspace.paths[path].xmlfiles):
+ self.sources.insert(0, source)
+ if parent_option:
+ self.family_is_leadership = parent_option.user_type == "leadership"
+ self.family_is_dynamic = parent_option.family_is_dynamic
+ self.parent_dynamic = parent_option.parent_dynamic
+ else:
+ self.family_is_leadership = False
+ self.family_is_dynamic = False
+ self.parent_dynamic = None
+ self.version = self.objectspace.version
+ self.set_option_types()
+ if self.user_type == "dynamic":
+ self.family_is_dynamic = True
+ self.parent_dynamic = subpath
+ if self.option_type == "family":
+ self.family_collect()
+ else:
+ self.variable_collect()
+ self.convert_calculated_parameters()
+ self.exists = self.is_exists()
+ self.redefine = self.is_redefine()
+
+ def convert_calculated_parameters(
+ self,
+ ):
+ """Parse option attributes and convert calculation"""
+ obj = self.parameters
+ for key, value in obj.items():
+ if self.is_calculation(
+ key,
+ value,
+ ):
+ try:
+ self.set_calculation(
+ key,
+ value,
+ )
+ except ValidationError as err:
+ raise DictConsistencyError(
+ _('the {0} "{1}" has an invalid "{2}": {3}').format(self.option_type, self.path, key, err),
+ 84,
+ self.sources,
+ ) from err
+ continue
+ if not isinstance(value, list):
+ continue
+ for idx, val in enumerate(value):
+ if not self.is_calculation(
+ key,
+ val,
+ inside_list=True,
+ ):
+ continue
+ try:
+ self.set_calculation(
+ key,
+ val,
+ inside_list=True,
+ index=idx,
+ )
+ except ValidationError as err:
+ raise Exception(
+ f'the {option.type} "{option.path}" in "{display_list(option.sources)}" has an invalid "{key}" '
+ f"at index {idx}: {err}"
+ ) from err
+
+ def is_dict(self, key: str, value: Any, *, attributes_types: Optional[dict]=None) -> bool:
+ """it's a dict, so it's a new variables!"""
+ return isinstance(value, dict) and not self.is_calculation(key, value, attributes_types=attributes_types)
+
+ def is_calculation(
+ self,
+ attribute: str,
+ value: dict,
+ *,
+ attributes_types: Optional[dict]=None,
+ inside_list: bool=False,
+ ):
+ """Check if it's a calculation"""
+ if not isinstance(value, dict):
+ return False
+ if attributes_types is None:
+ attributes_types = self.object["attributes_types"]
+ if inside_list:
+ attributes_types = attributes_types["lists"]["calculation"]
+ else:
+ attributes_types = attributes_types["calculation"]
+ if attribute not in attributes_types:
+ return False
+ return self.manage_calculation_type(value)
+
+ def manage_calculation_type(self, value) -> bool:
+ """Return true if the dict type is a calculation
+ If user set the type, it's easy, we just have to check if it's a known calculation type
+ Otherwise if we have an attribute with a known calculation type, we assume that is de calculation type
+ """
+ if "type" in value:
+ return value["type"] in CALCULATION_TYPES
+ # auto set type
+ typ = set(CALCULATION_TYPES) & set(value)
+ # XXX variable could have identifier
+ if typ == {"variable", "identifier"}:
+ typ = {"variable"}
+ # XXX variable is also set to information
+ if typ == {"variable", "information"}:
+ typ = {"information"}
+ if len(typ) == 1:
+ value["type"] = typ.pop()
+ return True
+ return False
+
+ def set_calculation(
+ self,
+ attribute: str,
+ value: dict,
+ *,
+ obj: Optional[dict] = None,
+ inside_list: bool = False,
+ index: int = None,
+ ):
+ """This variable is a calculation"""
+ if obj is None:
+ obj = self.parameters
+ calculation_object = value.copy()
+ typ = calculation_object.pop("type")
+ namespace = self.objectspace.namespace
+
+ calculation_object["attribute_name"] = attribute
+ calculation_object["inside_list"] = inside_list
+ calculation_object["version"] = self.version
+ calculation_object["namespace"] = namespace
+ calculation_object["xmlfiles"] = self.sources
+ #
+ self.set_identifier_calculation_in_default_attribut(attribute, calculation_object, inside_list, index)
+ self.set_params_calculation(calculation_object, attribute)
+ #
+ return_type = calculation_object.get("return_type")
+ if return_type and return_type not in self.objectspace.variable_objects[0]["types"]:
+ raise Exception(
+ f'unknown "return_type" in {attribute} of variable "{self.path}"'
+ )
+ #
+ if typ == "identifier" and not self.family_is_dynamic:
+ msg = f'identifier calculation for "{attribute}" in "{self.path}" cannot be set variable is not in dynamic family'
+ raise DictConsistencyError(msg, 53, self.sources)
+ if attribute in PROPERTY_ATTRIBUTE:
+ calc = CALCULATION_PROPERTY_TYPES[typ](**calculation_object)
+ else:
+ calc = CALCULATION_TYPES[typ](**calculation_object)
+ if index is None:
+ obj[attribute] = calc
+ else:
+ obj[attribute][index] = calc
+
+ def set_identifier_calculation_in_default_attribut(self, attribute: str, calculation_object: dict, inside_list: bool, index: Optional[int]) -> None:
+ if attribute != "default" or "identifier" not in calculation_object:
+ return
+ identifier = calculation_object["identifier"]
+ if self.is_calculation(
+ "identifier",
+ identifier,
+ attributes_types=self.objectspace.variable_objects[0]["attributes_types"],
+ inside_list=inside_list,
+ ):
+ self.set_calculation("identifier", identifier, obj=calculation_object, inside_list=inside_list, index=index)
+
+ def set_params_calculation(self, calculation_object: dict, attribute: str) -> None:
+ if "params" not in calculation_object:
+ return
+ params = []
+ for key, value in calculation_object["params"].items():
+ if isinstance(value, dict) and "type" not in value:
+ self.set_param_type(value)
+ if not isinstance(value, dict) or "type" not in value:
+ param_typ = "any"
+ value = {
+ "value": value,
+ "type": "any",
+ }
+ else:
+ if self.version == "1.0" and value["type"] == "suffix":
+ value["type"] = "identifier"
+ param_typ = value["type"]
+ value["key"] = key
+ value["path"] = self.path
+ value["family_is_dynamic"] = self.family_is_dynamic
+ value["attribute"] = attribute
+ value["namespace"] = self.objectspace.namespace
+ value["xmlfiles"] = self.sources
+ if param_typ not in PARAM_TYPES:
+ raise DictConsistencyError(
+ f'unknown type "{param_typ}" for "{self.path}"',
+ 52,
+ self.sources,
+ )
+ try:
+ params.append(PARAM_TYPES[param_typ](**value))
+ except ValidationError as err:
+ raise DictConsistencyError(
+ f'"{attribute}" has an invalid "{key}" for "{self.path}": {err}',
+ 29,
+ self.sources,
+ ) from err
+ calculation_object["params"] = params
+
+ def set_param_type(self, val):
+ # auto set type
+ param_typ = set(CALCULATION_TYPES) & set(val)
+ # XXX variable is also set to information
+ if param_typ == {"variable", "information"}:
+ param_typ = {"information"}
+ if len(param_typ) == 1:
+ val["type"] = list(param_typ)[0]
+
+ def is_redefine(self):
+ if self.path in self.objectspace.paths and self.option_type == "family" and not self.parameters:
+ # allow loading family with no attribute loaded
+ return True
+ if self.types:
+ return True
+ return self.parameters.pop("redefine", False) or (self.types and list(self.parameters) in [[], ["default"]])
+
+ def is_exists(self):
+ if self.version == "1.0" and self.option_type == "family":
+ return None
+ return self.parameters.pop("exists", None)
diff --git a/src/rougail/convert/convert.py b/src/rougail/convert/convert.py
index c8cf2928b..89dfe7c3d 100644
--- a/src/rougail/convert/convert.py
+++ b/src/rougail/convert/convert.py
@@ -26,7 +26,6 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
"""
-import logging
from pathlib import Path
from typing import (
Any,
@@ -43,29 +42,26 @@ from typing import (
from ruamel.yaml.comments import CommentedMap
from pydantic import ValidationError
-from warnings import warn
-
from tiramisu.error import display_list
from ..annotator import SpaceAnnotator
from ..i18n import _
-from ..tiramisu import CONVERT_OPTION
+from ..tiramisu import CONVERT_OPTION, normalize_family
from .object_model import (
- PROPERTY_ATTRIBUTE,
- CALCULATION_TYPES,
- CALCULATION_PROPERTY_TYPES,
- PARAM_TYPES,
- AnyParam,
Calculation,
Dynamic,
Family,
- SymLink,
Variable,
+ Choices,
+ Param,
+ Regexp,
+ SymLink,
VariableCalculation,
)
from .tiramisureflector import TiramisuReflector
from ..utils import load_modules
from .path import Paths
+from .collect import Collect
from ..error import DictConsistencyError
property_types = Union[Literal[True], Calculation]
@@ -205,10 +201,10 @@ class ParserVariable:
def init(self):
if self.is_init:
return
- variable = Variable
- family = Family
root = Path(__file__).parent.parent
self.walker = None
+ variable = Variable
+ family = Family
for structural_name in self.structurals:
structural = f"structural_{structural_name}"
module_path = root / structural / "__init__.py"
@@ -227,447 +223,204 @@ class ParserVariable:
)
if not self.walker and "Walker" in module.__all__:
self.walker = module.Walker
- self.variable = variable
- self.family = family
- self.dynamic = type(Dynamic.__name__, (Dynamic, family), {})
- hint = get_type_hints(self.dynamic)
- # FIXME: only for format 1.0
- self.family_types = hint["type"].__args__ # pylint: disable=W0201
- self.family_attrs = frozenset( # pylint: disable=W0201
- set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
- )
- self.family_calculations = self.search_calculation( # pylint: disable=W0201
- hint
- )
- #
- hint = get_type_hints(self.variable)
- self.variable_types = (
- self.convert_options
- ) # hint["type"].__args__ # pylint: disable=W0201
- #
- self.variable_attrs = frozenset( # pylint: disable=W0201
- set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
- )
- self.variable_calculations = self.search_calculation( # pylint: disable=W0201
- hint, variable=True,
- )
+ dynamic = type(Dynamic.__name__, (Dynamic, family), {})
+ choices = type(Choices.__name__, (Choices, variable), {})
+ regexp = type(Regexp.__name__, (Regexp, variable), {})
+ variable_types = self.convert_options.copy()
+ variable_types.remove("choice")
+ variable_types.remove("regexp")
+ variable_types.remove("symlink")
+ self.variable_objects = [self.get_variable_object(obj, is_variable=True) for obj in [(variable, variable_types), SymLink, choices, regexp]]
+ self.family_objects = [self.get_variable_object(obj, is_variable=False) for obj in [dynamic, family]]
self.is_init = True
- ###############################################################################################
- # determine if the object is a family or a variable
- ###############################################################################################
- def is_family_or_variable(
- self,
- path: str,
- obj: dict,
- family_is_leadership: bool,
- sources: list[str],
- ) -> Literal["variable", "family"]:
- """Check object to determine if it's a variable or a family"""
- # it's already has a variable or a family
- if path in self.paths:
- if path in self.families:
- return "family"
- return "variable"
- # it's: "my_variable:"
- if not obj:
- return "variable"
- # check type attributes
- obj_type = self.get_family_or_variable_type(obj)
- if obj_type:
- if obj_type in self.family_types or obj_type in self.custom_family_types:
- return "family"
- if obj_type in self.variable_types or obj_type in self.custom_variable_types:
- return "variable"
- msg = _('unknown type "{0}" for "{1}"').format(obj_type, path)
- raise DictConsistencyError(msg, 43, sources)
- # in a leadership there is only variable
- if family_is_leadership:
- return "variable"
- # all attributes are in variable object
- # and values in attributes are not dict is not Calculation
- if isinstance(obj, dict):
- extra_keys = set(obj) - self.variable_attrs
- if not extra_keys:
- for key, value in obj.items():
- if (
- isinstance(value, dict)
- and key != "params"
- and not self.is_calculation(
- key,
- value,
- self.variable_calculations,
- False,
- )
- ):
- break
- else:
- return "variable"
+ def get_variable_object(self, obj, *, is_variable: bool) -> dict:
+ if isinstance(obj, tuple):
+ obj, types = obj
+ hint = get_type_hints(obj)
else:
- if self.version == "1.0":
- msg = f'Invalid value for the variable "{path}": "{obj}"'
- raise DictConsistencyError(msg, 102, sources)
- return "variable"
- return "family"
+ hint = get_type_hints(obj)
+ types = self.get_types(hint)
+ return {"object": obj,
+ "types": types,
+ "attrs": self.get_option_attrs(hint),
+ "attributes_types": self.get_attributes_types(hint, variable=is_variable),
+ }
- def get_family_or_variable_type(
- self,
- obj: dict,
- ) -> Optional[str]:
- """Check 'type' attributes"""
- if not isinstance(obj, dict):
- return None
- if "_type" in obj:
- # only family has _type attributs
- return obj["_type"]
- if "type" in obj and isinstance(obj["type"], str):
- return obj["type"]
- if "_dynamic" in obj:
- return "dynamic"
- if "dynamic" in obj:
- dynamic = obj["dynamic"]
- if isinstance(dynamic, (list, dict)):
- return "dynamic"
- return None
+ def get_types(self, hint):
+ return hint["type"].__args__
+
+ def get_option_attrs(self, hint):
+ return frozenset( # pylint: disable=W0201
+ set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
+ )
###############################################################################################
# create, update or delete family or variable object
###############################################################################################
def family_or_variable(
self,
- sources: list[str],
name: str,
subpath: str,
obj: dict,
comment: Optional[str],
*,
first_variable: bool = False,
- family_is_leadership: bool = False,
- family_is_dynamic: bool = False,
- parent_dynamic: Optional[str] = None,
- copy_before_set: bool = False,
- force_redefine: bool = False,
custom_type: bool = False,
+ parent_option: "Collect" = None,
) -> None:
- if name.startswith("_"):
- msg = f'the variable or family name "{name}" is incorrect, it must not starts with "_" character'
- raise DictConsistencyError(msg, 16, sources)
- if not subpath:
- path = name
- else:
- path = f"{subpath}.{name}"
- if self.version == "0.1" and not isinstance(obj, dict) and obj is not None:
- msg = f'the variable "{path}" has a wrong type "{type(obj)}"'
- raise DictConsistencyError(msg, 17, sources)
- typ = self.is_family_or_variable(
- path,
+ option = Collect(
+ self,
+ name,
+ subpath,
obj,
- family_is_leadership,
- sources,
+ comment,
+ parent_option,
)
- logging.info("family_or_variable: %s is a %s", path, typ)
- if typ == "family":
+ if option.option_type == "family":
parser = self.parse_family
else:
parser = self.parse_variable
parser(
- sources,
- name,
- path,
- subpath,
- obj,
- comment=comment,
+ option,
first_variable=first_variable,
- 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,
custom_type=custom_type,
)
def parse_family(
self,
- sources: list[str],
- name: str,
- path: str,
- subpath: str,
- obj: Optional[Dict[str, Any]],
+ option: Collect,
*,
- comment: Optional[str] = None,
first_variable: bool = False,
- 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,
custom_type: bool = False,
) -> None:
"""Parse a family"""
- if obj is None:
- obj = {}
- if self.version != "1.0":
- exists = obj.pop("exists", None)
- else:
- exists = None
- redefine = self.is_redefine(path, obj, force_redefine)
- obj_type = self.get_family_or_variable_type(obj)
- family_obj, children_obj = self.split_param_family_children(path, sources, obj_type, obj)
- if self.version != "1.0" and not family_obj and comment:
- family_obj["description"] = comment
- if "type" in family_obj and not redefine and not exists:
- c_obj_type = family_obj.get("type")
- if c_obj_type in self.custom_family_types:
- redefine = True
- custom = self.custom_family_types[c_obj_type].copy()
- self.family_or_variable(
- custom.pop("xmlfiles") + sources,
- name,
- subpath,
- custom,
- "", # comment
- family_is_dynamic=family_is_dynamic,
- parent_dynamic=parent_dynamic,
- copy_before_set=True,
- custom_type=True,
- )
- force_redefine = True
- family_obj, children_obj = self.split_param_family_children(path, sources, obj_type, obj)
- family_obj["type"] = self.paths[path].type
- if path in self.paths:
- # it's just for modify subfamily or subvariable, do not redefine
- if family_obj:
- if exists in [None, True] and not redefine:
- msg = _('family "{0}" define multiple time').format(path)
- raise DictConsistencyError(
- msg, 32, self.paths[path].xmlfiles + sources
- )
- # convert to Calculation objects
- self.parse_parameters(
- path,
- family_obj,
- sources,
- family_is_dynamic,
- typ="family",
- )
- if self.load_unexist_redefine or exists in [None, True]:
- self.paths.add(
- path,
- self.paths[path].model_copy(update=family_obj),
- family_is_dynamic,
- parent_dynamic,
- force=True,
- )
- for source in sources:
- if source not in self.paths[path].xmlfiles:
- self.paths[path].xmlfiles.append(source)
- force_not_first = True
- if self.paths[path].type == "dynamic":
- family_is_dynamic = True
- parent_dynamic = path
- else:
+ path = option.path
+ redefine = option.redefine
+ exists = option.exists
+# if not redefine and not exists and option.user_type in self.custom_family_types:
+ types = option.types
+ if types:
+ self.add_family(types,
+ custom_type=True,
+ )
+ if path not in self.paths:
if not self.load_unexist_redefine and exists is None and redefine:
raise Exception(
- f'cannot redefine the inexisting family "{path}" in {display_list(sources)}'
+ f'cannot redefine the inexisting family "{path}" in {display_list(option.sources)}'
)
if not self.load_unexist_redefine and exists is True:
return
- extra_attrs = set(family_obj) - self.family_attrs
- if extra_attrs:
- raise Exception(f"extra attrs ... {extra_attrs}")
- if obj_type == "dynamic":
- family_obj["type"] = "dynamic"
- family_is_dynamic = True
- if "{{ identifier }}" not in name:
- if "{{ suffix }}" in name:
- name = name.replace("{{ suffix }}", "{{ identifier }}")
- path = path.replace("{{ suffix }}", "{{ identifier }}")
- elif "variable" in family_obj:
- name += "{{ identifier }}"
- path += "{{ identifier }}"
- else:
- msg = f'dynamic family name must have "{{{{ identifier }}}}" in his name for "{path}"'
- raise DictConsistencyError(msg, 13, sources)
- parent_dynamic = path
self.add_family(
- path,
- name,
- family_obj,
- sources,
- family_is_dynamic,
- parent_dynamic,
+ option,
custom_type=custom_type,
)
force_not_first = False
- if self.paths[path].type == "leadership":
- family_is_leadership = True
- for idx, key in enumerate(children_obj):
- if copy_before_set:
- value = children_obj[key].copy()
+ else:
+ if exists in [None, True] and not redefine:
+ msg = _('family "{0}" define multiple time').format(path)
+ raise DictConsistencyError(
+ msg, 32, option.sources
+ )
+ if self.load_unexist_redefine or exists in [None, True]:
+ objects = option.parameters.copy()
+ objects["xmlfiles"] = option.sources
+ self.paths.add(
+ option,
+ self.paths[path].model_copy(update=objects),
+ force=True,
+ )
+ force_not_first = types == None
+ children = option.children
+ for idx, key in enumerate(self.list_children(option, types)):
+ if key in children:
+ value = children[key]
+ comment = self.get_comment(key, children)
else:
- value = children_obj[key]
+ value = {}
+ comment = None
first_variable = not force_not_first and idx == 0
- if isinstance(obj, CommentedMap):
- comment = self.get_comment(key, obj)
- else:
- comment = ""
self.family_or_variable(
- sources,
key,
path,
value,
comment,
first_variable=first_variable,
- 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,
custom_type=custom_type,
+ parent_option=option,
)
- def is_redefine(self, path: str, obj, force_redefine: bool):
- return obj.pop("redefine", False) or (force_redefine is True and path in self.paths and list(obj) in [[], ["default"]])
+ def list_children(self, option, types):
+ """
+ my_type: [var1, var2]
- def split_param_family_children(self, path, sources, obj_type, obj):
- family_obj = {}
- children_obj = {}
- force_to_attrs = set(self.list_attributes(obj, sources, obj_type))
- if path in self.paths:
- force_to_attrs -= {p.rsplit('.', 1)[-1] for p in self.parents[path]}
- for key, value in obj.items():
- if key in force_to_attrs :
- if key.startswith("_"):
- key = key[1:]
- family_obj[key] = value
+ family: []
+ => [var1, var2]
+ family: [var1, var3, var2]
+ => [var1, var3, var2]
+ family: [var3]
+ => [var1, var2, var3]
+ family: [var3, var2]
+ => [var1, var3, var2]
+ family: [var1, var3]
+ => [var1, var2, var3]
+ """
+ option_children = list(option.children)
+ if not types:
+ yield from option_children
+ return
+ types_children = list(types.children)
+ while True:
+ if not option_children and not types_children:
+ break
+ if not option_children:
+ yield from types_children
+ break
+ elif not types_children:
+ yield from option_children
+ break
+ elif option_children[0] == types_children[0]:
+ yield option_children.pop(0)
+ types_children.pop(0)
+ elif types_children[0] not in option_children:
+ yield types_children.pop(0)
else:
- children_obj[key] = value
- return family_obj, children_obj
-
- def list_attributes(
- self,
- obj: Dict[str, Any],
- sources: list[str],
- obj_type: str,
- ) -> Iterator[str]:
- """List attributes"""
- force_to_variable = []
- for key, value in obj.items():
- if not isinstance(key, str):
- raise DictConsistencyError(
- f"a key is not in string format: {key}",
- 103,
- sources,
- )
- if key in force_to_variable:
- continue
- if key.startswith("_"):
- # if key starts with _, it's an attribute
- yield key
- # if same key without _ exists, it's a variable!
- true_key = key[1:]
- if true_key in obj:
- force_to_variable.append(true_key)
- continue
- if isinstance(value, dict) and not self.is_calculation(
- key,
- value,
- self.family_calculations,
- False,
- ):
- # it's a dict, so a new variables!
- continue
- # 'variable' for compatibility to format 1.0
- if (
- key == "variable"
- and obj.get("type") != "dynamic"
- and obj.get("_type") != "dynamic"
- ):
- continue
- if key in self.family_attrs:
- if obj_type != "dynamic" and key == "dynamic":
- continue
- yield key
+ name = option_children.pop(0)
+ yield name
+ if name in types_children:
+ types_children.remove(name)
def add_family(
self,
- path: str,
- name: str,
- family: dict,
- sources: list[str],
- family_is_dynamic: bool,
- parent_dynamic: str,
+ option: Collect,
*,
custom_type: bool=False,
) -> None:
"""Add a new family"""
- family["path"] = path
- family["namespace"] = self.namespace
- family["version"] = self.version
- family["xmlfiles"] = sources
- obj_type = self.get_family_or_variable_type(family)
+ path = option.path
if custom_type:
- self.change_namespaces(family)
- if obj_type == "dynamic":
- family_obj = self.dynamic
- if self.version == "1.0":
- if "variable" not in family:
- raise DictConsistencyError(
- f'dynamic family must have "variable" attribute for "{path}"',
- 101,
- family["xmlfiles"],
- )
- if "dynamic" in family:
- raise DictConsistencyError(
- 'variable and dynamic cannot be set together in the dynamic family "{path}"',
- 100,
- family["xmlfiles"],
- )
- family["dynamic"] = {
- "type": "variable",
- "variable": family["variable"],
- "propertyerror": False,
- "allow_none": True,
- }
- del family["variable"]
- if "variable" in family:
- family["dynamic"] = {
- "type": "variable",
- "variable": family["variable"],
- "propertyerror": False,
- "allow_none": True,
- }
- del family["variable"]
- if self.version != "1.0":
- warning = f'"variable" attribute in dynamic family "{ path }" is depreciated in {display_list(sources)}'
- warn(
- warning,
- DeprecationWarning,
- stacklevel=2,
- )
- if "variable" in family:
+ self.change_namespaces(option.parameters)
+ family_obj = option.object["object"]
+ if option.user_type == "dynamic":
+ # FIXME only for version 1.0 purpose
+ if "variable" in option.parameters:
raise Exception(
- f'dynamic family must not have "variable" attribute for "{family["path"]}" in {family["xmlfiles"]}'
+ f'dynamic family must not have "variable" attribute for "{path}" in {option.sources}'
)
- else:
- family_obj = self.family
- # convert to Calculation objects
- self.parse_parameters(
- path,
- family,
- sources,
- family_is_dynamic,
- typ="family",
- )
+ data = dict(option.parameters)
+ data["xmlfiles"] = option.sources
+ data["namespace"] = option.namespace
+ data["path"] = path
+ data["version"] = option.version
try:
self.paths.add(
- path,
- family_obj(name=name, **family),
- family_is_dynamic,
- parent_dynamic,
+ option,
+ family_obj(name=option.name,
+ **data,
+ ),
)
except ValidationError as err:
- raise Exception(f'invalid family "{path}" in "{display_list(sources)}": {err}') from err
+ raise Exception(f'invalid family "{path}" in "{display_list(option.sources)}": {err}') from err
self.set_name(
self.paths[path],
"optiondescription_",
@@ -679,78 +432,27 @@ class ParserVariable:
self.parents[parent].append(path)
self.parents[path] = []
self.families.append(path)
+ if self.loaded_custom_types != None:
+ self.loaded_custom_types[path] = option
def parse_variable(
self,
- sources: list[str],
- name: str,
- path: str,
- subpath: str,
- obj: Optional[Dict[str, Any]],
+ option: Collect,
*,
- comment: Optional[str] = None,
first_variable: bool = False,
- family_is_leadership: bool = False,
- family_is_dynamic: bool = False,
- parent_dynamic: Optional[str] = None,
- copy_before_set: bool = False,
- force_redefine: bool = False,
custom_type: bool = False,
) -> None:
"""Parse variable"""
- if self.version == "1.0" or isinstance(obj, dict):
- if obj is None:
- obj = {}
- extra_attrs = set(obj) - self.variable_attrs
- else:
- extra_attrs = []
- obj = {"default": obj}
- if comment:
- obj["description"] = comment
- if extra_attrs:
- raise DictConsistencyError(
- f'"{path}" is not a valid variable, there are additional '
- f'attributes: "{", ".join(extra_attrs)}"',
- 65,
- sources,
- )
- self.parse_parameters(
- path,
- obj,
- sources,
- family_is_dynamic,
- )
- self.parse_params(path, obj, sources)
- self.parse_secret_manager(path, obj, sources, family_is_dynamic, copy_before_set)
- exists = obj.pop("exists", None)
- redefine = self.is_redefine(path, obj, force_redefine)
- if not redefine and not exists:
- obj_type = obj.get("type")
- if obj_type in self.custom_variable_types:
- redefine = True
- custom = self.custom_variable_types[obj_type].copy()
- self.add_variable(name, path, custom, custom.get('xmlfiles'), family_is_dynamic, parent_dynamic, family_is_leadership, first_variable, custom_type=True)
- del obj["type"]
- if path in self.paths:
- if not self.load_unexist_redefine:
- if exists is False:
- return
- if not redefine:
- msg = _('variable "{0}" define multiple time').format(path)
- raise DictConsistencyError(
- msg, 45, self.paths[path].xmlfiles + sources
- )
- self.paths.add(
- path,
- self.paths[path].model_copy(update=obj),
- family_is_dynamic,
- parent_dynamic,
- force=True,
- )
- for source in sources:
- if source not in self.paths[path].xmlfiles:
- self.paths[path].xmlfiles.append(source)
- else:
+ redefine = option.redefine
+ exists = option.exists
+ path = option.path
+ if option.types:
+ redefine = True
+ self.add_variable(option.types,
+ first_variable=first_variable,
+ custom_type=True,
+ )
+ if path not in self.paths:
if not self.load_unexist_redefine and exists is True:
# this variable must exist
# but it's not the case
@@ -758,196 +460,73 @@ class ParserVariable:
return
if not self.load_unexist_redefine and redefine:
msg = f'cannot redefine the inexisting variable "{path}"'
- raise DictConsistencyError(msg, 46, sources)
- self.add_variable(name, path, obj, sources, family_is_dynamic, parent_dynamic, family_is_leadership, first_variable, custom_type=custom_type)
-
- def parse_parameters(
- self,
- path: str,
- obj: dict,
- sources: list[str],
- family_is_dynamic: bool,
- *,
- typ: str = "variable",
- ):
- """Parse variable or family parameters"""
- if typ == "variable":
- calculations = self.variable_calculations
+ raise DictConsistencyError(msg, 46, option.sources)
+ self.add_variable(option,
+ first_variable,
+ custom_type,
+ )
else:
- calculations = self.family_calculations
- for key, value in obj.items():
- if self.is_calculation(
- key,
- value,
- calculations,
- False,
- ):
- try:
- self.set_calculation(
- obj,
- key,
- value,
- path,
- family_is_dynamic,
- sources,
- )
- except ValidationError as err:
+ if not self.load_unexist_redefine:
+ if exists is False:
+ return
+ if not redefine:
+ msg = _('variable "{0}" define multiple time').format(path)
raise DictConsistencyError(
- _('the {0} "{1}" has an invalid "{2}": {3}').format(typ, path, key, err),
- 84,
- sources,
- ) from err
- continue
- if not isinstance(value, list):
- continue
- for idx, val in enumerate(value):
- if not self.is_calculation(
- key,
- val,
- calculations,
- True,
- ):
- continue
- try:
- self.set_calculation(
- obj,
- key,
- val,
- path,
- family_is_dynamic,
- sources,
- inside_list=True,
- index=idx,
+ msg, 45, option.sources
)
- except ValidationError as err:
- raise Exception(
- f'the {typ} "{path}" in "{display_list(sources)}" has an invalid "{key}" '
- f"at index {idx}: {err}"
- ) from err
-
- def parse_params(self, path, obj, sources):
- """Parse variable params"""
- if "params" not in obj:
- return
- 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,
- sources,
+ objects = option.parameters.copy()
+ objects["xmlfiles"] = option.sources
+ self.paths.add(
+ option,
+ self.paths[path].model_copy(update=objects),
+ force=True,
)
- params = []
- for key, val in obj["params"].items():
- try:
- params.append(
- AnyParam(
- key=key,
- value=val,
- type="any",
- path=None,
- attribute=None,
- family_is_dynamic=None,
- namespace=self.namespace,
- xmlfiles=sources,
- )
- )
- except ValidationError as err:
- raise DictConsistencyError(
- _('"{0}" has an invalid "params" for {1}: {2}').format(
- key, path, err
- ),
- 54,
- sources,
- ) from err
- obj["params"] = params
-
- def parse_secret_manager(self, path, obj, sources, family_is_dynamic, copy_before_set):
- """Parse variable secret_manager"""
- if "secret_manager" not in obj:
- return
- if not isinstance(obj["secret_manager"], dict):
- if copy_before_set:
- obj["secret_manager"] = obj["secret_manager"].model_copy()
- return
- raise DictConsistencyError(
- _("secret_manager must be a dict for {0}").format(path),
- 64,
- sources,
- )
- secret_manager = {
- "type": "jinja",
- "jinja": self.secret_pattern,
- "params": obj["secret_manager"],
- }
- self.set_calculation(
- obj,
- "secret_manager",
- secret_manager,
- path,
- family_is_dynamic,
- sources,
- )
def add_variable(
self,
- name: str,
- path: str,
- variable: dict,
- sources: list[str],
- family_is_dynamic: bool,
- parent_dynamic: Optional[str],
- family_is_leadership: bool,
+ option,
first_variable: bool,
- *,
- custom_type: bool=False,
+ custom_type: bool,
) -> None:
"""Add a new variable"""
- variable["namespace"] = self.namespace
- variable["version"] = self.version
- variable["xmlfiles"] = sources
- variable["path"] = path
- variable_type = self.get_family_or_variable_type(variable)
+ variable = option.parameters
+ path = option.path
if custom_type:
self.change_namespaces(variable)
- obj = {
- "symlink": SymLink,
- "choice": self.variable,
- }.get(variable_type, self.variable)
+ data = dict(variable)
+ data["xmlfiles"] = option.sources
+ data["namespace"] = option.namespace
+ data["path"] = path
+ data["version"] = option.version
try:
- variable_obj = obj(name=name, **variable)
+ variable_obj = option.object["object"](name=option.name,
+ **data,
+ )
except ValidationError as err:
raise Exception(
- f'invalid variable "{variable["path"]}" in "{display_list(sources)}": {err}'
+ f'invalid variable "{path}" in "{display_list(option.sources)}": {err}'
) from err
self.paths.add(
- variable["path"],
+ option,
variable_obj,
- family_is_dynamic,
- parent_dynamic,
)
- self.variables.append(variable["path"])
- if "." in variable["path"]:
- parent_path = variable["path"].rsplit(".", 1)[0]
+ self.variables.append(path)
+ if "." in path:
+ parent_path = path.rsplit(".", 1)[0]
else:
parent_path = "."
- self.parents[parent_path].append(variable["path"])
+ self.parents[parent_path].append(path)
self.set_name(
variable_obj,
"option_",
)
- if family_is_leadership:
+ if option.family_is_leadership:
if first_variable:
self.leaders.append(path)
else:
self.followers.append(path)
+ if self.loaded_custom_types != None:
+ self.loaded_custom_types[path] = option
def change_namespaces(self, variable):
for key, value in variable.items():
@@ -989,146 +568,13 @@ class ParserVariable:
self.index += 1
self.reflector_names[obj.path] = f"{option_prefix}{self.index}{self.suffix}"
- ###############################################################################################
- # calculations
- ###############################################################################################
- def is_calculation(
- self,
- attribute: str,
- value: dict,
- calculations: list,
- inside_list: bool,
- ):
- """Check if it's a calculation"""
- if inside_list:
- calculations = calculations[0]
- else:
- calculations = calculations[1]
- if not isinstance(value, dict) or attribute not in calculations:
- return False
- return self.check_auto_type(value)
-
- def check_auto_type(self, value):
- if "type" in value:
- return value["type"] in CALCULATION_TYPES
- # auto set type
- typ = set(CALCULATION_TYPES) & set(value)
- # XXX variable could have identifier
- if typ == {"variable", "identifier"}:
- typ = {"variable"}
- # XXX variable is also set to information
- if typ == {"variable", "information"}:
- typ = {"information"}
- if len(typ) == 1:
- value["type"] = list(typ)[0]
- return True
- return False
-
- def set_calculation(
- self,
- obj: dict,
- attribute: str,
- value: dict,
- path: str,
- family_is_dynamic: bool,
- xmlfiles: List[str],
- *,
- inside_list: bool = False,
- index: int = None,
- ):
- """This variable is a calculation"""
- calculation_object = value.copy()
- typ = calculation_object.pop("type")
-
- calculation_object["attribute_name"] = attribute
-# calculation_object["path"] = path
- calculation_object["inside_list"] = inside_list
- calculation_object["version"] = self.version
- calculation_object["namespace"] = self.namespace
- calculation_object["xmlfiles"] = xmlfiles
- #
- if attribute == "default" and "identifier" in calculation_object:
- identifier = calculation_object["identifier"]
- 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)
- if "params" in calculation_object:
- if not isinstance(calculation_object["params"], dict):
- raise Exception("params must be a dict")
- params = []
- for key, val in calculation_object["params"].items():
- if isinstance(val, dict) and "type" not in val:
- self.set_param_type(val)
- if not isinstance(val, dict) or "type" not in val:
- param_typ = "any"
- val = {
- "value": val,
- "type": "any",
- }
- else:
- if self.version == "1.0" and val["type"] == "suffix":
- val["type"] = "identifier"
- param_typ = val["type"]
- val["key"] = key
- val["path"] = path
- val["family_is_dynamic"] = family_is_dynamic
- val["attribute"] = attribute
- val["namespace"] = self.namespace
- val["xmlfiles"] = xmlfiles
- if param_typ not in PARAM_TYPES:
- raise DictConsistencyError(
- f'unknown type "{param_typ}" for "{path}"',
- 52,
- xmlfiles,
- )
- try:
- params.append(PARAM_TYPES[param_typ](**val))
- except ValidationError as err:
- raise DictConsistencyError(
- f'"{attribute}" has an invalid "{key}" for "{path}": {err}',
- 29,
- xmlfiles,
- ) from err
- calculation_object["params"] = params
- #
- return_type = calculation_object.get("return_type")
- if return_type:
- if return_type not in self.variable_types:
- raise Exception(
- f'unknown "return_type" in {attribute} of variable "{path}"'
- )
- #
- if typ == "identifier" and not family_is_dynamic:
- msg = f'identifier calculation for "{attribute}" in "{path}" cannot be set variable is not in dynamic family'
- raise DictConsistencyError(msg, 53, xmlfiles)
- if attribute in PROPERTY_ATTRIBUTE:
- calc = CALCULATION_PROPERTY_TYPES[typ](**calculation_object)
- else:
- calc = CALCULATION_TYPES[typ](**calculation_object)
- if index is None:
- obj[attribute] = calc
- else:
- obj[attribute][index] = calc
-
- def set_param_type(self, val):
- # auto set type
- param_typ = set(CALCULATION_TYPES) & set(val)
- # XXX variable is also set to information
- if param_typ == {"variable", "information"}:
- param_typ = {"information"}
- if len(param_typ) == 1:
- val["type"] = list(param_typ)[0]
-
class RougailConvert(ParserVariable):
"""Main Rougail conversion"""
def __init__(self,
rougailconfig,
+ *,
custom_variable_types: dict={},
custom_family_types: dict={},
) -> None:
@@ -1136,62 +582,122 @@ class RougailConvert(ParserVariable):
self.has_namespace = False
self.custom_variable_types = custom_variable_types
self.custom_family_types = custom_family_types
+ self.loaded_custom_types = None
super().__init__(rougailconfig)
- def search_calculation(
+ def get_attributes_types(
self,
hint: dict,
variable: bool=False,
- ) -> Tuple[List[Any], List[Any]]:
+ ) -> dict:
"""attribute is calculated if typing is like: Union[Calculation, xxx]"""
+ lists = {"strings": [],
+ "booleans": [],
+ "integers": [],
+ "floats": [],
+ "calculation": []}
if variable:
- inside_list = ["identifier"]
- outside_list = ["identifier"]
+ lists["calculation"].append("identifier")
+ calculation = ["identifier"]
else:
- inside_list = []
- outside_list = []
+ calculation = []
+ strings = []
+ booleans = ["redefine", "exists"]
+ integers = []
+ floats = []
+ params = []
+ literals = {}
for key, value in hint.items():
- if "Union" in value.__class__.__name__ and (
- Calculation in value.__args__ or VariableCalculation in value.__args__
- ):
- outside_list.append(key)
- if (
- "Union" in value.__class__.__name__
- and "_GenericAlias" in value.__args__[0].__class__.__name__
- and Calculation in value.__args__[0].__args__
- ):
- inside_list.append(key)
- if (
- "Union" in value.__class__.__name__
- and value.__args__[0].__class__.__name__ == "_GenericAlias"
- and "Union" in value.__args__[0].__args__[0].__class__.__name__
- and Calculation in value.__args__[0].__args__[0].__args__
- ):
- inside_list.append(key)
- return inside_list, outside_list
+ if "Union" in value.__class__.__name__:
+ key_types = value.__args__
+ if str in key_types:
+ strings.append(key)
+ if int in key_types:
+ integers.append(key)
+ if bool in key_types:
+ booleans.append(key)
+ if float in key_types:
+ floats.append(key)
+ if Calculation in key_types or VariableCalculation in key_types:
+ calculation.append(key)
+ if "_GenericAlias" in key_types[0].__class__.__name__:
+ if Calculation in key_types[0].__args__:
+ lists["calculation"].append(key)
+ elif "Union" in key_types[0].__args__[0].__class__.__name__:
+ key_types_list = key_types[0].__args__[0].__args__
+ if Calculation in key_types_list:
+ lists["calculation"].append(key)
+ if str in key_types_list:
+ lists["strings"].append(key)
+ if int in key_types_list:
+ lists["integers"].append(key)
+ if bool in key_types_list:
+ lists["booleans"].append(key)
+ if float in key_types_list:
+ lists["floats"].append(key)
+ else:
+ key_types_list = key_types[0].__args__
+ if Param in key_types_list:
+ params.append(key)
+ if str in key_types_list:
+ lists["strings"].append(key)
+ elif value == str:
+ strings.append(key)
+ elif value == bool:
+ booleans.append(key)
+ elif "Literal" in value.__class__.__name__:
+ literals[key] = value.__args__
+ return {"strings": strings,
+ "integers": integers,
+ "booleans": booleans,
+ "floats": floats,
+ "literals": literals,
+ "calculation": calculation,
+ "lists": lists,
+ "params": params,
+ }
def create_namespace(
- self, namespace_description: str, namespace_path: Optional[str] = None
+ self, namespace_description: str, isolated_namespace: bool=True,
) -> None:
+ namespace_path = normalize_family(namespace_description)
self.has_namespace = True
- if namespace_path is None:
- namespace_path = self.namespace
+ if namespace_path in self.parents:
+ raise DictConsistencyError(
+ _("duplicate namespace {0}").format(namespace_path),
+ 86,
+ None,
+ )
+ self.namespace = namespace_path
+ if not self.paths.default_namespace:
+ self.paths = Paths(
+ namespace_description,
+ isolated_namespace,
+ )
self.version = ""
- self.parse_family(
- [],
+ self.sources = []
+ option = Collect(
+ self,
self.namespace,
- namespace_path,
- namespace_path,
+ None,
{
+ "type": "family",
"description": namespace_description,
},
+ None,
+ None,
+ )
+ self.parse_family(
+ option
)
def get_comment(
self,
name: str,
- objects: CommentedMap,
+ objects: Any,
) -> Optional[str]:
+ if self.version == "1.0" or not isinstance(objects, CommentedMap):
+ return
if name in objects.ca.items:
comment = objects.ca.items[name][2]
else:
@@ -1208,10 +714,10 @@ class RougailConvert(ParserVariable):
objects: dict,
) -> None:
self.version = version
+ self.sources = sources
for name, obj in objects.items():
comment = self.get_comment(name, objects)
self.family_or_variable(
- sources,
name,
path,
obj,
diff --git a/src/rougail/convert/object_model.py b/src/rougail/convert/object_model.py
index e1c511f31..0b38e95d8 100644
--- a/src/rougail/convert/object_model.py
+++ b/src/rougail/convert/object_model.py
@@ -134,12 +134,12 @@ class VariableParam(Param):
).format(param["variable"], attribute_name, path)
raise DictConsistencyError(msg, 22, xmlfiles)
return None
- if isinstance(variable, objectspace.family):
+ if isinstance(variable, objectspace.family_objects[-1]["object"]):
msg = _(
'the variable "{0}" is in fact a family in attribute "{1}" for "{2}"'
).format(variable["name"], attribute_name, path)
raise DictConsistencyError(msg, 42, xmlfiles)
- if not isinstance(variable, objectspace.variable):
+ if not isinstance(variable, objectspace.variable_objects[0]["object"]):
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(
variable, attribute_name, path
)
@@ -253,6 +253,7 @@ class Calculation(BaseModel):
ori_path: Optional[StrictStr] = None
default_values: Any = None
namespace: Optional[StrictStr]
+ # FIXME warnings is not available for Properties!
warnings: Optional[bool] = None
description: Optional[StrictStr] = None
xmlfiles: List[StrictStr]
@@ -493,6 +494,7 @@ class _VariableCalculation(Calculation):
propertyerror: bool = True,
allow_none: bool = False
optional: bool = False
+ # FIXME identifier is not available for Properties!
identifier: Optional[Calculation] = None
def get_variable(
@@ -520,7 +522,7 @@ class _VariableCalculation(Calculation):
self.namespace,
self.xmlfiles,
)
- if variable and not isinstance(variable, objectspace.variable):
+ if variable and not isinstance(variable, objectspace.variable_objects[0]["object"]):
if isinstance(variable, objectspace.family):
msg = _(
'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family'
@@ -1057,7 +1059,7 @@ class Family(BaseModel):
help: Optional[StrictStr] = None
mode: Optional[StrictStr] = None
# validation
- type: Literal["family", "leadership", "dynamic"] = "family"
+ type: Literal["family", "leadership"] = "family"
# properties
hidden: Union[bool, Calculation] = False
disabled: Union[bool, Calculation] = False
@@ -1070,7 +1072,8 @@ class Family(BaseModel):
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
-class Dynamic(Family):
+class Dynamic(BaseModel):
+ type: Literal["dynamic"] = "dynamic"
# None only for format 1.0
variable: StrictStr = None
dynamic: Union[List[Union[StrictStr, Calculation]], Calculation]
@@ -1082,17 +1085,16 @@ class Variable(BaseModel):
description: Optional[StrictStr] = None
help: Optional[StrictStr] = None
mode: Optional[StrictStr] = None
- tags: Optional[list] = None
- examples: Optional[list] = None
- test: Optional[list] = None
+ tags: Optional[List[StrictStr]] = None
+ examples: Optional[List[BASETYPE]] = None
+ test: Optional[List[BASETYPE]] = None
# validations
## type will be set dynamically in `annotator/value.py`, default is None
type: StrictStr = None
params: Optional[List[Param]] = None
- regexp: Optional[StrictStr] = None
- choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
multi: Optional[bool] = None
validators: Optional[List[Calculation]] = None
+ # FIXME: warnings markes sense? if so, please document it
warnings: bool = False
# value
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
@@ -1100,6 +1102,7 @@ class Variable(BaseModel):
# properties
auto_save: bool = False
mandatory: Union[None, bool, Calculation] = None
+ # FIXME: terme empty is not appropriate
empty: Union[None, bool, Calculation] = True
unique: Optional[bool] = None
hidden: Union[bool, Calculation] = False
@@ -1114,6 +1117,16 @@ class Variable(BaseModel):
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
+class Choices(BaseModel):
+ type: Literal["choice"] = "choice"
+ choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
+
+
+class Regexp(BaseModel):
+ type: Literal["regexp"] = "regexp"
+ regexp: Optional[StrictStr] = None
+
+
class SymLink(BaseModel):
type: Literal["symlink"] = "symlink"
name: StrictStr
diff --git a/src/rougail/convert/path.py b/src/rougail/convert/path.py
index a7de9ab31..5e0bcfc79 100644
--- a/src/rougail/convert/path.py
+++ b/src/rougail/convert/path.py
@@ -50,16 +50,15 @@ class Paths:
def add(
self,
- path: str,
+ option: "Collect",
data: Any,
- is_dynamic: bool,
- dynamic: str,
*,
force: bool = False,
) -> None:
+ path = option.path
self._data[path] = data
- if not force and is_dynamic:
- self._dynamics[path] = dynamic
+ if not force and option.family_is_dynamic:
+ self._dynamics[path] = option.parent_dynamic
def get_full_path(
self,
@@ -242,3 +241,6 @@ class Paths:
def get(self):
return self._data.values()
+
+ def replace(self, path, variable):
+ self._data[path] = variable
diff --git a/src/rougail/convert/tiramisureflector.py b/src/rougail/convert/tiramisureflector.py
index 9864cbd69..e7941b153 100644
--- a/src/rougail/convert/tiramisureflector.py
+++ b/src/rougail/convert/tiramisureflector.py
@@ -187,7 +187,7 @@ class Common:
def populate_attrib(self):
"""Populate attributes"""
keys = {"name": self.convert_str(self.elt.name)}
- if hasattr(self.elt, "description") and self.elt.description:
+ if self.elt.type != "symlink":
keys["doc"] = self.convert_str(self.elt.description)
self._populate_attrib(keys)
if self.elt.path in self.objectspace.properties:
diff --git a/src/rougail/structural_commandline/annotator.py b/src/rougail/structural_commandline/annotator.py
index 0bd3f2778..6339ce55b 100644
--- a/src/rougail/structural_commandline/annotator.py
+++ b/src/rougail/structural_commandline/annotator.py
@@ -20,6 +20,7 @@ along with this program. If not, see .
from rougail.annotator.variable import Walk
from rougail.utils import _
from rougail.error import DictConsistencyError
+from rougail.convert.collect import Collect
class Annotator(Walk):
@@ -76,17 +77,22 @@ class Annotator(Walk):
self.alternative_names[alternative_name] = variable_path
if "." not in variable_path:
- path = alternative_name
+ subpath = None
else:
- path = variable_path.rsplit(".", 1)[0] + "." + alternative_name
+ subpath = variable_path.rsplit(".", 1)[0]
self.objectspace.version = variable.version
- self.objectspace.add_variable(
+ # FIXME dynamic_family peut etre == true ??
+ # FIXME objectspace ? zut peut avoir une version différente !!
+ option = Collect(
+ self.objectspace,
alternative_name,
- path,
+ subpath,
{"type": "symlink", "opt": variable},
- variable.xmlfiles,
- False,
- False,
+ None,
+ None,
+ )
+ self.objectspace.add_variable(
+ option,
False,
False,
)
diff --git a/src/rougail/structural_directory/__init__.py b/src/rougail/structural_directory/__init__.py
index 02b36a966..043042eaa 100644
--- a/src/rougail/structural_directory/__init__.py
+++ b/src/rougail/structural_directory/__init__.py
@@ -22,7 +22,6 @@ from pathlib import Path
from ruamel.yaml import YAML
-from ..tiramisu import normalize_family
from ..convert.path import Paths
from ..error import DictConsistencyError
from ..i18n import _
@@ -36,29 +35,26 @@ class Walker:
"""Parse directories content"""
self.convert = convert
self.yaml = YAML()
+ self.sort_structural_files_all = True
+ self.walk()
+
+ def walk(self) -> None:
rougailconfig = self.convert.rougailconfig
self.sort_structural_files_all = rougailconfig["sort_structural_files_all"]
if rougailconfig["main_namespace"]:
- self.convert.paths = Paths(
- rougailconfig["main_namespace"],
- rougailconfig["isolated_namespace"],
- )
self.load_with_extra(
rougailconfig["extra_namespaces"],
rougailconfig["main_namespace"],
rougailconfig["main_structural_directories"],
+ rougailconfig["isolated_namespace"],
)
else:
self.convert.namespace = None
- namespace_path = ""
- if namespace_path in self.convert.parents:
- raise Exception("pfff")
- for filename in self.get_sorted_filename(
+ for filename in self.get_sorted_filenames(
rougailconfig["main_structural_directories"]
):
self.parse_variable_file(
filename,
- namespace_path,
)
def load_with_extra(
@@ -66,38 +62,25 @@ class Walker:
extra_structures: dict,
main_namespace: Optional[str] = None,
main_structures: Optional[List[str]] = None,
+ isolated_namespace: bool = True,
) -> None:
- self.convert.has_namespace = True
- if main_namespace:
- directory_dict = chain(
+ directory_dict = chain(
+ (
(
- (
- main_namespace,
- main_structures,
- ),
+ main_namespace,
+ main_structures,
),
- extra_structures.items(),
- )
- else:
- directory_dict = extra_structures.items()
- for namespace, extra_dirs in directory_dict:
- # if namespace is None:
- # self.convert.namespace = namespace
- # else:
- self.convert.namespace = normalize_family(namespace)
- namespace_path = self.convert.namespace
- if namespace_path in self.convert.parents:
- raise Exception("pfff")
- for idx, filename in enumerate(self.get_sorted_filename(extra_dirs)):
- if not idx:
- # create only for the first file
- self.convert.create_namespace(namespace, namespace_path)
+ ),
+ extra_structures.items(),
+ )
+ for namespace, directories in directory_dict:
+ self.convert.create_namespace(namespace, isolated_namespace)
+ for filename in self.get_sorted_filenames(directories):
self.parse_variable_file(
filename,
- namespace_path,
)
- def get_sorted_filename(
+ def get_sorted_filenames(
self,
directories: Union[str, List[str]],
) -> Iterator[str]:
@@ -116,11 +99,13 @@ class Walker:
for file_path in directory.iterdir():
self.get_filename(file_path, filenames)
if not self.sort_structural_files_all:
- for filename in sorted(filenames):
- yield filenames[filename]
+ yield from self._get_sorted_filenames(filenames)
if self.sort_structural_files_all:
- for filename in sorted(filenames):
- yield filenames[filename]
+ yield from self._get_sorted_filenames(filenames)
+
+ def _get_sorted_filenames(self, filenames):
+ for filename in sorted(filenames):
+ yield filenames[filename]
def get_filename(self, file_path, filenames: List[str]) -> None:
if file_path.suffix not in [".yml", ".yaml"]:
@@ -136,7 +121,6 @@ class Walker:
def parse_variable_file(
self,
filename: str,
- path: str,
) -> None:
"""Parse file"""
with open(filename, encoding="utf8") as file_fh:
@@ -149,7 +133,7 @@ class Walker:
)
self.convert.parse_root_file(
[filename],
- path,
+ self.convert.namespace,
version,
objects,
)
diff --git a/src/rougail/structural_string/__init__.py b/src/rougail/structural_string/__init__.py
index 1c07332cb..ea94f1e2a 100644
--- a/src/rougail/structural_string/__init__.py
+++ b/src/rougail/structural_string/__init__.py
@@ -37,25 +37,17 @@ class Walker:
self.yaml = YAML()
rougailconfig = self.convert.rougailconfig
if rougailconfig["main_namespace"]:
- self.convert.has_namespace = True
- self.convert.paths = Paths(
- rougailconfig["main_namespace"],
- rougailconfig["isolated_namespace"],
- )
self.load_with_extra(
rougailconfig["extra_namespaces"],
rougailconfig["main_namespace"],
rougailconfig["main_structural_strings"],
+ rougailconfig["isolated_namespace"],
)
else:
self.convert.namespace = None
- namespace_path = ""
- if namespace_path in self.convert.parents:
- raise Exception("pfff")
for string in rougailconfig["main_structural_strings"]:
self.parse_variable(
string,
- namespace_path,
)
def load_with_extra(
@@ -63,6 +55,7 @@ class Walker:
extra_structures: dict,
main_namespace: str,
main_strings: Optional[List[str]] = None,
+ isolated_namespace: bool = True,
) -> None:
directory_dict = chain(
(
@@ -75,26 +68,22 @@ class Walker:
)
for namespace, extra_objects in directory_dict:
namespace_path = normalize_family(namespace)
- if namespace_path in self.convert.parents:
- raise Exception("pfff")
- self.convert.namespace = namespace_path
for idx, string in enumerate(extra_objects):
if not idx:
# create only for the first file
- self.convert.create_namespace(namespace, namespace_path)
+ self.convert.create_namespace(namespace, isolated_namespace)
self.parse_variable(
string,
- namespace_path,
)
def parse_variable(
self,
string: str,
- path: str,
) -> None:
objects = self.yaml.load(string)
if objects is None:
return
+ path = self.convert.namespace
if path:
name = f'yaml file for {path}'
else:
diff --git a/src/rougail/tiramisu.py b/src/rougail/tiramisu.py
index 8ff575b40..6de836a1a 100644
--- a/src/rougail/tiramisu.py
+++ b/src/rougail/tiramisu.py
@@ -217,6 +217,7 @@ CONVERT_OPTION = {
#
"symlink": dict(opttype="SymLinkOption"),
}
+# only version 1.1
RENAME_TYPE = {"number": "integer"}
@@ -411,15 +412,15 @@ def jinja_to_function(
for v in value:
if isinstance(v, PropertiesOptionError):
v = JinjaError(v)
- if v is None:
- v = ''
+# if v is None:
+# v = ''
val.append(v)
value = val
else:
if isinstance(value, PropertiesOptionError):
value = JinjaError(value)
- if value is None:
- value = ''
+# if value is None:
+# value = ''
if "." in key:
c_kw = kw
path, var = key.rsplit(".", 1)
diff --git a/src/rougail/types.py b/src/rougail/types.py
index aa4111841..41d55b25d 100644
--- a/src/rougail/types.py
+++ b/src/rougail/types.py
@@ -33,11 +33,11 @@ class TypeRougailConvert(StaticRougailConvert):
})
self.default_structural_format_version = default_structural_format_version
self.secret_pattern = secret_pattern
-
+ self.loaded_custom_types = {}
def load_config(self) -> None:
super().load_config()
- self.add_extra_options = self.add_extra_options
+# self.add_extra_options = self.add_extra_options
self.sort_structural_files_all = False
self.structurals = ["directory"]
@@ -45,32 +45,33 @@ class TypeRougailConvert(StaticRougailConvert):
def rougail_type(rougailconfig):
types = rougailconfig["types"]
if not types:
- return {}, {}
- convert = TypeRougailConvert(types, rougailconfig["secret_manager.pattern"], rougailconfig["default_structural_format_version"])
+ return {"custom_variable_types": {}, "custom_family_types": {}}
+ convert = TypeRougailConvert(types,
+ rougailconfig["secret_manager.pattern"],
+ rougailconfig["default_structural_format_version"],
+ )
convert.init()
convert.parse_directories()
- return ({typ: to_dict_variable(convert.paths[typ]) for typ in convert.variables},
- {typ: to_dict_family(typ, convert.paths, convert.parents, convert.families) for typ in convert.families},
- )
-
-
-def to_dict_variable(obj, with_files=True):
- if with_files:
- keys = ['name', 'path']
- else:
- keys = ['name', 'path', 'xmlfiles']
- return {key: value for key, value in dict(obj).items() if key not in keys and value is not None}
-
-
-def to_dict_family(family_name, paths, parents, families, root=True):
- ret = to_dict_variable(paths[family_name], root)
- for variable_path in parents[family_name]:
- variable = paths[variable_path]
- variable_name = variable.name
- if variable_path in families:
- if variable_name in ret:
- ret["_" + variable_name] = ret.pop(variable_name)
- ret[variable_name] = to_dict_family(variable.path, paths, parents, families, False)
+ loaded_custom_types_keys = list(convert.loaded_custom_types)
+ loaded_custom_types_keys.sort()
+ for path in loaded_custom_types_keys:
+ if "." not in path:
+ continue
+ current = None
+ *spath, name = path.split(".")
+ for subpath in spath:
+ if not current:
+ current = convert.loaded_custom_types[subpath]
+ else:
+ current = current.children[subpath]
+ current.children[name] = convert.loaded_custom_types.pop(path)
+ custom_variable_types = {}
+ custom_family_types = {}
+ for typ, data in convert.loaded_custom_types.items():
+ if data.option_type == 'variable':
+ custom_variable_types[typ] = data
else:
- ret[variable_name] = to_dict_variable(variable, False)
- return ret
+ custom_family_types[typ] = data
+ return {"custom_variable_types": custom_variable_types,
+ "custom_family_types": custom_family_types,
+ }
diff --git a/tests/dictionaries/00_0no_variable/tiramisu/base.py b/tests/dictionaries/00_0no_variable/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/00_0no_variable/tiramisu/base.py
+++ b/tests/dictionaries/00_0no_variable/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/00_0no_variable_default_version/tiramisu/base.py b/tests/dictionaries/00_0no_variable_default_version/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/00_0no_variable_default_version/tiramisu/base.py
+++ b/tests/dictionaries/00_0no_variable_default_version/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/00_0no_variable_remove_version/tiramisu/base.py b/tests/dictionaries/00_0no_variable_remove_version/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/00_0no_variable_remove_version/tiramisu/base.py
+++ b/tests/dictionaries/00_0no_variable_remove_version/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/00_9default_calculation/makedict/after.json b/tests/dictionaries/00_9default_calculation/makedict/after.json
index 406efb327..22d2591a3 100644
--- a/tests/dictionaries/00_9default_calculation/makedict/after.json
+++ b/tests/dictionaries/00_9default_calculation/makedict/after.json
@@ -1,6 +1,6 @@
{
"rougail.variable": {
"owner": "default",
- "value": "string_1_True_"
+ "value": "string_1_True_None"
}
}
diff --git a/tests/dictionaries/00_9default_calculation/makedict/base.json b/tests/dictionaries/00_9default_calculation/makedict/base.json
index a5a3e6b97..2b34a6249 100644
--- a/tests/dictionaries/00_9default_calculation/makedict/base.json
+++ b/tests/dictionaries/00_9default_calculation/makedict/base.json
@@ -1,3 +1,3 @@
{
- "rougail.variable": "string_1_True_"
+ "rougail.variable": "string_1_True_None"
}
diff --git a/tests/dictionaries/00_9default_calculation/makedict/before.json b/tests/dictionaries/00_9default_calculation/makedict/before.json
index 406efb327..22d2591a3 100644
--- a/tests/dictionaries/00_9default_calculation/makedict/before.json
+++ b/tests/dictionaries/00_9default_calculation/makedict/before.json
@@ -1,6 +1,6 @@
{
"rougail.variable": {
"owner": "default",
- "value": "string_1_True_"
+ "value": "string_1_True_None"
}
}
diff --git a/tests/dictionaries/00_9default_calculation/makedict/read_write.json b/tests/dictionaries/00_9default_calculation/makedict/read_write.json
index a5a3e6b97..2b34a6249 100644
--- a/tests/dictionaries/00_9default_calculation/makedict/read_write.json
+++ b/tests/dictionaries/00_9default_calculation/makedict/read_write.json
@@ -1,3 +1,3 @@
{
- "rougail.variable": "string_1_True_"
+ "rougail.variable": "string_1_True_None"
}
diff --git a/tests/dictionaries/16_2family_redefine_calculation/tiramisu/base.py b/tests/dictionaries/16_2family_redefine_calculation/tiramisu/base.py
index 4f81555b2..febd83ac7 100644
--- a/tests/dictionaries/16_2family_redefine_calculation/tiramisu/base.py
+++ b/tests/dictionaries/16_2family_redefine_calculation/tiramisu/base.py
@@ -12,6 +12,6 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['disabled_rougail.family'] = "true\n"
option_3 = StrOption(name="var1", doc="var1", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml'], 'type': 'string'})
-optiondescription_2 = OptionDescription(name="family", doc="family", children=[option_3], properties=frozenset({"basic", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue(None)), kwargs={'__internal_jinja': ParamValue("disabled_rougail.family"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("rougail.family"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']})
+optiondescription_2 = OptionDescription(name="family", doc="family", children=[option_3], properties=frozenset({"basic", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue(None)), kwargs={'__internal_jinja': ParamValue("disabled_rougail.family"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("rougail.family"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/dictionaries/16_2family_redefine_calculation/tiramisu/no_namespace.py b/tests/dictionaries/16_2family_redefine_calculation/tiramisu/no_namespace.py
index 014c91712..85aa01ae2 100644
--- a/tests/dictionaries/16_2family_redefine_calculation/tiramisu/no_namespace.py
+++ b/tests/dictionaries/16_2family_redefine_calculation/tiramisu/no_namespace.py
@@ -12,5 +12,5 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['disabled_family'] = "true\n"
option_2 = StrOption(name="var1", doc="var1", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml'], 'type': 'string'})
-optiondescription_1 = OptionDescription(name="family", doc="family", children=[option_2], properties=frozenset({"basic", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue(None)), kwargs={'__internal_jinja': ParamValue("disabled_family"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("family"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']})
+optiondescription_1 = OptionDescription(name="family", doc="family", children=[option_2], properties=frozenset({"basic", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue(None)), kwargs={'__internal_jinja': ParamValue("disabled_family"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("family"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['../rougail-tests/structures/16_2family_redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_2family_redefine_calculation/rougail/01-base.yml']})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/dictionaries/16_5redefine_calculation/tiramisu/base.py b/tests/dictionaries/16_5redefine_calculation/tiramisu/base.py
index 6d9c04d17..437f113c4 100644
--- a/tests/dictionaries/16_5redefine_calculation/tiramisu/base.py
+++ b/tests/dictionaries/16_5redefine_calculation/tiramisu/base.py
@@ -11,6 +11,6 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_rougail.variable'] = "yes"
-option_2 = StrOption(name="variable", doc="a variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.variable"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.variable")})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml'], 'type': 'string'})
+option_2 = StrOption(name="variable", doc="a variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.variable"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.variable")})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml'], 'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/dictionaries/16_5redefine_calculation/tiramisu/no_namespace.py b/tests/dictionaries/16_5redefine_calculation/tiramisu/no_namespace.py
index 572c4672c..4ae0fb40a 100644
--- a/tests/dictionaries/16_5redefine_calculation/tiramisu/no_namespace.py
+++ b/tests/dictionaries/16_5redefine_calculation/tiramisu/no_namespace.py
@@ -11,5 +11,5 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_variable'] = "yes"
-option_1 = StrOption(name="variable", doc="a variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_variable"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("variable")})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml'], 'type': 'string'})
+option_1 = StrOption(name="variable", doc="a variable", default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_variable"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("variable")})), properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/16_5redefine_calculation/rougail/00-base.yml', '../rougail-tests/structures/16_5redefine_calculation/rougail/01-base.yml'], 'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1])
diff --git a/tests/dictionaries/16_6exists_family/tiramisu/base.py b/tests/dictionaries/16_6exists_family/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/16_6exists_family/tiramisu/base.py
+++ b/tests/dictionaries/16_6exists_family/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py b/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py
index 1041b435b..bd61975d5 100644
--- a/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py
+++ b/tests/dictionaries/16_6exists_redefine_family/tiramisu/base.py
@@ -13,6 +13,6 @@ ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_2 = OptionDescription(name="family1", doc="new description", children=[option_3], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml', '../rougail-tests/structures/16_6exists_redefine_family/rougail/01-base.yml']})
option_5 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml'], 'type': 'string'})
-optiondescription_4 = OptionDescription(name="family2", doc="a second family", children=[option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml', '../rougail-tests/structures/16_6exists_redefine_family/rougail/01-base.yml']})
+optiondescription_4 = OptionDescription(name="family2", doc="a second family", children=[option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml']})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2, optiondescription_4], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py b/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py
index 1f3faea44..d77e97c3b 100644
--- a/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py
+++ b/tests/dictionaries/16_6exists_redefine_family/tiramisu/no_namespace.py
@@ -13,5 +13,5 @@ ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="variable1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_1 = OptionDescription(name="family1", doc="new description", children=[option_2], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml', '../rougail-tests/structures/16_6exists_redefine_family/rougail/01-base.yml']})
option_4 = StrOption(name="variable2", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml'], 'type': 'string'})
-optiondescription_3 = OptionDescription(name="family2", doc="a second family", children=[option_4], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml', '../rougail-tests/structures/16_6exists_redefine_family/rougail/01-base.yml']})
+optiondescription_3 = OptionDescription(name="family2", doc="a second family", children=[option_4], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/16_6exists_redefine_family/rougail/00-base.yml']})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_3])
diff --git a/tests/dictionaries/20_0empty_family/tiramisu/base.py b/tests/dictionaries/20_0empty_family/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/20_0empty_family/tiramisu/base.py
+++ b/tests/dictionaries/20_0empty_family/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/20_0validators_differ_redefine/tiramisu/base.py b/tests/dictionaries/20_0validators_differ_redefine/tiramisu/base.py
index b118b90be..5a3188aff 100644
--- a/tests/dictionaries/20_0validators_differ_redefine/tiramisu/base.py
+++ b/tests/dictionaries/20_0validators_differ_redefine/tiramisu/base.py
@@ -13,6 +13,6 @@ ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['validators_rougail.var3'] = "{% if _.var3 == _.var2 %}\nvar3 must be different than var2\n{% endif %}\n"
option_2 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml'], 'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml'], 'type': 'string'})
-option_4 = StrOption(name="var3", doc="a third variable", default="yes", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_rougail.var3"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("rougail.var3"), 'description': ParamValue(None), '_.var3': ParamSelfOption(whole=False), '_.var2': ParamOption(option_3, notraisepropertyerror=True)}))], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml'], 'type': 'string', 'test': ('yes',)})
+option_4 = StrOption(name="var3", doc="a third variable", default="yes", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_rougail.var3"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("rougail.var3"), 'description': ParamValue(None), '_.var3': ParamSelfOption(whole=False), '_.var2': ParamOption(option_3, notraisepropertyerror=True)}))], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml'], 'type': 'string', 'test': ('yes',)})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3, option_4], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/dictionaries/20_0validators_differ_redefine/tiramisu/no_namespace.py b/tests/dictionaries/20_0validators_differ_redefine/tiramisu/no_namespace.py
index 37e779ec6..d53ff3bfa 100644
--- a/tests/dictionaries/20_0validators_differ_redefine/tiramisu/no_namespace.py
+++ b/tests/dictionaries/20_0validators_differ_redefine/tiramisu/no_namespace.py
@@ -13,5 +13,5 @@ ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['validators_var3'] = "{% if _.var3 == _.var2 %}\nvar3 must be different than var2\n{% endif %}\n"
option_1 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml'], 'type': 'string'})
option_2 = StrOption(name="var2", doc="a second variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml'], 'type': 'string'})
-option_3 = StrOption(name="var3", doc="a third variable", default="yes", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_var3"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("var3"), 'description': ParamValue(None), '_.var3': ParamSelfOption(whole=False), '_.var2': ParamOption(option_2, notraisepropertyerror=True)}))], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml'], 'type': 'string', 'test': ('yes',)})
+option_3 = StrOption(name="var3", doc="a third variable", default="yes", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_var3"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("var3"), 'description': ParamValue(None), '_.var3': ParamSelfOption(whole=False), '_.var2': ParamOption(option_2, notraisepropertyerror=True)}))], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/20_0validators_differ_redefine/rougail/00-base.yml', '../rougail-tests/structures/20_0validators_differ_redefine/rougail/01-base.yml'], 'type': 'string', 'test': ('yes',)})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2, option_3])
diff --git a/tests/dictionaries/20_1empty_subfamily/tiramisu/base.py b/tests/dictionaries/20_1empty_subfamily/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/20_1empty_subfamily/tiramisu/base.py
+++ b/tests/dictionaries/20_1empty_subfamily/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/40_0leadership_empty/tiramisu/base.py b/tests/dictionaries/40_0leadership_empty/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/40_0leadership_empty/tiramisu/base.py
+++ b/tests/dictionaries/40_0leadership_empty/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/dictionaries/60_0family_empty/tiramisu/base.py b/tests/dictionaries/60_0family_empty/tiramisu/base.py
index d9e243d06..546fc18a6 100644
--- a/tests/dictionaries/60_0family_empty/tiramisu/base.py
+++ b/tests/dictionaries/60_0family_empty/tiramisu/base.py
@@ -10,5 +10,4 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[])
diff --git a/tests/errors/10_family_to_variable_redefine/errno_11 b/tests/errors/10_family_to_variable_redefine/errno_11
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/errors/10_family_to_variable_redefine/rougail/00-base.yml b/tests/errors/10_family_to_variable_redefine/rougail/00-base.yml
new file mode 100644
index 000000000..38ab0fd1e
--- /dev/null
+++ b/tests/errors/10_family_to_variable_redefine/rougail/00-base.yml
@@ -0,0 +1,5 @@
+---
+version: 1.1
+
+my_variable:
+ default: val1
diff --git a/tests/errors/10_family_to_variable_redefine/rougail/01-redefine.yml b/tests/errors/10_family_to_variable_redefine/rougail/01-redefine.yml
new file mode 100644
index 000000000..974acf413
--- /dev/null
+++ b/tests/errors/10_family_to_variable_redefine/rougail/01-redefine.yml
@@ -0,0 +1,6 @@
+---
+version: 1.1
+
+my_variable:
+ type: family
+ redefine: true
diff --git a/tests/errors/22_0calculation_family_in_leader/errno_17 b/tests/errors/22_0calculation_family_in_leader/errno_17
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/errors/22_0calculation_family_in_leader/rougail/00-base.yml b/tests/errors/22_0calculation_family_in_leader/rougail/00-base.yml
new file mode 100644
index 000000000..952d607ba
--- /dev/null
+++ b/tests/errors/22_0calculation_family_in_leader/rougail/00-base.yml
@@ -0,0 +1,16 @@
+---
+version: 1.1
+
+leadership:
+ description: a leadership
+ type: leadership
+
+ leader: # a leader
+ - value1
+ - value2
+
+ follower: # a follower
+
+ a_family: # A family
+
+ new_variable: # new variable
diff --git a/tests/personalize_mode/dictionary/00-base.yml b/tests/personalize_mode/dictionary/00-base.yml
index f080f3da2..f2c87fed7 100644
--- a/tests/personalize_mode/dictionary/00-base.yml
+++ b/tests/personalize_mode/dictionary/00-base.yml
@@ -1,7 +1,11 @@
-version: '1.0'
+---
+version: 1.1
+
general:
mode: level1
+
my_variable:
mode: level2
+
my_variable1:
mode: level1
diff --git a/tests/personalize_mode_without_family/dictionary/00-base.yml b/tests/personalize_mode_without_family/dictionary/00-base.yml
new file mode 100644
index 000000000..fa03c7fd8
--- /dev/null
+++ b/tests/personalize_mode_without_family/dictionary/00-base.yml
@@ -0,0 +1,8 @@
+---
+version: 1.1
+
+my_variable:
+ mode: level2
+
+my_variable1:
+ mode: level1
diff --git a/tests/result_tutorial/101/tiramisu.py b/tests/result_tutorial/101/tiramisu.py
deleted file mode 100644
index e867f7dd2..000000000
--- a/tests/result_tutorial/101/tiramisu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-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_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname'})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15])
diff --git a/tests/result_tutorial/102/tiramisu.py b/tests/result_tutorial/102/tiramisu.py
deleted file mode 100644
index b2eb363e6..000000000
--- a/tests/result_tutorial/102/tiramisu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-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_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname'})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15])
diff --git a/tests/result_tutorial/103/tiramisu.py b/tests/result_tutorial/103/tiramisu.py
deleted file mode 100644
index 8914a1e0e..000000000
--- a/tests/result_tutorial/103/tiramisu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-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_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24')})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15])
diff --git a/tests/result_tutorial/104/tiramisu.py b/tests/result_tutorial/104/tiramisu.py
deleted file mode 100644
index b1990e17e..000000000
--- a/tests/result_tutorial/104/tiramisu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-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_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15])
diff --git a/tests/result_tutorial/131/tiramisu.py b/tests/result_tutorial/131/tiramisu.py
index 78cac7632..6ba03ebf3 100644
--- a/tests/result_tutorial/131/tiramisu.py
+++ b/tests/result_tutorial/131/tiramisu.py
@@ -25,5 +25,4 @@ optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configu
option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
option_16 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_17 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15, option_16, option_17])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15, option_16])
diff --git a/tests/result_tutorial/112/tiramisu.py b/tests/result_tutorial/132/131/tiramisu.py
similarity index 79%
rename from tests/result_tutorial/112/tiramisu.py
rename to tests/result_tutorial/132/131/tiramisu.py
index 2e3f4d904..78cac7632 100644
--- a/tests/result_tutorial/112/tiramisu.py
+++ b/tests/result_tutorial/132/131/tiramisu.py
@@ -9,7 +9,6 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-dict_env['disabled_proxy_dns_socks5'] = "{{ _.proxy_mode != \"Manual proxy configuration\" or _.manual.socks_proxy.version == 'v4' }}"
option_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
@@ -18,13 +17,13 @@ option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS",
option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
+option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", type="domainname", allow_ip=True, properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
+option_12 = PortOption(name="port", doc="SOCKS proxy port", default="1080", allow_private=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_11), 'prop': ParamValue("disabled"), 'when': ParamValue(None), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
+option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_11), 'prop': ParamValue("disabled"), 'when': ParamValue(None), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
option_16 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_17 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.proxy_mode\" is not \"Manual proxy configuration\"\nor \"_.manual.socks_proxy.version\" is \"v4\"")), kwargs={'__internal_jinja': ParamValue("disabled_proxy_dns_socks5"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("proxy_dns_socks5"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.proxy_mode': ParamOption(option_1, notraisepropertyerror=True), '_.manual.socks_proxy.version': ParamOption(option_13, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
+option_17 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15, option_16, option_17])
diff --git a/tests/result_tutorial/141/tiramisu.py b/tests/result_tutorial/141/tiramisu.py
deleted file mode 100644
index f721e21ba..000000000
--- a/tests/result_tutorial/141/tiramisu.py
+++ /dev/null
@@ -1,33 +0,0 @@
-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")
-dict_env['disabled_proxy_dns_socks5'] = "{{ _.manual.socks_proxy.version is propertyerror or _.manual.socks_proxy.version == 'v4' }}"
-option_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
-option_16 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_17 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"advanced", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.proxy_mode\" is not \"Manual proxy configuration\"\nor \"_.manual.socks_proxy.version\" is \"v4\"")), kwargs={'__internal_jinja': ParamValue("disabled_proxy_dns_socks5"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("proxy_dns_socks5"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.manual.socks_proxy.version': ParamOption(option_13, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
-option_19 = BoolOption(name="enable_dns_over_https", doc="Enable DNS over HTTPS", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'boolean'})
-option_20 = ChoiceOption(name="provider", doc="Use Provider", values=("Cloudflare", "NextDNS", "Custom"), default="Cloudflare", properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_19), 'prop': ParamValue("disabled"), 'when': ParamValue(False), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'choice'})
-optiondescription_18 = OptionDescription(name="dns_over_https", doc="DNS over HTTPS", children=[option_19, option_20], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml']})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15, option_16, option_17, optiondescription_18])
diff --git a/tests/result_tutorial/142/tiramisu.py b/tests/result_tutorial/142/tiramisu.py
deleted file mode 100644
index 04aaf5ffb..000000000
--- a/tests/result_tutorial/142/tiramisu.py
+++ /dev/null
@@ -1,35 +0,0 @@
-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")
-dict_env['disabled_proxy_dns_socks5'] = "{{ _.manual.socks_proxy.version is propertyerror or _.manual.socks_proxy.version == 'v4' }}"
-dict_env['disabled_dns_over_https.custom_dns_url'] = "{{ _.provider is propertyerror or _.provider != 'Custom' }}"
-option_1 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_4 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_5 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_3 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_6 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_8 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_9 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_7 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_8, option_9], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_11 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_4)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_12 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_13 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_10 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_11, option_12, option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_2 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_3, option_6, optiondescription_7, optiondescription_10], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_14 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_15 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
-option_16 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_1), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_17 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"advanced", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.proxy_mode\" is not \"Manual proxy configuration\"\nor \"_.manual.socks_proxy.version\" is \"v4\"")), kwargs={'__internal_jinja': ParamValue("disabled_proxy_dns_socks5"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("proxy_dns_socks5"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.manual.socks_proxy.version': ParamOption(option_13, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
-option_19 = BoolOption(name="enable_dns_over_https", doc="Enable DNS over HTTPS", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'boolean'})
-option_20 = ChoiceOption(name="provider", doc="Use Provider", values=("Cloudflare", "NextDNS", "Custom"), default="Cloudflare", properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_19), 'prop': ParamValue("disabled"), 'when': ParamValue(False), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'choice'})
-option_21 = URLOption(name="custom_dns_url", doc="Custom DNS URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.provider\" is not \"Custom\"")), kwargs={'__internal_jinja': ParamValue("disabled_dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("dns_over_https.custom_dns_url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.provider': ParamOption(option_20, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'web_address'})
-optiondescription_18 = OptionDescription(name="dns_over_https", doc="DNS over HTTPS", children=[option_19, option_20, option_21], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml']})
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, optiondescription_2, option_14, option_15, option_16, option_17, optiondescription_18])
diff --git a/tests/result_tutorial/181/tiramisu.py b/tests/result_tutorial/181/tiramisu.py
index a732400d3..eb4a39d82 100644
--- a/tests/result_tutorial/181/tiramisu.py
+++ b/tests/result_tutorial/181/tiramisu.py
@@ -34,5 +34,4 @@ option_21 = ChoiceOption(name="provider", doc="Use Provider", values=("Cloudflar
option_22 = URLOption(name="custom_dns_url", doc="Custom DNS URL", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'description': ParamValue("must starts with 'https://' only"), '_.custom_dns_url': ParamSelfOption(whole=False)}))], allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.provider\" is not \"Custom\"")), kwargs={'__internal_jinja': ParamValue("disabled_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.provider': ParamOption(option_21, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'web_address'})
optiondescription_19 = OptionDescription(name="dns_over_https", doc="DNS over HTTPS", children=[option_20, option_21, option_22], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml']})
optiondescription_1 = OptionDescription(name="firefox", doc="firefox", group_type=groups.namespace, children=[option_2, optiondescription_3, option_15, option_16, option_17, option_18, optiondescription_19], properties=frozenset({"basic"}))
-optiondescription_23 = OptionDescription(name="foxyproxy", doc="foxyproxy", group_type=groups.namespace, children=[], properties=frozenset({"advanced"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_23])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
diff --git a/tests/result_tutorial/182/tiramisu.py b/tests/result_tutorial/182/tiramisu.py
deleted file mode 100644
index fd56d7255..000000000
--- a/tests/result_tutorial/182/tiramisu.py
+++ /dev/null
@@ -1,47 +0,0 @@
-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")
-class Regexp_option_26(RegexpOption):
- __slots__ = tuple()
- _type = 'value'
-Regexp_option_26._regexp = re_compile(r"^#(?:[0-9a-f]{3}){1,2}$")
-
-dict_env['disabled_firefox.proxy_dns_socks5'] = "{{ _.manual.socks_proxy.version is propertyerror or _.manual.socks_proxy.version == 'v4' }}"
-dict_env['validators_firefox.dns_over_https.custom_dns_url'] = "{{ _.custom_dns_url.startswith(\"http://\") }}"
-dict_env['disabled_firefox.dns_over_https.custom_dns_url'] = "{{ _.provider is propertyerror or _.provider != 'Custom' }}"
-dict_env['default_foxyproxy.proxies.color'] = "#{%- for i in range(6) -%}{{- '0123456789abcdef' | random -}}{%- endfor -%}"
-option_2 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_5 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_6 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_4 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_5, option_6], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_7 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_9 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_10 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_6)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_8 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_9, option_10], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_12 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_13 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_6)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_14 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_11 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_12, option_13, option_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_3 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_4, option_7, optiondescription_8, optiondescription_11], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_15 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_16 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
-option_17 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_18 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"advanced", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.proxy_mode\" is not \"Manual proxy configuration\"\nor \"_.manual.socks_proxy.version\" is \"v4\"")), kwargs={'__internal_jinja': ParamValue("disabled_firefox.proxy_dns_socks5"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("firefox.proxy_dns_socks5"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.manual.socks_proxy.version': ParamOption(option_14, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
-option_20 = BoolOption(name="enable_dns_over_https", doc="Enable DNS over HTTPS", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'boolean'})
-option_21 = ChoiceOption(name="provider", doc="Use Provider", values=("Cloudflare", "NextDNS", "Custom"), default="Cloudflare", properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_20), 'prop': ParamValue("disabled"), 'when': ParamValue(False), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'choice'})
-option_22 = URLOption(name="custom_dns_url", doc="Custom DNS URL", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'description': ParamValue("must starts with 'https://' only"), '_.custom_dns_url': ParamSelfOption(whole=False)}))], allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.provider\" is not \"Custom\"")), kwargs={'__internal_jinja': ParamValue("disabled_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.provider': ParamOption(option_21, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'web_address'})
-optiondescription_19 = OptionDescription(name="dns_over_https", doc="DNS over HTTPS", children=[option_20, option_21, option_22], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml']})
-optiondescription_1 = OptionDescription(name="firefox", doc="firefox", group_type=groups.namespace, children=[option_2, optiondescription_3, option_15, option_16, option_17, option_18, optiondescription_19], properties=frozenset({"basic"}))
-option_25 = StrOption(name="title", doc="Title or Description", multi=True, properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'string'})
-option_26 = Regexp_option_26(name="color", doc="Color", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_foxyproxy.proxies.color"), '__internal_type': ParamValue("regexp"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("foxyproxy.proxies.color")})), properties=frozenset({"basic", "force_store_value", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'regexp'})
-optiondescription_24 = Leadership(name="proxies", doc="Proxy configuration", children=[option_25, option_26], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']})
-optiondescription_23 = OptionDescription(name="foxyproxy", doc="foxyproxy", group_type=groups.namespace, children=[optiondescription_24], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_23])
diff --git a/tests/result_tutorial/211/tiramisu.py b/tests/result_tutorial/211/tiramisu.py
deleted file mode 100644
index a6a365612..000000000
--- a/tests/result_tutorial/211/tiramisu.py
+++ /dev/null
@@ -1,60 +0,0 @@
-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")
-class Regexp_option_27(RegexpOption):
- __slots__ = tuple()
- _type = 'value'
-Regexp_option_27._regexp = re_compile(r"^#(?:[0-9a-f]{3}){1,2}$")
-
-dict_env['disabled_firefox.proxy_dns_socks5'] = "{{ _.manual.socks_proxy.version is propertyerror or _.manual.socks_proxy.version == 'v4' }}"
-dict_env['validators_firefox.dns_over_https.custom_dns_url'] = "{{ _.custom_dns_url.startswith(\"http://\") }}"
-dict_env['disabled_firefox.dns_over_https.custom_dns_url'] = "{{ _.provider is propertyerror or _.provider != 'Custom' }}"
-dict_env['default_foxyproxy.proxies.color'] = "#{%- for i in range(6) -%}{{- '0123456789abcdef' | random -}}{%- endfor -%}"
-dict_env['disabled_foxyproxy.proxies.address'] = "{{ _.type not in ['HTTP', 'HTTPS/SSL', 'SOCKS4', 'SOCKS5'] }}"
-dict_env['disabled_foxyproxy.proxies.port'] = "{{ _.type not in ['HTTP', 'HTTPS/SSL', 'SOCKS4', 'SOCKS5'] }}"
-dict_env['disabled_foxyproxy.proxies.username'] = "{{ _.type not in ['HTTP', 'HTTPS/SSL', 'SOCKS4', 'SOCKS5'] }}"
-dict_env['hidden_foxyproxy.proxies.password'] = "{{ not _.username }}"
-dict_env['disabled_foxyproxy.proxies.password'] = "{{ _.type not in ['HTTP', 'HTTPS/SSL', 'SOCKS4', 'SOCKS5'] }}"
-dict_env['frozen_foxyproxy.proxies.password'] = "{{ not _.username }}"
-dict_env['disabled_foxyproxy.proxies.url'] = "{{ _.type not in ['PAC URL', 'WPAD'] }}"
-option_2 = ChoiceOption(name="proxy_mode", doc="Configure Proxy Access to the Internet", values=("No proxy", "Auto-detect proxy settings for this network", "Use system proxy settings", "Manual proxy configuration", "Automatic proxy configuration URL"), default="No proxy", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/00-proxy.yml'], 'type': 'choice'})
-option_5 = DomainnameOption(name="address", doc="HTTP proxy address", type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'domainname'})
-option_6 = PortOption(name="port", doc="HTTP proxy port", default="8080", allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml'], 'type': 'port'})
-optiondescription_4 = OptionDescription(name="http_proxy", doc="HTTP Proxy", children=[option_5, option_6], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/10-manual.yml']})
-option_7 = BoolOption(name="use_for_https", doc="Also use this proxy for HTTPS", default=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'boolean'})
-option_9 = DomainnameOption(name="address", doc="HTTPS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), type="domainname", allow_ip=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_10 = PortOption(name="port", doc="HTTPS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_6)))), allow_private=True, properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("frozen"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-optiondescription_8 = OptionDescription(name="https_proxy", doc="HTTPS Proxy", children=[option_9, option_10], properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("hidden"), 'when': ParamValue(True), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_12 = DomainnameOption(name="address", doc="SOCKS proxy address", default=Calculation(func['calc_value'], Params((ParamOption(option_5)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'domainname'})
-option_13 = PortOption(name="port", doc="SOCKS proxy port", default=Calculation(func['calc_value'], Params((ParamOption(option_6)))), allow_private=True, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'port'})
-option_14 = ChoiceOption(name="version", doc="SOCKS host version used by proxy", values=("v4", "v5"), default="v5", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/20-manual.yml'], 'type': 'choice'})
-optiondescription_11 = OptionDescription(name="socks_proxy", doc="SOCKS Proxy", children=[option_12, option_13, option_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/types/00-type.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-optiondescription_3 = OptionDescription(name="manual", doc="Manual proxy configuration", children=[optiondescription_4, option_7, optiondescription_8, optiondescription_11], properties=frozenset({"basic", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("Manual proxy configuration"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/10-manual.yml', 'tutorial_tmp/structural/firefox/20-manual.yml']})
-option_15 = URLOption(name="auto", doc="Automatic proxy configuration URL", allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("Automatic proxy configuration URL"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/30-auto.yml'], 'type': 'web_address'})
-option_16 = DomainnameOption(name="no_proxy", doc="Address for which proxy will be desactivated", multi=True, type="domainname", allow_ip=True, allow_cidr_network=True, allow_without_dot=True, allow_startswith_dot=True, properties=frozenset({"standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), '__internal_multi': ParamValue(True), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/40-no_proxy.yml'], 'type': 'domainname', 'examples': ('.mozilla.org', '.net.nz', '192.168.1.0/24'), 'help': 'Connections to localhost, 127.0.0.1/8 and ::1 are never proxied'})
-option_17 = BoolOption(name="prompt_authentication", doc="Prompt for authentication if password is saved", default=True, properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_2), 'prop': ParamValue("disabled"), 'when': ParamValue("No proxy"), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/50-prompt_authentication.yml'], 'type': 'boolean'})
-option_18 = BoolOption(name="proxy_dns_socks5", doc="Use proxy DNS when using SOCKS v5", default=False, properties=frozenset({"advanced", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.proxy_mode\" is not \"Manual proxy configuration\"\nor \"_.manual.socks_proxy.version\" is \"v4\"")), kwargs={'__internal_jinja': ParamValue("disabled_firefox.proxy_dns_socks5"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("firefox.proxy_dns_socks5"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.manual.socks_proxy.version': ParamOption(option_14, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/55-proxy_dns_socks5.yml'], 'type': 'boolean'})
-option_20 = BoolOption(name="enable_dns_over_https", doc="Enable DNS over HTTPS", default=False, properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'boolean'})
-option_21 = ChoiceOption(name="provider", doc="Use Provider", values=("Cloudflare", "NextDNS", "Custom"), default="Cloudflare", properties=frozenset({"mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_20), 'prop': ParamValue("disabled"), 'when': ParamValue(False), 'inverse': ParamValue(False)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'choice'})
-option_22 = URLOption(name="custom_dns_url", doc="Custom DNS URL", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("validators"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'description': ParamValue("must starts with 'https://' only"), '_.custom_dns_url': ParamSelfOption(whole=False)}))], allow_ip=False, allow_without_dot=True, properties=frozenset({"basic", "mandatory", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if \"_.provider\" is not \"Custom\"")), kwargs={'__internal_jinja': ParamValue("disabled_firefox.dns_over_https.custom_dns_url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/firefox/60-dns_over_https.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("firefox.dns_over_https.custom_dns_url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.provider': ParamOption(option_21, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml'], 'type': 'web_address'})
-optiondescription_19 = OptionDescription(name="dns_over_https", doc="DNS over HTTPS", children=[option_20, option_21, option_22], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/firefox/60-dns_over_https.yml']})
-optiondescription_1 = OptionDescription(name="firefox", doc="firefox", group_type=groups.namespace, children=[option_2, optiondescription_3, option_15, option_16, option_17, option_18, optiondescription_19], properties=frozenset({"basic"}))
-option_25 = StrOption(name="title", doc="Title or Description", multi=True, properties=frozenset({"standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'string'})
-option_26 = ChoiceOption(name="type", doc="Proxy Type", values=("HTTP", "HTTPS/SSL", "SOCKS4", "SOCKS5", "PAC URL", "WPAD", "System (use system settings)", "Direct (no proxy)"), multi=True, default_multi="Direct (no proxy)", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'choice'})
-option_27 = Regexp_option_27(name="color", doc="Color", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_foxyproxy.proxies.color"), '__internal_type': ParamValue("regexp"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("foxyproxy.proxies.color")})), properties=frozenset({"basic", "force_store_value", "mandatory"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'regexp'})
-option_28 = DomainnameOption(name="address", doc="IP address, DNS name, server name", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_5, notraisepropertyerror=True)))), type="domainname", allow_ip=True, allow_without_dot=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.address"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.address"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'domainname'})
-option_29 = PortOption(name="port", doc="Port", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_6, notraisepropertyerror=True)))), allow_private=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.port"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.port"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'port'})
-option_30 = UsernameOption(name="username", doc="Username", multi=True, properties=frozenset({"standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.username"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.username"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml'], 'type': 'unix_user'})
-option_31 = PasswordOption(name="password", doc="Password", multi=True, properties=frozenset({"force_default_on_freeze", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("hidden"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("hidden_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("hidden"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("frozen"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("frozen_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("frozen"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml'], 'type': 'secret'})
-option_32 = URLOption(name="url", doc="URL", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_15, notraisepropertyerror=True)))), allow_ip=False, allow_without_dot=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type is not in:\n- PAC URL\n- WPAD")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'web_address'})
-optiondescription_24 = Leadership(name="proxies", doc="Proxy configuration", children=[option_25, option_26, option_27, option_28, option_29, option_30, option_31, option_32], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml']})
-optiondescription_23 = OptionDescription(name="foxyproxy", doc="foxyproxy", group_type=groups.namespace, children=[optiondescription_24], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_23])
diff --git a/tests/result_tutorial/231/tiramisu.py b/tests/result_tutorial/231/tiramisu.py
index 6001b749a..5e7204c97 100644
--- a/tests/result_tutorial/231/tiramisu.py
+++ b/tests/result_tutorial/231/tiramisu.py
@@ -53,7 +53,7 @@ option_27 = Regexp_option_27(name="color", doc="Color", multi=True, default=Calc
option_28 = DomainnameOption(name="address", doc="IP address, DNS name, server name", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_5, notraisepropertyerror=True)))), type="domainname", allow_ip=True, allow_without_dot=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.address"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.address"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'domainname'})
option_29 = PortOption(name="port", doc="Port", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_6, notraisepropertyerror=True)))), allow_private=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.port"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.port"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'port'})
option_30 = UsernameOption(name="username", doc="Username", multi=True, properties=frozenset({"standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.username"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.username"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml'], 'type': 'unix_user'})
-option_31 = PasswordOption(name="password", doc="Password", multi=True, properties=frozenset({"force_default_on_freeze", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("hidden"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("hidden_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("hidden"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("frozen"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("frozen_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("frozen"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml'], 'type': 'secret'})
+option_31 = PasswordOption(name="password", doc="Password", multi=True, properties=frozenset({"force_default_on_freeze", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("hidden"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("hidden_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("hidden"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type not in:\n- HTTP\n- HTTPS/SSL\n- SOCKS4\n- SOCKS5")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help']), Calculation(func['jinja_to_property'], Params((ParamValue("frozen"), ParamValue("if username is empty")), kwargs={'__internal_jinja': ParamValue("frozen_foxyproxy.proxies.password"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml']), '__internal_attribute': ParamValue("frozen"), '__internal_variable': ParamValue("foxyproxy.proxies.password"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.username': ParamOption(option_30, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml'], 'type': 'secret'})
option_32 = URLOption(name="url", doc="URL", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_15, notraisepropertyerror=True)))), allow_ip=False, allow_without_dot=True, properties=frozenset({"mandatory", "standard", Calculation(func['jinja_to_property'], Params((ParamValue("disabled"), ParamValue("if type is not in:\n- PAC URL\n- WPAD")), kwargs={'__internal_jinja': ParamValue("disabled_foxyproxy.proxies.url"), '__internal_type': ParamValue("boolean"), '__internal_multi': ParamValue(False), '__internal_files': ParamValue(['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml']), '__internal_attribute': ParamValue("disabled"), '__internal_variable': ParamValue("foxyproxy.proxies.url"), 'when': ParamValue(True), 'inverse': ParamValue(False), '_.type': ParamOption(option_26, notraisepropertyerror=True)}), help_function=func['jinja_to_property_help'])}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml'], 'type': 'web_address'})
optiondescription_24 = Leadership(name="proxies", doc="Proxy configuration", children=[option_25, option_26, option_27, option_28, option_29, option_30, option_31, option_32], properties=frozenset({"basic"}), informations={'ymlfiles': ['tutorial_tmp/structural/foxyproxy/00-foxyproxy.yml', 'tutorial_tmp/structural/foxyproxy/10-redefine.yml']})
optiondescription_23 = OptionDescription(name="foxyproxy", doc="foxyproxy", group_type=groups.namespace, children=[optiondescription_24], properties=frozenset({"basic"}))
diff --git a/tests/test_1_flattener.py b/tests/test_1_flattener.py
index 839b3fbb1..b378997e7 100644
--- a/tests/test_1_flattener.py
+++ b/tests/test_1_flattener.py
@@ -142,7 +142,7 @@ def save(test_dir, eolobj, multi=False, namespace=False, error=False):
rmtree(tiramisu_tmp_dir)
-def test_structural_file(test_dir):
+def test_structural_file1(test_dir):
if not test_no_namespace:
print('NAMESPACE!')
return
diff --git a/tests/test_others.py b/tests/test_others.py
index 35b8720ef..8e4a6e0ab 100644
--- a/tests/test_others.py
+++ b/tests/test_others.py
@@ -6,11 +6,24 @@ from rougail.error import DictConsistencyError
from tiramisu.error import ConflictError
from rougail_tests.utils import config_to_dict
+from rougail.config import get_rougail_config
logger = logging.getLogger()
logger.setLevel(logging.INFO)
+def test_mode_unconfigured_mode():
+ # default variable mode is not in modes_level
+ rougailconfig = get_rougail_config(
+ backward_compatibility=False, add_extra_options=False
+ )
+ rougailconfig['main_structural_directories'] = ['tests/personalize_mode/dictionary']
+ eolobj = Rougail(rougailconfig=rougailconfig)
+ with raises(DictConsistencyError) as err:
+ eolobj.converted.annotate()
+ assert err.value.errno == 71
+
+
def test_mode_invalid_default():
# default variable mode is not in modes_level
rougailconfig = RougailConfig.copy()
@@ -56,6 +69,20 @@ def test_personalize_mode_unknown():
assert err.value.errno == 71
+def test_personalize_mode_unknown2():
+ # a variable has an unknown mode
+ rougailconfig = RougailConfig.copy()
+ rougailconfig['main_structural_directories'] = ['tests/personalize_mode_without_family/dictionary']
+ rougailconfig['main_namespace'] = None
+ rougailconfig['modes_level'] = ['level1']
+ rougailconfig['default_variable_mode'] = 'level1'
+ rougailconfig['default_family_mode'] = 'level1'
+ eolobj = Rougail(rougailconfig=rougailconfig)
+ with raises(DictConsistencyError) as err:
+ eolobj.converted.annotate()
+ assert err.value.errno == 71
+
+
def test_personalize_annotate_twice():
rougailconfig = RougailConfig.copy()
rougailconfig['main_structural_directories'] = ['tests/personalize_mode/dictionary']
diff --git a/tests/test_types.py b/tests/test_types.py
index a368339af..e5f49c7d7 100644
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -99,6 +99,12 @@ def test_type_family_redefine_namespace():
type_variable("family_redefine", namespace=True)
+def test_type_family_redefine_2():
+ with raises(DictConsistencyError) as err:
+ type_variable("family_redefine_family_types")
+ assert err.value.errno == 64
+
+
def test_type_family_subfamily():
type_variable("family_subfamily")
@@ -134,7 +140,7 @@ def test_type_family_subfamily_add_namespace():
def test_type_error_version():
with raises(DictConsistencyError) as err:
type_variable("error_version")
- assert err.errno == 27
+ assert err.value.errno == 27
def test_type_family_name_description():
@@ -147,3 +153,23 @@ def test_type_leadership():
def test_type_leadership_namespace():
type_variable("leadership", namespace=True)
+
+
+def test_type_error_redefine():
+ type_variable("error_variable_redefine", namespace=True)
+
+
+def test_type_secret():
+ type_variable("secret_manager")
+
+
+def test_type_secret_namespace():
+ type_variable("secret_manager", namespace=True)
+
+
+def test_type_family_secret():
+ type_variable("family_secret_manager")
+
+
+def test_type_family_secret_namespace():
+ type_variable("family_secret_manager", namespace=True)
diff --git a/tests/types/result/error_variable_redefine/namespace_tiramisu.py b/tests/types/result/error_variable_redefine/namespace_tiramisu.py
new file mode 100644
index 000000000..646f6ea3d
--- /dev/null
+++ b/tests/types/result/error_variable_redefine/namespace_tiramisu.py
@@ -0,0 +1,13 @@
+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_1 = StrOption(name="my_var", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/error_variable_redefine/00_type.yml', 'tests/types/structures/error_variable_redefine/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1])
diff --git a/tests/types/result/error_variable_redefine/namespace_variables.json b/tests/types/result/error_variable_redefine/namespace_variables.json
new file mode 100644
index 000000000..9a5fd9c00
--- /dev/null
+++ b/tests/types/result/error_variable_redefine/namespace_variables.json
@@ -0,0 +1,3 @@
+{
+ "my_var": "a value"
+}
\ No newline at end of file
diff --git a/tests/types/result/error_variable_redefine/namespace_variables_rw.json b/tests/types/result/error_variable_redefine/namespace_variables_rw.json
new file mode 100644
index 000000000..9a5fd9c00
--- /dev/null
+++ b/tests/types/result/error_variable_redefine/namespace_variables_rw.json
@@ -0,0 +1,3 @@
+{
+ "my_var": "a value"
+}
\ No newline at end of file
diff --git a/tests/types/result/family/tiramisu.py b/tests/types/result/family/tiramisu.py
index acc39eda4..802c570d0 100644
--- a/tests/types/result/family/tiramisu.py
+++ b/tests/types/result/family/tiramisu.py
@@ -9,7 +9,7 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-option_3 = StrOption(name="my_type", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/family/00_type.yml', 'tests/types/structures/family/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
-optiondescription_2 = OptionDescription(name="my_family", doc="My family type", children=[option_3], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family/00_type.yml', 'tests/types/structures/family/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2], properties=frozenset({"standard"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="my_type", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/family/00_type.yml', 'tests/types/structures/family/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
+optiondescription_3 = OptionDescription(name="my_family", doc="My family type", children=[option_4], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family/00_type.yml', 'tests/types/structures/family/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3], properties=frozenset({"standard"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_dynfamily/tiramisu.py b/tests/types/result/family_dynfamily/tiramisu.py
index af179b46d..2fd306605 100644
--- a/tests/types/result/family_dynfamily/tiramisu.py
+++ b/tests/types/result/family_dynfamily/tiramisu.py
@@ -9,20 +9,20 @@ except:
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_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_5 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_6 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_4 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_5, option_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-optiondescription_2 = OptionDescription(name="my_family_1", doc="My family type", children=[option_3, optiondescription_4], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-option_8 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_10 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_11 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_9 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_10, option_11], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-optiondescription_7 = OptionDescription(name="my_family_2", doc="My family type", children=[option_8, optiondescription_9], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-option_13 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_15 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-option_16 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_14 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_15, option_16], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-optiondescription_12 = OptionDescription(name="my_family_3", doc="My family type", children=[option_13, optiondescription_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_7, optiondescription_12], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="a_first_variable", doc="a first variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_6 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_7 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_5 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_6, option_7], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
+optiondescription_3 = OptionDescription(name="my_family_1", doc="My family type", children=[option_4, optiondescription_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/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_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_11 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_12 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_10 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_11, option_12], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
+optiondescription_8 = OptionDescription(name="my_family_2", doc="My family type", children=[option_9, optiondescription_10], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
+option_14 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_16 = StrOption(name="identifier", doc="identifier", multi=True, default=["family"], default_multi="family", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+option_17 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_15 = OptionDescription(name="a_sub_{{Â identifier }}", doc="My sub{{ identifier }}", children=[option_16, option_17], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
+optiondescription_13 = OptionDescription(name="my_family_3", doc="My family type", children=[option_14, optiondescription_15], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_dynfamily/00_structure.yml', 'tests/types/structures/family_dynfamily/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_8, optiondescription_13], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_name_description/tiramisu.py b/tests/types/result/family_name_description/tiramisu.py
index 393dd86a4..eb2c3d990 100644
--- a/tests/types/result/family_name_description/tiramisu.py
+++ b/tests/types/result/family_name_description/tiramisu.py
@@ -9,9 +9,9 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-option_3 = StrOption(name="description", doc="My second variable", default="an other new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
-option_4 = StrOption(name="type", doc="My third variable", default="again an other new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
-option_5 = StrOption(name="name", doc="My first variable", default="a new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
-optiondescription_2 = OptionDescription(name="my_family", doc="my_family", children=[option_3, option_4, option_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2], properties=frozenset({"standard"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="name", doc="My first variable", default="a new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
+option_5 = StrOption(name="description", doc="My second variable", default="an other new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
+option_6 = StrOption(name="type", doc="My third variable", default="again an other new value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml'], 'type': 'string'})
+optiondescription_3 = OptionDescription(name="my_family", doc="My family type", children=[option_4, option_5, option_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_name_description/00_structure.yml', 'tests/types/structures/family_name_description/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3], properties=frozenset({"standard"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_redefine/tiramisu.py b/tests/types/result/family_redefine/tiramisu.py
index 2e35af0b7..94b368c7f 100644
--- a/tests/types/result/family_redefine/tiramisu.py
+++ b/tests/types/result/family_redefine/tiramisu.py
@@ -9,14 +9,14 @@ except:
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', 'tests/types/structures/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', 'tests/types/structures/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', 'tests/types/structures/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="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_5, optiondescription_8], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = 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_5 = 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_3 = OptionDescription(name="my_family_1", doc="My family type", children=[option_4, option_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
+option_7 = 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', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
+option_8 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
+optiondescription_6 = OptionDescription(name="my_family_2", doc="My family type", children=[option_7, option_8], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
+option_10 = 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', 'tests/types/structures/family_redefine/00_structure.yml'], 'type': 'string'})
+option_11 = 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_9 = OptionDescription(name="my_family_3", doc="My family type", children=[option_10, option_11], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_redefine/00_structure.yml', 'tests/types/structures/family_redefine/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_6, optiondescription_9], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_secret_manager/namespace_tiramisu.py b/tests/types/result/family_secret_manager/namespace_tiramisu.py
new file mode 100644
index 000000000..ae027782f
--- /dev/null
+++ b/tests/types/result/family_secret_manager/namespace_tiramisu.py
@@ -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
+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="a_variable", doc="A variable", default="my_value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'string'})
+option_3 = PasswordOption(name="secret", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'secret'})
+optiondescription_1 = OptionDescription(name="secret1", doc="Family with secret", children=[option_2, option_3], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml']})
+option_5 = StrOption(name="a_variable", doc="A variable", default="my_value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'string'})
+option_6 = PasswordOption(name="secret", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'secret'})
+optiondescription_4 = OptionDescription(name="secret2", doc="Family with secret", children=[option_5, option_6], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml']})
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_4])
diff --git a/tests/types/result/family_secret_manager/namespace_variables.json b/tests/types/result/family_secret_manager/namespace_variables.json
new file mode 100644
index 000000000..5aed2ce54
--- /dev/null
+++ b/tests/types/result/family_secret_manager/namespace_variables.json
@@ -0,0 +1,6 @@
+{
+ "secret1.a_variable": "my_value",
+ "secret1.secret": null,
+ "secret2.a_variable": "my_value",
+ "secret2.secret": null
+}
\ No newline at end of file
diff --git a/tests/types/result/family_secret_manager/namespace_variables_rw.json b/tests/types/result/family_secret_manager/namespace_variables_rw.json
new file mode 100644
index 000000000..5aed2ce54
--- /dev/null
+++ b/tests/types/result/family_secret_manager/namespace_variables_rw.json
@@ -0,0 +1,6 @@
+{
+ "secret1.a_variable": "my_value",
+ "secret1.secret": null,
+ "secret2.a_variable": "my_value",
+ "secret2.secret": null
+}
\ No newline at end of file
diff --git a/tests/types/result/family_secret_manager/tiramisu.py b/tests/types/result/family_secret_manager/tiramisu.py
new file mode 100644
index 000000000..6fa66b651
--- /dev/null
+++ b/tests/types/result/family_secret_manager/tiramisu.py
@@ -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
+try:
+ groups.namespace
+except:
+ groups.addgroup('namespace')
+ALLOWED_LEADER_PROPERTIES.add("basic")
+ALLOWED_LEADER_PROPERTIES.add("standard")
+ALLOWED_LEADER_PROPERTIES.add("advanced")
+option_4 = StrOption(name="a_variable", doc="A variable", default="my_value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'string'})
+option_5 = PasswordOption(name="secret", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'secret'})
+optiondescription_3 = OptionDescription(name="secret1", doc="Family with secret", children=[option_4, option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml']})
+option_7 = StrOption(name="a_variable", doc="A variable", default="my_value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'string'})
+option_8 = PasswordOption(name="secret", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml'], 'type': 'secret'})
+optiondescription_6 = OptionDescription(name="secret2", doc="Family with secret", children=[option_7, option_8], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_secret_manager/00-base.yml', 'tests/types/structures/family_secret_manager/00-base.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_6], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_secret_manager/variables.json b/tests/types/result/family_secret_manager/variables.json
new file mode 100644
index 000000000..6d5792c33
--- /dev/null
+++ b/tests/types/result/family_secret_manager/variables.json
@@ -0,0 +1,6 @@
+{
+ "ns2.secret1.a_variable": "my_value",
+ "ns2.secret1.secret": null,
+ "ns2.secret2.a_variable": "my_value",
+ "ns2.secret2.secret": null
+}
\ No newline at end of file
diff --git a/tests/types/result/family_secret_manager/variables_rw.json b/tests/types/result/family_secret_manager/variables_rw.json
new file mode 100644
index 000000000..6d5792c33
--- /dev/null
+++ b/tests/types/result/family_secret_manager/variables_rw.json
@@ -0,0 +1,6 @@
+{
+ "ns2.secret1.a_variable": "my_value",
+ "ns2.secret1.secret": null,
+ "ns2.secret2.a_variable": "my_value",
+ "ns2.secret2.secret": null
+}
\ No newline at end of file
diff --git a/tests/types/result/family_subfamily/tiramisu.py b/tests/types/result/family_subfamily/tiramisu.py
index 9f1c98795..739b8f60e 100644
--- a/tests/types/result/family_subfamily/tiramisu.py
+++ b/tests/types/result/family_subfamily/tiramisu.py
@@ -9,17 +9,17 @@ except:
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_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-option_5 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_4 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-optiondescription_2 = OptionDescription(name="my_family_1", doc="My family type", children=[option_3, optiondescription_4], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-option_7 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-option_9 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_8 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_9], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-optiondescription_6 = OptionDescription(name="my_family_2", doc="My family type", children=[option_7, optiondescription_8], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-option_11 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-option_13 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
-optiondescription_12 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-optiondescription_10 = OptionDescription(name="my_family_3", doc="My family type", children=[option_11, optiondescription_12], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_6, optiondescription_10], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="a_first_variable", doc="a first variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+option_6 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_5 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+optiondescription_3 = OptionDescription(name="my_family_1", doc="My family type", children=[option_4, optiondescription_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+option_8 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+option_10 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_9 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_10], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+optiondescription_7 = OptionDescription(name="my_family_2", doc="My family type", children=[option_8, optiondescription_9], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+option_12 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+option_14 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml'], 'type': 'string'})
+optiondescription_13 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+optiondescription_11 = OptionDescription(name="my_family_3", doc="My family type", children=[option_12, optiondescription_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily/00_structure.yml', 'tests/types/structures/family_subfamily/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_7, optiondescription_11], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/family_subfamily_add/namespace_tiramisu.py b/tests/types/result/family_subfamily_add/namespace_tiramisu.py
index ec0de4665..0640f88d1 100644
--- a/tests/types/result/family_subfamily_add/namespace_tiramisu.py
+++ b/tests/types/result/family_subfamily_add/namespace_tiramisu.py
@@ -20,8 +20,8 @@ option_10 = StrOption(name="a_second_variable", doc="a second variable", propert
optiondescription_9 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_10], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
optiondescription_7 = OptionDescription(name="my_family_2", doc="My family type", children=[option_8, optiondescription_9], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
option_12 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-option_14 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_13 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-option_15 = StrOption(name="a_new_variable", doc="a_new_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_11 = OptionDescription(name="my_family_3", doc="My family type", children=[option_12, optiondescription_13, option_15], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+option_13 = StrOption(name="a_new_variable", doc="a_new_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+option_15 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+optiondescription_14 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_15], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+optiondescription_11 = OptionDescription(name="my_family_3", doc="My family type", children=[option_12, option_13, optiondescription_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_7, optiondescription_11])
diff --git a/tests/types/result/family_subfamily_add/tiramisu.py b/tests/types/result/family_subfamily_add/tiramisu.py
index 6ce3cf339..79ab198e3 100644
--- a/tests/types/result/family_subfamily_add/tiramisu.py
+++ b/tests/types/result/family_subfamily_add/tiramisu.py
@@ -9,20 +9,20 @@ except:
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_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-option_5 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_4 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-option_7 = StrOption(name="a_second_variable", doc="a_second_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_6 = OptionDescription(name="a_new_subfamily", doc="a_new_subfamily", children=[option_7], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml']})
-optiondescription_2 = OptionDescription(name="my_family_1", doc="My family type", children=[option_3, optiondescription_4, optiondescription_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/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_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-option_11 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_10 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_11], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-optiondescription_8 = OptionDescription(name="my_family_2", doc="My family type", children=[option_9, optiondescription_10], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-option_13 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-option_15 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_14 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_15], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-option_16 = StrOption(name="a_new_variable", doc="a_new_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
-optiondescription_12 = OptionDescription(name="my_family_3", doc="My family type", children=[option_13, optiondescription_14, option_16], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_8, optiondescription_12], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="a_first_variable", doc="a first variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+option_6 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+optiondescription_5 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+option_8 = StrOption(name="a_second_variable", doc="a_second_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+optiondescription_7 = OptionDescription(name="a_new_subfamily", doc="a_new_subfamily", children=[option_8], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml']})
+optiondescription_3 = OptionDescription(name="my_family_1", doc="My family type", children=[option_4, optiondescription_5, optiondescription_7], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+option_10 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+option_12 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+optiondescription_11 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_12], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+optiondescription_9 = OptionDescription(name="my_family_2", doc="My family type", children=[option_10, optiondescription_11], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+option_14 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+option_15 = StrOption(name="a_new_variable", doc="a_new_variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+option_17 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml'], 'type': 'string'})
+optiondescription_16 = OptionDescription(name="a_sub_family", doc="My subfamily", children=[option_17], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+optiondescription_13 = OptionDescription(name="my_family_3", doc="My family type", children=[option_14, option_15, optiondescription_16], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/family_subfamily_add/00_structure.yml', 'tests/types/structures/family_subfamily_add/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_9, optiondescription_13], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/leadership/tiramisu.py b/tests/types/result/leadership/tiramisu.py
index b176609ff..5a9e3587b 100644
--- a/tests/types/result/leadership/tiramisu.py
+++ b/tests/types/result/leadership/tiramisu.py
@@ -9,26 +9,26 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-option_4 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_5 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_6 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-optiondescription_3 = Leadership(name="my_leadership", doc="my_leadership", children=[option_4, option_5, option_6], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-optiondescription_2 = OptionDescription(name="my_leadership_1", doc="My family type", children=[optiondescription_3], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-option_9 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_10 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_11 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-optiondescription_8 = Leadership(name="my_leadership", doc="my_leadership", children=[option_9, option_10, option_11], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-optiondescription_7 = OptionDescription(name="my_leadership_2", doc="My family type", children=[optiondescription_8], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-option_14 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_15 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_16 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_17 = StrOption(name="a_new_follower", doc="a description", multi=True, default_multi="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-optiondescription_13 = Leadership(name="my_leadership", doc="my_leadership", children=[option_14, option_15, option_16, option_17], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-optiondescription_12 = OptionDescription(name="my_leadership_3", doc="My family type", children=[optiondescription_13], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-option_20 = StrOption(name="a_leader", doc="a description", multi=True, default=["a value leader", "a second leader"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_21 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-option_22 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
-optiondescription_19 = Leadership(name="my_leadership", doc="my_leadership", children=[option_20, option_21, option_22], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-optiondescription_18 = OptionDescription(name="my_leadership_4", doc="My family type", children=[optiondescription_19], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_7, optiondescription_12, optiondescription_18], properties=frozenset({"standard"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_5 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_6 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_7 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+optiondescription_4 = Leadership(name="my_leadership", doc="my_leadership", children=[option_5, option_6, option_7], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+optiondescription_3 = OptionDescription(name="my_leadership_1", doc="My family type", children=[optiondescription_4], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+option_10 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_11 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_12 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+optiondescription_9 = Leadership(name="my_leadership", doc="my_leadership", children=[option_10, option_11, option_12], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+optiondescription_8 = OptionDescription(name="my_leadership_2", doc="My family type", children=[optiondescription_9], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+option_15 = StrOption(name="a_leader", doc="My first variable", multi=True, default=["a value"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_16 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_17 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_18 = StrOption(name="a_new_follower", doc="a description", multi=True, default_multi="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+optiondescription_14 = Leadership(name="my_leadership", doc="my_leadership", children=[option_15, option_16, option_17, option_18], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+optiondescription_13 = OptionDescription(name="my_leadership_3", doc="My family type", children=[optiondescription_14], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+option_21 = StrOption(name="a_leader", doc="a description", multi=True, default=["a value leader", "a second leader"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_22 = StrOption(name="a_first_follower", doc="My second variable", multi=True, default_multi="an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+option_23 = StrOption(name="a_second_follower", doc="My third variable", multi=True, default_multi="again an other value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml'], 'type': 'string'})
+optiondescription_20 = Leadership(name="my_leadership", doc="my_leadership", children=[option_21, option_22, option_23], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+optiondescription_19 = OptionDescription(name="my_leadership_4", doc="My family type", children=[optiondescription_20], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/leadership/00_type.yml', 'tests/types/structures/leadership/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_8, optiondescription_13, optiondescription_19], properties=frozenset({"standard"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/secret_manager/namespace_tiramisu.py b/tests/types/result/secret_manager/namespace_tiramisu.py
new file mode 100644
index 000000000..5e2e4abeb
--- /dev/null
+++ b/tests/types/result/secret_manager/namespace_tiramisu.py
@@ -0,0 +1,14 @@
+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_1 = PasswordOption(name="secret1", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/secret_manager/00-base.yml', 'tests/types/structures/secret_manager/00-base.yml'], 'type': 'secret'})
+option_2 = PasswordOption(name="secret2", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/secret_manager/00-base.yml', 'tests/types/structures/secret_manager/00-base.yml'], 'type': 'secret'})
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])
diff --git a/tests/types/result/secret_manager/namespace_variables.json b/tests/types/result/secret_manager/namespace_variables.json
new file mode 100644
index 000000000..dc44d59c1
--- /dev/null
+++ b/tests/types/result/secret_manager/namespace_variables.json
@@ -0,0 +1,4 @@
+{
+ "secret1": null,
+ "secret2": null
+}
\ No newline at end of file
diff --git a/tests/types/result/secret_manager/namespace_variables_rw.json b/tests/types/result/secret_manager/namespace_variables_rw.json
new file mode 100644
index 000000000..dc44d59c1
--- /dev/null
+++ b/tests/types/result/secret_manager/namespace_variables_rw.json
@@ -0,0 +1,4 @@
+{
+ "secret1": null,
+ "secret2": null
+}
\ No newline at end of file
diff --git a/tests/types/result/secret_manager/tiramisu.py b/tests/types/result/secret_manager/tiramisu.py
new file mode 100644
index 000000000..ecf9bc146
--- /dev/null
+++ b/tests/types/result/secret_manager/tiramisu.py
@@ -0,0 +1,15 @@
+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 = PasswordOption(name="secret1", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/secret_manager/00-base.yml', 'tests/types/structures/secret_manager/00-base.yml'], 'type': 'secret'})
+option_4 = PasswordOption(name="secret2", doc="the secret", properties=frozenset({"basic", "mandatory", "novalidator"}), informations={'ymlfiles': ['tests/types/types/secret_manager/00-base.yml', 'tests/types/structures/secret_manager/00-base.yml'], 'type': 'secret'})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/secret_manager/variables.json b/tests/types/result/secret_manager/variables.json
new file mode 100644
index 000000000..e9ed53524
--- /dev/null
+++ b/tests/types/result/secret_manager/variables.json
@@ -0,0 +1,4 @@
+{
+ "ns2.secret1": null,
+ "ns2.secret2": null
+}
\ No newline at end of file
diff --git a/tests/types/result/secret_manager/variables_rw.json b/tests/types/result/secret_manager/variables_rw.json
new file mode 100644
index 000000000..e9ed53524
--- /dev/null
+++ b/tests/types/result/secret_manager/variables_rw.json
@@ -0,0 +1,4 @@
+{
+ "ns2.secret1": null,
+ "ns2.secret2": null
+}
\ No newline at end of file
diff --git a/tests/types/result/variable/tiramisu.py b/tests/types/result/variable/tiramisu.py
index dbf745372..2d08e2ec3 100644
--- a/tests/types/result/variable/tiramisu.py
+++ b/tests/types/result/variable/tiramisu.py
@@ -9,6 +9,6 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-option_2 = StrOption(name="my_var", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/variable/00_type.yml', 'tests/types/structures/variable/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[option_2], properties=frozenset({"standard"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_3 = StrOption(name="my_var", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/variable/00_type.yml', 'tests/types/structures/variable/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/variable_hidden/tiramisu.py b/tests/types/result/variable_hidden/tiramisu.py
index 0f1b98d3c..935764555 100644
--- a/tests/types/result/variable_hidden/tiramisu.py
+++ b/tests/types/result/variable_hidden/tiramisu.py
@@ -9,14 +9,14 @@ except:
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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
-option_4 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_3), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_3), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
-option_7 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "force_default_on_freeze", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_6), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
-option_10 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_9), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_9), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/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/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml']})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_2, optiondescription_5, optiondescription_8], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_4 = StrOption(name="a_first_variable", doc="a first variable", default="a modified value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+option_5 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value", properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_4), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_4), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+optiondescription_3 = OptionDescription(name="my_family_1", doc="My family type", children=[option_4, option_5], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml']})
+option_7 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+option_8 = StrOption(name="a_second_variable", doc="a second variable", properties=frozenset({"basic", "force_default_on_freeze", "mandatory", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_7), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+optiondescription_6 = OptionDescription(name="my_family_2", doc="My family type", children=[option_7, option_8], properties=frozenset({"basic"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml']})
+option_10 = StrOption(name="a_first_variable", doc="a first variable", default="a value", properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+option_11 = StrOption(name="a_second_variable", doc="a second variable", default="a modified value 2", properties=frozenset({"force_default_on_freeze", "mandatory", "standard", Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_10), 'prop': ParamValue("hidden"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property']), Calculation(func['variable_to_property'], Params((), kwargs={'value': ParamOption(option_10), 'prop': ParamValue("frozen"), 'when': ParamValue("a value"), 'inverse': ParamValue(True)}), help_function=func['variable_to_property'])}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml'], 'type': 'string'})
+optiondescription_9 = OptionDescription(name="my_family_3", doc="My family type", children=[option_10, option_11], properties=frozenset({"standard"}), informations={'ymlfiles': ['tests/types/types/variable_hidden/00_structure.yml', 'tests/types/structures/variable_hidden/00_structure.yml']})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[optiondescription_3, optiondescription_6, optiondescription_9], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/result/variables/tiramisu.py b/tests/types/result/variables/tiramisu.py
index 0a219e8dc..375d17cad 100644
--- a/tests/types/result/variables/tiramisu.py
+++ b/tests/types/result/variables/tiramisu.py
@@ -9,8 +9,8 @@ except:
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
-option_2 = StrOption(name="my_var1", doc="My type", default="a value", properties=frozenset({"an_other_tag", "mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/variables/00_type.yml', 'tests/types/structures/variables/00_structure.yml'], 'type': 'string', 'tags': ('an_other_tag',)})
-option_3 = StrOption(name="my_var2", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/variables/00_type.yml', 'tests/types/structures/variables/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
-option_4 = StrOption(name="my_var3", doc="my_var3", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/structures/variables/00_structure.yml'], 'type': 'string'})
-optiondescription_1 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[option_2, option_3, option_4], properties=frozenset({"basic"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])
+option_3 = StrOption(name="my_var1", doc="My type", default="a value", properties=frozenset({"an_other_tag", "mandatory", "standard"}), informations={'ymlfiles': ['tests/types/types/variables/00_type.yml', 'tests/types/structures/variables/00_structure.yml'], 'type': 'string', 'tags': ('an_other_tag',)})
+option_4 = StrOption(name="my_var2", doc="My type", default="a value", properties=frozenset({"mandatory", "one_tag", "standard"}), informations={'ymlfiles': ['tests/types/types/variables/00_type.yml', 'tests/types/structures/variables/00_structure.yml'], 'type': 'string', 'tags': ('one_tag',)})
+option_5 = StrOption(name="my_var3", doc="my_var3", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['tests/types/structures/variables/00_structure.yml'], 'type': 'string'})
+optiondescription_2 = OptionDescription(name="ns2", doc="NS2", group_type=groups.namespace, children=[option_3, option_4, option_5], properties=frozenset({"basic"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_2])
diff --git a/tests/types/structures/error_variable_redefine/00_structure.yml b/tests/types/structures/error_variable_redefine/00_structure.yml
new file mode 100644
index 000000000..420820273
--- /dev/null
+++ b/tests/types/structures/error_variable_redefine/00_structure.yml
@@ -0,0 +1,8 @@
+%YAML 1.2
+---
+version: 1.1
+
+my_var:
+ type: my_type
+ description: My type
+...
diff --git a/tests/types/structures/family_redefine_family_types/00_structure.yml b/tests/types/structures/family_redefine_family_types/00_structure.yml
new file mode 100644
index 000000000..4322ff966
--- /dev/null
+++ b/tests/types/structures/family_redefine_family_types/00_structure.yml
@@ -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: family
+
+my_family_3:
+ type: my_family_type
+
+ a_second_variable: a modified value 2
+...
diff --git a/tests/types/structures/family_redefine_family_types/01_redefine.yml b/tests/types/structures/family_redefine_family_types/01_redefine.yml
new file mode 100644
index 000000000..4f2d56866
--- /dev/null
+++ b/tests/types/structures/family_redefine_family_types/01_redefine.yml
@@ -0,0 +1,7 @@
+%YAML 1.2
+---
+version: 1.1
+
+my_family_2:
+ type: my_family_type
+...
diff --git a/tests/types/structures/family_secret_manager/00-base.yml b/tests/types/structures/family_secret_manager/00-base.yml
new file mode 100644
index 000000000..b00f0e7ec
--- /dev/null
+++ b/tests/types/structures/family_secret_manager/00-base.yml
@@ -0,0 +1,10 @@
+%YAML 1.2
+---
+version: 1.1
+
+secret1:
+ type: family_secret
+
+secret2:
+ type: family_secret
+...
diff --git a/tests/types/structures/secret_manager/00-base.yml b/tests/types/structures/secret_manager/00-base.yml
new file mode 100644
index 000000000..a862db3a2
--- /dev/null
+++ b/tests/types/structures/secret_manager/00-base.yml
@@ -0,0 +1,10 @@
+%YAML 1.2
+---
+version: 1.1
+
+secret1:
+ type: secret
+
+secret2:
+ type: secret
+...
diff --git a/tests/types/types/error_variable_redefine/00_type.yml b/tests/types/types/error_variable_redefine/00_type.yml
new file mode 100644
index 000000000..c22439517
--- /dev/null
+++ b/tests/types/types/error_variable_redefine/00_type.yml
@@ -0,0 +1,10 @@
+%YAML 1.2
+---
+version: 1.1
+
+my_type:
+ description: My type
+ default: a value
+ tags:
+ - one_tag
+...
diff --git a/tests/types/types/family_redefine_family_types/00_structure.yml b/tests/types/types/family_redefine_family_types/00_structure.yml
new file mode 100644
index 000000000..79c52daeb
--- /dev/null
+++ b/tests/types/types/family_redefine_family_types/00_structure.yml
@@ -0,0 +1,10 @@
+%YAML 1.2
+---
+version: 1.1
+
+my_family_type: # My family type
+
+ a_first_variable: a value # a first variable
+
+ a_second_variable: # a second variable
+...
diff --git a/tests/types/types/family_secret_manager/00-base.yml b/tests/types/types/family_secret_manager/00-base.yml
new file mode 100644
index 000000000..1ec36212a
--- /dev/null
+++ b/tests/types/types/family_secret_manager/00-base.yml
@@ -0,0 +1,13 @@
+---
+version: 1.1
+
+family_secret: # Family with secret
+
+ a_variable: my_value # A variable
+
+ secret:
+ description: the secret
+ type: secret
+ secret_manager:
+ project:
+ variable: _.a_variable
diff --git a/tests/types/types/secret_manager/00-base.yml b/tests/types/types/secret_manager/00-base.yml
new file mode 100644
index 000000000..f50d8dafc
--- /dev/null
+++ b/tests/types/types/secret_manager/00-base.yml
@@ -0,0 +1,8 @@
+---
+version: 1.1
+
+secret:
+ description: the secret
+ type: secret
+ secret_manager:
+ project: test