diff --git a/src/rougail/object_model.py b/src/rougail/object_model.py index 5c6ab31c1..493f4064a 100644 --- a/src/rougail/object_model.py +++ b/src/rougail/object_model.py @@ -132,6 +132,7 @@ class VariableParam(Param): type: str variable: str propertyerror: bool = True + whole: bool = False optional: bool = False diff --git a/src/rougail/tiramisu.py b/src/rougail/tiramisu.py index cfcd3e175..40ea9c794 100644 --- a/src/rougail/tiramisu.py +++ b/src/rougail/tiramisu.py @@ -41,10 +41,9 @@ from .utils import normalize_family global func -func = {} dict_env = {} ENV = SandboxedEnvironment(loader=DictLoader(dict_env), undefined=StrictUndefined) -ENV.filters = func +func = ENV.filters ENV.compile_templates('jinja_caches', zip=None) diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py index c2d51bda9..20e91a38d 100644 --- a/src/rougail/tiramisureflector.py +++ b/src/rougail/tiramisureflector.py @@ -332,6 +332,7 @@ class Common: param.get("propertyerror", True), param.get("suffix"), param.get("dynamic"), + param.get('whole', False), ) if param["type"] == "any": if isinstance(param["value"], str): @@ -343,15 +344,19 @@ class Common: def build_option_param( self, - param, + variable, propertyerror, suffix: Optional[str], dynamic, + whole: bool, ) -> str: """build variable parameters""" - if param.path == self.elt.path: - return "ParamSelfOption(whole=False)" - option_name = self.tiramisu.reflector_objects[param.path].get( + if variable.path == self.elt.path: + return f"ParamSelfOption(whole={whole})" + if whole: + msg = f'variable param "{variable.path}" has whole attribute but it\'s not allowed for external variable' + raise DictConsistencyError(msg, 34, self.elt.xmlfiles) + option_name = self.tiramisu.reflector_objects[variable.path].get( self.calls, self.elt.path ) params = [f"{option_name}"] diff --git a/tests/dictionaries/04_5validators_multi/__init__.py b/tests/dictionaries/04_5validators_multi/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/04_5validators_multi/dictionaries/rougail/00-base.yml b/tests/dictionaries/04_5validators_multi/dictionaries/rougail/00-base.yml new file mode 100644 index 000000000..81714725f --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/dictionaries/rougail/00-base.yml @@ -0,0 +1,15 @@ +--- +version: 1.1 +var1: + description: a second variable + multi: true + default: + - 'no' + - 'yes' + validators: + - type: jinja + jinja: | + {% if _.var1 | length > 9 %} + length must be less than 10 + {% endif %} + description: check length is less than 10 diff --git a/tests/dictionaries/04_5validators_multi/makedict/after.json b/tests/dictionaries/04_5validators_multi/makedict/after.json new file mode 100644 index 000000000..45a7b8795 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/makedict/after.json @@ -0,0 +1,9 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [ + "no", + "yes" + ] + } +} diff --git a/tests/dictionaries/04_5validators_multi/makedict/base.json b/tests/dictionaries/04_5validators_multi/makedict/base.json new file mode 100644 index 000000000..8a8a50173 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/makedict/base.json @@ -0,0 +1,6 @@ +{ + "rougail.var1": [ + "no", + "yes" + ] +} diff --git a/tests/dictionaries/04_5validators_multi/makedict/before.json b/tests/dictionaries/04_5validators_multi/makedict/before.json new file mode 100644 index 000000000..45a7b8795 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/makedict/before.json @@ -0,0 +1,9 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [ + "no", + "yes" + ] + } +} diff --git a/tests/dictionaries/04_5validators_multi/makedict/mandatory.json b/tests/dictionaries/04_5validators_multi/makedict/mandatory.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/makedict/mandatory.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/dictionaries/04_5validators_multi/tiramisu/base.py b/tests/dictionaries/04_5validators_multi/tiramisu/base.py new file mode 100644 index 000000000..960cd949b --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/tiramisu/base.py @@ -0,0 +1,11 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_rougail.var1'] = "{% if _.var1 | length > 9 %}\nlength must be less than 10\n{% endif %}\n" +option_2 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '_.var1': ParamSelfOption(whole=False)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", children=[option_2], properties=frozenset({"standard"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/04_5validators_multi/tiramisu/multi.py b/tests/dictionaries/04_5validators_multi/tiramisu/multi.py new file mode 100644 index 000000000..fde8be7ff --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/tiramisu/multi.py @@ -0,0 +1,16 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_1.rougail.var1'] = "{% if _.var1 | length > 9 %}\nlength must be less than 10\n{% endif %}\n" +dict_env['validators_2.rougail.var1'] = "{% if _.var1 | length > 9 %}\nlength must be less than 10\n{% endif %}\n" +option_3 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_1.rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '_.var1': ParamSelfOption(whole=False)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", children=[option_3], properties=frozenset({"standard"})) +optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"})) +option_6 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_2.rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '_.var1': ParamSelfOption(whole=False)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", children=[option_6], properties=frozenset({"standard"})) +optiondescription_4 = OptionDescription(name="2", doc="2", children=[optiondescription_5], properties=frozenset({"standard"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_4]) diff --git a/tests/dictionaries/04_5validators_multi/tiramisu/no_namespace.py b/tests/dictionaries/04_5validators_multi/tiramisu/no_namespace.py new file mode 100644 index 000000000..5d732ead8 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi/tiramisu/no_namespace.py @@ -0,0 +1,10 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_var1'] = "{% if _.var1 | length > 9 %}\nlength must be less than 10\n{% endif %}\n" +option_1 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), '_': ParamValue({}), '_.var1': ParamSelfOption(whole=False)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) diff --git a/tests/dictionaries/04_5validators_multi2/__init__.py b/tests/dictionaries/04_5validators_multi2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/04_5validators_multi2/dictionaries/rougail/00-base.yml b/tests/dictionaries/04_5validators_multi2/dictionaries/rougail/00-base.yml new file mode 100644 index 000000000..20178d7d4 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/dictionaries/rougail/00-base.yml @@ -0,0 +1,20 @@ +--- +version: 1.1 +var1: + description: a second variable + multi: true + default: + - 'no' + - 'yes' + validators: + - type: jinja + params: + values: + type: variable + variable: _.var1 + whole: true + jinja: | + {% if values | length > 2 %} + length must be less than 3 + {% endif %} + description: check length is less than 3 diff --git a/tests/dictionaries/04_5validators_multi2/makedict/after.json b/tests/dictionaries/04_5validators_multi2/makedict/after.json new file mode 100644 index 000000000..45a7b8795 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/makedict/after.json @@ -0,0 +1,9 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [ + "no", + "yes" + ] + } +} diff --git a/tests/dictionaries/04_5validators_multi2/makedict/base.json b/tests/dictionaries/04_5validators_multi2/makedict/base.json new file mode 100644 index 000000000..8a8a50173 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/makedict/base.json @@ -0,0 +1,6 @@ +{ + "rougail.var1": [ + "no", + "yes" + ] +} diff --git a/tests/dictionaries/04_5validators_multi2/makedict/before.json b/tests/dictionaries/04_5validators_multi2/makedict/before.json new file mode 100644 index 000000000..45a7b8795 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/makedict/before.json @@ -0,0 +1,9 @@ +{ + "rougail.var1": { + "owner": "default", + "value": [ + "no", + "yes" + ] + } +} diff --git a/tests/dictionaries/04_5validators_multi2/makedict/mandatory.json b/tests/dictionaries/04_5validators_multi2/makedict/mandatory.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/makedict/mandatory.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/dictionaries/04_5validators_multi2/tiramisu/base.py b/tests/dictionaries/04_5validators_multi2/tiramisu/base.py new file mode 100644 index 000000000..39f2cf95a --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/tiramisu/base.py @@ -0,0 +1,11 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_rougail.var1'] = "{% if values | length > 2 %}\nlength must be less than 3\n{% endif %}\n" +option_2 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), 'values': ParamSelfOption(whole=True)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", children=[option_2], properties=frozenset({"standard"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries/04_5validators_multi2/tiramisu/multi.py b/tests/dictionaries/04_5validators_multi2/tiramisu/multi.py new file mode 100644 index 000000000..d00a58292 --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/tiramisu/multi.py @@ -0,0 +1,16 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_1.rougail.var1'] = "{% if values | length > 2 %}\nlength must be less than 3\n{% endif %}\n" +dict_env['validators_2.rougail.var1'] = "{% if values | length > 2 %}\nlength must be less than 3\n{% endif %}\n" +option_3 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_1.rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), 'values': ParamSelfOption(whole=True)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", children=[option_3], properties=frozenset({"standard"})) +optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"})) +option_6 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_2.rougail.var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), 'values': ParamSelfOption(whole=True)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", children=[option_6], properties=frozenset({"standard"})) +optiondescription_4 = OptionDescription(name="2", doc="2", children=[optiondescription_5], properties=frozenset({"standard"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_4]) diff --git a/tests/dictionaries/04_5validators_multi2/tiramisu/no_namespace.py b/tests/dictionaries/04_5validators_multi2/tiramisu/no_namespace.py new file mode 100644 index 000000000..105c5ac2b --- /dev/null +++ b/tests/dictionaries/04_5validators_multi2/tiramisu/no_namespace.py @@ -0,0 +1,10 @@ +from tiramisu import * +from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription +load_functions('tests/dictionaries/../eosfunc/test.py') +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("standard") +ALLOWED_LEADER_PROPERTIES.add("advanced") +dict_env['validators_var1'] = "{% if values | length > 2 %}\nlength must be less than 3\n{% endif %}\n" +option_1 = StrOption(name="var1", doc="a second variable", multi=True, default=["no", "yes"], default_multi="no", validators=[Calculation(func['valid_with_jinja'], Params((), kwargs={'__internal_jinja': ParamValue("validators_var1"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(False), 'values': ParamSelfOption(whole=True)}))], properties=frozenset({"mandatory", "notempty", "standard"}), informations={'type': 'string'}) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) diff --git a/tests/test_1_flattener.py b/tests/test_1_flattener.py index 97cca2382..2edb961f9 100644 --- a/tests/test_1_flattener.py +++ b/tests/test_1_flattener.py @@ -180,7 +180,7 @@ def test_error_dictionary(test_dir_error): errno = [] rougailconfig = RougailConfig.copy() rougailconfig['main_namespace'] = 'Rougail' - eolobj = load_rougail_object(test_dir_, rougailconfig) + eolobj = load_rougail_object(test_dir_, rougailconfig, namespace=True) if eolobj is None: return for i in listdir(test_dir_):