diff --git a/doc/check/README.md b/doc/check/README.md
index 6dd671bd..5127691d 100644
--- a/doc/check/README.md
+++ b/doc/check/README.md
@@ -1,4 +1,5 @@
# Les vérifications des valeurs
- [Fonction de vérification](function.md)
+ - [Les variables à choix](valid_enum.md)
- [Réfinition](redefine.md)
diff --git a/doc/check/valid_enum.md b/doc/check/valid_enum.md
new file mode 100644
index 00000000..64cf29c7
--- /dev/null
+++ b/doc/check/valid_enum.md
@@ -0,0 +1,46 @@
+# Les variables à choix
+
+Une variable à choix est d'abord une variable avec une [fonction check](function.md).
+
+## Les variables à choix simple
+
+Il est possible d'imposer une liste de valeur pour une variable particulière :
+
+```
+
+ yes
+ no
+ maybe
+ my_variable
+
+```
+
+Dans ce cas, seule les valeurs proposés sont possible pour cette variable.
+
+Par défaut, cette variable est obligatoire. Cela signifie qu'il n'est pas possible de spécifier "None" à cette variable.
+
+## Les variables à choix avec valeur None
+
+Il y a deux possibilités pour avoir une valeur "None" dans les choix :
+
+- rendre la variable non obligatoire, cela va ajouter un choix "None" dans la liste :
+
+```
+
+```
+
+Ou en ajoutant le paramètre "None" :
+
+```
+
+ yes
+ no
+
+ maybe
+ my_variable
+
+```
+
+## La valeur par défaut
+
+Si aucune valeur n'est spécifié pour la variable, automatiquement le premier choix va est placé comme valeur par défaut.
diff --git a/doc/variable/simple.md b/doc/variable/simple.md
index aaea1045..60792e0b 100644
--- a/doc/variable/simple.md
+++ b/doc/variable/simple.md
@@ -113,6 +113,9 @@ Les variables booléans sont par défaut obligatoire. Pour qu'une variable bool
```
+Les variables avec une valeur par défaut (non calculée) sont également automatiquement obligatoire.
+[Les variables à choix](../check/valid_enum.md) sans choix "None" sont également automatiquement obligatoire.
+
## Valeur par défaut d'une variable
Il est possible de fixer les valeurs par défaut d'une variable :
diff --git a/src/rougail/annotator/check.py b/src/rougail/annotator/check.py
index 00915f04..a902efcf 100644
--- a/src/rougail/annotator/check.py
+++ b/src/rougail/annotator/check.py
@@ -110,7 +110,7 @@ class CheckAnnotator(TargetAnnotator, ParamAnnotator):
# check value
self.check_valid_enum_value(target.name, values)
else:
- # no value, set the first choice has default value
+ # no value, set the first choice as default value
new_value = self.objectspace.value(check.xmlfiles)
new_value.name = values[0]
new_value.type = variable_type
@@ -124,8 +124,6 @@ class CheckAnnotator(TargetAnnotator, ParamAnnotator):
variable,
check,
) -> List[Any]:
- # value for choice's variable is mandatory
- variable.mandatory = True
# build choice
variable.values = []
variable.ori_type = variable.type
@@ -133,6 +131,7 @@ class CheckAnnotator(TargetAnnotator, ParamAnnotator):
has_variable = False
values = []
+ has_nil = False
for param in check.param:
if has_variable:
msg = _(f'only one "variable" parameter is allowed for valid_enum '
@@ -150,15 +149,22 @@ class CheckAnnotator(TargetAnnotator, ParamAnnotator):
f'of variable "{variable.name}"')
raise DictConsistencyError(msg, 6, param.xmlfiles)
param_type = 'calculation'
+ elif param.type == 'nil':
+ has_nil = True
values.append(param.text)
choice = self.objectspace.choice(variable.xmlfiles)
choice.name = param.text
choice.type = param_type
variable.values.append(choice)
-
+ if 'mandatory' not in vars(variable):
+ variable.mandatory = not has_nil
+ elif variable.mandatory is False:
+ choice = self.objectspace.choice(variable.xmlfiles)
+ choice.name = None
+ choice.type = 'nil'
+ variable.values.append(choice)
if has_variable:
return None
-
for target in check.target:
self.objectspace.valid_enums[target.name.path] = {'type': variable.ori_type,
'values': values,
diff --git a/tests/dictionaries/10valid_enum_base_no_mandatory/00-base.xml b/tests/dictionaries/10valid_enum_base_no_mandatory/00-base.xml
new file mode 100644
index 00000000..275d9f18
--- /dev/null
+++ b/tests/dictionaries/10valid_enum_base_no_mandatory/00-base.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+ non
+
+
+
+
+ c
+
+
+
+
+
+
+ a
+ b
+ c
+ enumvar
+
+
+
+
diff --git a/tests/dictionaries/10valid_enum_base_no_mandatory/__init__.py b/tests/dictionaries/10valid_enum_base_no_mandatory/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/10valid_enum_base_no_mandatory/makedict/base.json b/tests/dictionaries/10valid_enum_base_no_mandatory/makedict/base.json
new file mode 100644
index 00000000..58c810c5
--- /dev/null
+++ b/tests/dictionaries/10valid_enum_base_no_mandatory/makedict/base.json
@@ -0,0 +1,4 @@
+{
+ "rougail.general.mode_conteneur_actif": "non",
+ "rougail.enumfam.enumvar": "c"
+}
diff --git a/tests/dictionaries/10valid_enum_base_no_mandatory/tiramisu/base.py b/tests/dictionaries/10valid_enum_base_no_mandatory/tiramisu/base.py
new file mode 100644
index 00000000..042e251e
--- /dev/null
+++ b/tests/dictionaries/10valid_enum_base_no_mandatory/tiramisu/base.py
@@ -0,0 +1,19 @@
+from importlib.machinery import SourceFileLoader
+from importlib.util import spec_from_loader, module_from_spec
+loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
+spec = spec_from_loader(loader.name, loader)
+func = module_from_spec(spec)
+loader.exec_module(func)
+for key, value in dict(locals()).items():
+ if key != ['SourceFileLoader', 'func']:
+ setattr(func, key, value)
+try:
+ from tiramisu3 import *
+except:
+ from tiramisu import *
+option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "mandatory"}))
+option_2 = OptionDescription(name="general", doc="general", children=[option_3], properties=frozenset({"expert"}))
+option_5 = ChoiceOption(name="enumvar", doc="enumvar", values=('a', 'b', 'c', None), default="c", properties=frozenset({"expert"}))
+option_4 = OptionDescription(name="enumfam", doc="enumfam", children=[option_5], properties=frozenset({"expert"}))
+option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_4])
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1])
diff --git a/tests/dictionaries/10valid_enum_none/00-base.xml b/tests/dictionaries/10valid_enum_none/00-base.xml
index 28e599f5..289af701 100644
--- a/tests/dictionaries/10valid_enum_none/00-base.xml
+++ b/tests/dictionaries/10valid_enum_none/00-base.xml
@@ -7,7 +7,7 @@
-
+
b
@@ -17,7 +17,6 @@
a
b
-
enumvar
diff --git a/tests/dictionaries/10valid_enum_none/tiramisu/base.py b/tests/dictionaries/10valid_enum_none/tiramisu/base.py
index 6fcb84e5..1625920d 100644
--- a/tests/dictionaries/10valid_enum_none/tiramisu/base.py
+++ b/tests/dictionaries/10valid_enum_none/tiramisu/base.py
@@ -13,7 +13,7 @@ except:
from tiramisu import *
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "mandatory"}))
option_2 = OptionDescription(name="general", doc="general", children=[option_3], properties=frozenset({"expert"}))
-option_5 = ChoiceOption(name="enumvar", doc="multi", values=('a', 'b', None, ''), default="b", properties=frozenset({"expert", "mandatory"}))
+option_5 = ChoiceOption(name="enumvar", doc="multi", values=('a', 'b', '', None), default="b", properties=frozenset({"expert"}))
option_5.impl_set_information('help', "bla bla bla")
option_4 = OptionDescription(name="enumfam", doc="enumfam", children=[option_5], properties=frozenset({"expert"}))
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_4])
diff --git a/tests/dictionaries/10valid_enum_param_empty/tiramisu/base.py b/tests/dictionaries/10valid_enum_param_empty/tiramisu/base.py
index 7e75cbdf..782b6a33 100644
--- a/tests/dictionaries/10valid_enum_param_empty/tiramisu/base.py
+++ b/tests/dictionaries/10valid_enum_param_empty/tiramisu/base.py
@@ -13,7 +13,7 @@ except:
from tiramisu import *
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "mandatory"}))
option_2 = OptionDescription(name="general", doc="general", children=[option_3], properties=frozenset({"expert"}))
-option_5 = ChoiceOption(name="enumvar", doc="multi", values=(None,), properties=frozenset({"expert", "mandatory"}))
+option_5 = ChoiceOption(name="enumvar", doc="multi", values=(None,), properties=frozenset({"expert"}))
option_5.impl_set_information('help', "bla bla bla")
option_4 = OptionDescription(name="enumfam", doc="enumfam", children=[option_5], properties=frozenset({"expert"}))
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_4])
diff --git a/tests/dictionaries/10valid_enum_param_empty2/tiramisu/base.py b/tests/dictionaries/10valid_enum_param_empty2/tiramisu/base.py
index 7e75cbdf..782b6a33 100644
--- a/tests/dictionaries/10valid_enum_param_empty2/tiramisu/base.py
+++ b/tests/dictionaries/10valid_enum_param_empty2/tiramisu/base.py
@@ -13,7 +13,7 @@ except:
from tiramisu import *
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "mandatory"}))
option_2 = OptionDescription(name="general", doc="general", children=[option_3], properties=frozenset({"expert"}))
-option_5 = ChoiceOption(name="enumvar", doc="multi", values=(None,), properties=frozenset({"expert", "mandatory"}))
+option_5 = ChoiceOption(name="enumvar", doc="multi", values=(None,), properties=frozenset({"expert"}))
option_5.impl_set_information('help', "bla bla bla")
option_4 = OptionDescription(name="enumfam", doc="enumfam", children=[option_5], properties=frozenset({"expert"}))
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_4])