Compare commits

..

37 commits

Author SHA1 Message Date
d35fe16cd9 bump: version 1.2.0a10 → 1.2.0a11 2025-02-17 15:45:33 +01:00
04aa9444a3 fix: add get remove properties 2025-02-17 15:45:27 +01:00
9c7fb1d505 bump: version 1.2.0a9 → 1.2.0a10 2025-02-17 09:21:02 +01:00
70003fcbc5 fix: we can define structural plugin when generate documentation 2025-02-17 09:20:38 +01:00
85f3b9f80f fix: if a variable in user_data not existe, it's no a warnings 2025-02-17 09:19:31 +01:00
b0687fdcc6 bump: version 1.2.0a8 → 1.2.0a9 2025-02-10 10:32:57 +01:00
cc5aaf6393 feat: can change defaut params for an option 2025-02-10 10:32:48 +01:00
df2fcb467f fix: if no description, generate negative_description too 2025-02-10 10:09:34 +01:00
7b9d7ce419 fix: error messages 2025-02-07 08:08:55 +01:00
63f76dc68f bump: version 1.2.0a7 → 1.2.0a8 2025-01-04 12:01:17 +01:00
e7e9687b8d fix: better support of not_for_commandline feature 2025-01-04 12:01:08 +01:00
0fea822c91 bump: version 1.2.0a6 → 1.2.0a7 2025-01-02 22:01:56 +01:00
ea6baa3dc2 fix: add structural_directory 2025-01-02 22:01:38 +01:00
7d830d5e40 bump: version 1.2.0a5 → 1.2.0a6 2025-01-02 21:19:40 +01:00
81d86e7b6f fix: add path.py 2025-01-02 21:19:16 +01:00
7a5a1b42e8 bump: version 1.2.0a4 → 1.2.0a5 2025-01-02 21:06:47 +01:00
3849c42cba feat: upgrade is not in formatter 2025-01-02 21:06:13 +01:00
6c1df5578f feat: remove prefix 2025-01-02 21:02:44 +01:00
dfd31c4fb4 bump: version 1.2.0a3 → 1.2.0a4 2024-12-11 21:00:22 +01:00
45959ac18b fix: remove link 2024-12-11 20:58:08 +01:00
9e8c6f96c5 feat: move test to a new project rougail-tests 2024-12-11 20:54:54 +01:00
00e0941f6e fix: reorganise user_datas 2024-12-11 20:54:03 +01:00
8afb787c98 fix: only change prefix if path is relative 2024-12-11 20:51:08 +01:00
a91a4d6a55 feat: output could have annotator 2024-12-11 20:50:15 +01:00
688aa8d053 bump: version 1.2.0a2 → 1.2.0a3 2024-11-28 08:31:00 +01:00
4c613f6425 fix: add user_datas file 2024-11-28 08:30:47 +01:00
145b7be0a5 bump: version 1.2.0a1 → 1.2.0a2 2024-11-27 16:09:18 +01:00
829d7692ad fix: separate UserDatas 2024-11-27 16:09:04 +01:00
ea34751e08 fix: options could be a list 2024-11-27 10:22:00 +01:00
c25a66f0cb feat: add "exists" attribut for a family 2024-11-27 10:14:42 +01:00
fdfb7ec73b bump: version 1.2.0a0 → 1.2.0a1 2024-11-25 09:18:04 +01:00
db768f94af fix: dynamic variable could be optional 2024-11-25 09:17:27 +01:00
9782bcde95 fix: dynamic variable declare in verion 1.0 has {{ suffix }} 2024-11-25 09:16:48 +01:00
fbb1446fa3 fix: user_data plugins could have annotator function 2024-11-25 09:14:58 +01:00
56659f7ea4 fix: do not modify a dynamic variable if has default value 2024-11-25 09:10:44 +01:00
af3f77c920 bump: version 1.1.1 → 1.2.0a0 2024-11-08 08:13:27 +01:00
e29c0c8abc feat: add force_optional option to allow charging structure even if all variables are not available 2024-11-08 08:12:33 +01:00
1032 changed files with 4969 additions and 10056 deletions

View file

@ -1,3 +1,97 @@
## 1.2.0a11 (2025-02-17)
### Fix
- add get remove properties
## 1.2.0a10 (2025-02-17)
### Fix
- we can define structural plugin when generate documentation
- if a variable in user_data not existe, it's no a warnings
## 1.2.0a9 (2025-02-10)
### Feat
- can change defaut params for an option
### Fix
- if no description, generate negative_description too
- error messages
## 1.2.0a8 (2025-01-04)
### Fix
- better support of not_for_commandline feature
## 1.2.0a7 (2025-01-02)
### Fix
- add structural_directory
## 1.2.0a6 (2025-01-02)
### Fix
- add path.py
## 1.2.0a5 (2025-01-02)
### Feat
- upgrade is not in formatter
- remove prefix
## 1.2.0a4 (2024-12-11)
### Feat
- move test to a new project rougail-tests
- output could have annotator
### Fix
- remove link
- reorganise user_datas
- only change prefix if path is relative
## 1.2.0a3 (2024-11-28)
### Fix
- add user_datas file
## 1.2.0a2 (2024-11-27)
### Feat
- add "exists" attribut for a family
### Fix
- separate UserDatas
- options could be a list
## 1.2.0a1 (2024-11-25)
### Fix
- dynamic variable could be optional
- dynamic variable declare in verion 1.0 has {{ suffix }}
- user_data plugins could have annotator function
- do not modify a dynamic variable if has default value
## 1.2.0a0 (2024-11-08)
### Feat
- add force_optional option to allow charging structure even if all variables are not available
## 1.1.1 (2024-11-06) ## 1.1.1 (2024-11-06)
### Fix ### Fix

View file

@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"POT-Creation-Date: 2024-10-30 13:21+0100\n" "POT-Creation-Date: 2025-02-17 09:16+0100\n"
"PO-Revision-Date: 2024-10-30 13:39+0100\n" "PO-Revision-Date: 2025-02-17 09:17+0100\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: fr\n" "Language: fr\n"
@ -16,39 +16,39 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.5\n" "X-Generator: Poedit 3.5\n"
#: src/rougail/annotator/family.py:142 #: src/rougail/annotator/family.py:147
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}" msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr "" msgstr ""
"le mode d'une variable par défaut \"{0}\" n'est pas un mode valide, les " "le mode d'une variable par défaut \"{0}\" n'est pas un mode valide, les "
"modes valides sont {1}" "modes valides sont {1}"
#: src/rougail/annotator/family.py:148 #: src/rougail/annotator/family.py:153
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}" msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr "" msgstr ""
"le mode d'une famille par défaut \"{0}\" n'est pas un mode valide, les modes " "le mode d'une famille par défaut \"{0}\" n'est pas un mode valide, les modes "
"valides sont {1}" "valides sont {1}"
#: src/rougail/annotator/family.py:180 #: src/rougail/annotator/family.py:185
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}" msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr "" msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, les modes valides " "le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, les modes valides "
"sont {2}" "sont {2}"
#: src/rougail/annotator/family.py:184 #: src/rougail/annotator/family.py:189
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available" msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr "" msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, aucun mode ne sont " "le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, aucun mode ne sont "
"définis" "définis"
#: src/rougail/annotator/family.py:248 #: src/rougail/annotator/family.py:253
msgid "" msgid ""
"the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the " "the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the "
"higher family mode \"{2}\"" "higher family mode \"{2}\""
msgstr "" msgstr ""
"la variable \"{0}\" est obligatoire donc dans le mode \"{1}\" mais la " "la variable \"{0}\" est obligatoire, donc en mode \"{1}\", mais la famille a "
"famille a un mode supérieur \"{2}\"" "un mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:286 #: src/rougail/annotator/family.py:291
msgid "" msgid ""
"the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode " "the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode "
"\"{2}\"" "\"{2}\""
@ -56,7 +56,7 @@ msgstr ""
"la variable suiveuse \"{0}\" a le mode \"{1}\" mais la variable leader a un " "la variable suiveuse \"{0}\" a le mode \"{1}\" mais la variable leader a un "
"mode supérieur \"{2}\"" "mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:319 #: src/rougail/annotator/family.py:324
msgid "" msgid ""
"the family \"{0}\" is in \"{1}\" mode but variables and families inside have " "the family \"{0}\" is in \"{1}\" mode but variables and families inside have "
"the higher modes \"{2}\"" "the higher modes \"{2}\""
@ -64,7 +64,7 @@ msgstr ""
"la famille \"{0}\" a le mode \"{1}\" mais les variables et les familles à " "la famille \"{0}\" a le mode \"{1}\" mais les variables et les familles à "
"l'intérieur ont des modes supérieurs \"{2}\"" "l'intérieur ont des modes supérieurs \"{2}\""
#: src/rougail/annotator/family.py:337 #: src/rougail/annotator/family.py:342
msgid "" msgid ""
"the variable \"{0}\" is in \"{1}\" mode but family has the higher family " "the variable \"{0}\" is in \"{1}\" mode but family has the higher family "
"mode \"{2}\"" "mode \"{2}\""
@ -72,37 +72,134 @@ msgstr ""
"la variable \"{0}\" est dans le mode \"{1}\" mais la famille a le mode " "la variable \"{0}\" est dans le mode \"{1}\" mais la famille a le mode "
"supérieur \"{2}\"" "supérieur \"{2}\""
#: src/rougail/annotator/value.py:80 #: src/rougail/annotator/value.py:77
msgid "the follower \"{0}\" without multi attribute can only have one value" msgid "the follower \"{0}\" without multi attribute can only have one value"
msgstr "" msgstr ""
"la variable suiveuse \"{0}\" sans l'attribut multi peut avoir seulement une " "la variable suiveuse \"{0}\" sans l'attribut multi peut avoir seulement une "
"valeur" "valeur"
#: src/rougail/annotator/value.py:96 #: src/rougail/annotator/value.py:93
msgid "the variable \"{0}\" is multi but has a non list default value" msgid "the variable \"{0}\" is multi but has a non list default value"
msgstr "" msgstr ""
"la variable \"{0}\" est multiple mais a une valeur par défaut sans être une " "la variable \"{0}\" est multiple mais a une valeur par défaut sans être une "
"liste" "liste"
#: src/rougail/annotator/variable.py:192 #: src/rougail/annotator/variable.py:175
msgid "" msgid ""
"the variable \"{0}\" has regexp attribut but has not the \"regexp\" type" "the variable \"{0}\" has regexp attribut but has not the \"regexp\" type"
msgstr "" msgstr ""
"la variable \"{0}\" a un attribut regexp mais n'a pas le type \"regexp\"" "la variable \"{0}\" a un attribut regexp mais n'a pas le type \"regexp\""
#: src/rougail/annotator/variable.py:235 #: src/rougail/annotator/variable.py:218
msgid "" msgid ""
"the variable \"{0}\" has choices attribut but has not the \"choice\" type" "the variable \"{0}\" has choices attribut but has not the \"choice\" type"
msgstr "" msgstr ""
"la variable \"{0}\" a un attribut choices mais n'a pas le type \"choice\"" "la variable \"{0}\" a un attribut choices mais n'a pas le type \"choice\""
#: src/rougail/annotator/variable.py:263 #: src/rougail/annotator/variable.py:246
msgid "" msgid ""
"the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}" "the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}"
msgstr "" msgstr ""
"la variable \"{0}\" a la valeur par défaut invalide \"{1}\" devrait être {2}" "la variable \"{0}\" a la valeur par défaut invalide \"{1}\" devrait être {2}"
#: src/rougail/convert.py:268 #: src/rougail/config.py:231
msgid "File with functions"
msgstr "Fichier avec les fonctions"
#: src/rougail/config.py:243
msgid "All modes level available"
msgstr "Tous les niveaux de modes valides"
#: src/rougail/config.py:255
msgid "Default mode for a family"
msgstr "Mode par défaut pour une famille"
#: src/rougail/config.py:275
msgid "Default mode for a variable"
msgstr "Mode par défaut pour une variable"
#: src/rougail/config.py:299
msgid "Option name for the base option"
msgstr "Nom de l'option pour l'option de base"
#: src/rougail/config.py:304
msgid "In cache file, do not importation of Tiramisu and other dependencies"
msgstr ""
"Dans le fichier de cache, ne pas importer Tiramisu et autres dépendances"
#: src/rougail/config.py:305
msgid "In cache file, do importation of Tiramisu and other dependencies"
msgstr "Dans le fichier de cache, importer Tiramisu et autres dépendances"
#: src/rougail/config.py:310
msgid "Tiramisu cache filename"
msgstr "Nom du fichier du cache Tiramisu"
#: src/rougail/config.py:318
msgid "Name of internal functions that we can use as a function"
msgstr ""
"Nom des fonctions internes qu'il est possible d'utiliser comme fonction"
#: src/rougail/config.py:324
msgid "Name of extra annotators"
msgstr "Nom des annotators supplémentaires"
#: src/rougail/config.py:330
msgid "Suffix add to generated options name"
msgstr "Suffix ajouté pour généré le nom des options"
#: src/rougail/config.py:336
msgid "Every variables in calculation are optionals"
msgstr "Toutes les variables dans un calcul sont optionnelles"
#: src/rougail/config.py:337
msgid "Variables in calculation are not optional by default"
msgstr "Les variables dans un calcul sont optionnelles par défaut"
#: src/rougail/config.py:341 src/rougail/config.py:342
msgid "Loads redefine variables even if there don't already exists"
msgstr "Charger les variables redéfinis même si elles n'existe pas"
#: src/rougail/config.py:443
msgid "Default parameters for option type"
msgstr "Paramètre par défaut pour le type d'option"
#: src/rougail/convert.py:270
msgid "unknown type {0} for {1}"
msgstr "type {0} inconnu pour {1}"
#: src/rougail/convert.py:402
msgid "family \"{0}\" define multiple time"
msgstr "la famille \"{0}\" est définit plusieurs fois"
#: src/rougail/convert.py:658
msgid "variable \"{0}\" define multiple time"
msgstr "la variable \"{0}\" est définit plusieurs fois"
#: src/rougail/convert.py:761
msgid "params must be a dict for {0}"
msgstr "params doit être une dict pour {0}"
#: src/rougail/convert.py:782
msgid "\"{0}\" has an invalid \"params\" for {1}: {2}"
msgstr "\"{0}\" a un attribut \"params\" invalide pour {1}: {2}"
#: src/rougail/convert.py:1096
msgid "Cannot execute annotate multiple time"
msgstr "Ne peut exécuter l'annotation plusieurs fois"
#: src/rougail/convert.py:1103
msgid ""
"invalid \"structural\" definition ({0}), we cannot load any structural file!"
msgstr ""
"définition invalide pour la définition des \"structures\" ({0}), aucun "
"fichier de structure ne peut être chargé !"
#: src/rougail/error.py:67
msgid "{0} in {1}"
msgstr "{0} dans {1}"
#: src/rougail/path.py:209
msgid "" msgid ""
"A variable or a family located in the \"{0}\" namespace shall not be used in " "A variable or a family located in the \"{0}\" namespace shall not be used in "
"the \"{1}\" namespace" "the \"{1}\" namespace"
@ -110,38 +207,22 @@ msgstr ""
"Une variable ou une famille localisé dans l'espace de nom \"{0}\" ne devrait " "Une variable ou une famille localisé dans l'espace de nom \"{0}\" ne devrait "
"pas être utilisé dans l'espace de nom \"{1}\"" "pas être utilisé dans l'espace de nom \"{1}\""
#: src/rougail/convert.py:462 #: src/rougail/structural_commandline/annotator.py:67
msgid "unknown type {0} for {1}"
msgstr "type {0} inconnu pour {1}"
#: src/rougail/convert.py:1323
msgid "duplicate dictionary file name {0}"
msgstr "nom de fichier {0} de dictionnaire dupliqué"
#: src/rougail/convert.py:1370
msgid "Cannot execute annotate multiple time"
msgstr "Ne peut exécuter l'annotation plusieurs fois"
#: src/rougail/error.py:70
msgid "{0} in {1}"
msgstr "{0} dans {1}"
#: src/rougail/structural_commandline/annotator.py:70
msgid "alternative_name \"{0}\" conflict with \"--help\"" msgid "alternative_name \"{0}\" conflict with \"--help\""
msgstr "alternative_name \"{0}\" est en conflit avec \"--help\"" msgstr "alternative_name \"{0}\" est en conflit avec \"--help\""
#: src/rougail/structural_commandline/annotator.py:73 #: src/rougail/structural_commandline/annotator.py:72
msgid "conflict alternative_name \"{0}\": \"{1}\" and \"{2}\"" msgid "conflict alternative_name \"{0}\": \"{1}\" and \"{2}\""
msgstr "conflit dans les \"alternative_name\" \"{0}\": \"{1}\" et \"{2}\"" msgstr "conflit dans les \"alternative_name\" \"{0}\": \"{1}\" et \"{2}\""
#: src/rougail/structural_commandline/annotator.py:96 #: src/rougail/structural_commandline/annotator.py:98
msgid "" msgid ""
"negative_description is mandatory for boolean variable, but \"{0}\" hasn't" "negative_description is mandatory for boolean variable, but \"{0}\" hasn't"
msgstr "" msgstr ""
"l'attribut negative_description est obligatoire pour des variables " "l'attribut negative_description est obligatoire pour des variables "
"\"boolean\", mais \"{0}\" n'en a pas" "\"boolean\", mais \"{0}\" n'en a pas"
#: src/rougail/structural_commandline/annotator.py:105 #: src/rougail/structural_commandline/annotator.py:106
msgid "" msgid ""
"negative_description is only available for boolean variable, but \"{0}\" is " "negative_description is only available for boolean variable, but \"{0}\" is "
"\"{1}\"" "\"{1}\""
@ -149,11 +230,51 @@ msgstr ""
"l'attribut negative_description est seulement valide pour des variables " "l'attribut negative_description est seulement valide pour des variables "
"\"boolean\", mais \"{0}\" est \"{1}\"" "\"boolean\", mais \"{0}\" est \"{1}\""
#: src/rougail/update/update.py:741 #: src/rougail/structural_directory/__init__.py:127
msgid "not a XML file: {0}" msgid "duplicate dictionary file name {0}"
msgstr "fichier XML invalid : {0}" msgstr "nom de fichier {0} de dictionnaire dupliqué"
#: src/rougail/utils.py:58 #: src/rougail/structural_directory/config.py:32
msgid "Directories where dictionary files are placed"
msgstr "Répertoires où sont placés les fichiers de structure"
#: src/rougail/structural_directory/config.py:46
msgid "Sort dictionaries from differents directories"
msgstr "Trier les fichiers de structure à partir de différents répertoires"
#: src/rougail/structural_directory/config.py:56
msgid "Main namespace name"
msgstr "Nom de l'espace de nom principal"
#: src/rougail/structural_directory/config.py:67
msgid "Extra namespaces"
msgstr "Espaces de nom supplémentaires"
#: src/rougail/structural_directory/config.py:76
msgid "Extra namespace name"
msgstr "Nom de l'espace de nom supplémentaire"
#: src/rougail/structural_directory/config.py:82
msgid "Directories where extra dictionary files are placed"
msgstr ""
"Répertoires où sont placés les fichiers de structure de l'espace de nom "
"supplémentaire"
#: src/rougail/tiramisureflector.py:376
msgid "internal error, {0} is not a dynamic variable"
msgstr "erreur interne, \"{0}\" n'est pas une variable dynamique"
#: src/rougail/user_datas.py:155
msgid "the variable \"{0}\" contains secrets and should not be defined in {1}"
msgstr ""
"la variable \"{0}\" contient des secrets et ne devrait pas être défini dans "
"{1}"
#: src/rougail/user_datas.py:215
msgid "the option \"{0}\" is an option description"
msgstr "l'option \"{0}\" est une option description"
#: src/rougail/utils.py:55
msgid "" msgid ""
"invalid variable or family name \"{0}\" must only contains lowercase ascii " "invalid variable or family name \"{0}\" must only contains lowercase ascii "
"character, number or _" "character, number or _"
@ -161,6 +282,31 @@ msgstr ""
"nom invalide pour la variable ou famille \"{0}\" doit seulement contenir des " "nom invalide pour la variable ou famille \"{0}\" doit seulement contenir des "
"caractères ascii minuscule, nombre or _" "caractères ascii minuscule, nombre or _"
#: src/rougail/utils.py:120 #: src/rougail/utils.py:113
msgid "error in jinja \"{0}\" for the variable \"{1}\": {2}" msgid "error in jinja \"{0}\" for the variable \"{1}\": {2}"
msgstr "erreur dans Jinja \"{0}\" pour la variable \"{1}\": {2}" msgstr "erreur dans Jinja \"{0}\" pour la variable \"{1}\": {2}"
#~ msgid "Update dictionaries to newest Rougail format version"
#~ msgstr ""
#~ "Mettre à jour le fichier de structure vers la dernière version du format "
#~ "de Rougail"
#~ msgid "Do not update dictionaries to newest Rougail format version"
#~ msgstr ""
#~ "Ne pas mettre à jour le fichier de structure vers la dernière version du "
#~ "format de Rougail"
#~ msgid "Update informations"
#~ msgstr "Mise à jour des informations"
#~ msgid "Directories where dictionary files will be placed"
#~ msgstr "Répertoires où sont placés les fichiers de structure"
#~ msgid "Directories where extra files will be placed"
#~ msgstr "Répertoires où sont placés les fichiers de structure supplémentaire"
#~ msgid "The family \"{0}\" already exists and it is not redefined"
#~ msgstr "La famille \"{0}\" existe déjà et n'est pas redéfinie"
#~ msgid "not a XML file: {0}"
#~ msgstr "fichier XML invalid : {0}"

View file

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-11-04 12:04+0100\n" "POT-Creation-Date: 2025-02-17 09:18+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,35 +15,35 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
#: src/rougail/annotator/family.py:139 #: src/rougail/annotator/family.py:147
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}" msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:145 #: src/rougail/annotator/family.py:153
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}" msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:177 #: src/rougail/annotator/family.py:185
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}" msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:181 #: src/rougail/annotator/family.py:189
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available" msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:245 #: src/rougail/annotator/family.py:253
msgid "the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the higher family mode \"{2}\"" msgid "the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:283 #: src/rougail/annotator/family.py:291
msgid "the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode \"{2}\"" msgid "the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode \"{2}\""
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:316 #: src/rougail/annotator/family.py:324
msgid "the family \"{0}\" is in \"{1}\" mode but variables and families inside have the higher modes \"{2}\"" msgid "the family \"{0}\" is in \"{1}\" mode but variables and families inside have the higher modes \"{2}\""
msgstr "" msgstr ""
#: src/rougail/annotator/family.py:334 #: src/rougail/annotator/family.py:342
msgid "the variable \"{0}\" is in \"{1}\" mode but family has the higher family mode \"{2}\"" msgid "the variable \"{0}\" is in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr "" msgstr ""
@ -55,38 +55,114 @@ msgstr ""
msgid "the variable \"{0}\" is multi but has a non list default value" msgid "the variable \"{0}\" is multi but has a non list default value"
msgstr "" msgstr ""
#: src/rougail/annotator/variable.py:189 #: src/rougail/annotator/variable.py:175
msgid "the variable \"{0}\" has regexp attribut but has not the \"regexp\" type" msgid "the variable \"{0}\" has regexp attribut but has not the \"regexp\" type"
msgstr "" msgstr ""
#: src/rougail/annotator/variable.py:232 #: src/rougail/annotator/variable.py:218
msgid "the variable \"{0}\" has choices attribut but has not the \"choice\" type" msgid "the variable \"{0}\" has choices attribut but has not the \"choice\" type"
msgstr "" msgstr ""
#: src/rougail/annotator/variable.py:260 #: src/rougail/annotator/variable.py:246
msgid "the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}" msgid "the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}"
msgstr "" msgstr ""
#: src/rougail/convert.py:281 #: src/rougail/config.py:231
msgid "A variable or a family located in the \"{0}\" namespace shall not be used in the \"{1}\" namespace" msgid "File with functions"
msgstr "" msgstr ""
#: src/rougail/convert.py:475 #: src/rougail/config.py:243
msgid "All modes level available"
msgstr ""
#: src/rougail/config.py:255
msgid "Default mode for a family"
msgstr ""
#: src/rougail/config.py:275
msgid "Default mode for a variable"
msgstr ""
#: src/rougail/config.py:299
msgid "Option name for the base option"
msgstr ""
#: src/rougail/config.py:304
msgid "In cache file, do not importation of Tiramisu and other dependencies"
msgstr ""
#: src/rougail/config.py:305
msgid "In cache file, do importation of Tiramisu and other dependencies"
msgstr ""
#: src/rougail/config.py:310
msgid "Tiramisu cache filename"
msgstr ""
#: src/rougail/config.py:318
msgid "Name of internal functions that we can use as a function"
msgstr ""
#: src/rougail/config.py:324
msgid "Name of extra annotators"
msgstr ""
#: src/rougail/config.py:330
msgid "Suffix add to generated options name"
msgstr ""
#: src/rougail/config.py:336
msgid "Every variables in calculation are optionals"
msgstr ""
#: src/rougail/config.py:337
msgid "Variables in calculation are not optional by default"
msgstr ""
#: src/rougail/config.py:341 src/rougail/config.py:342
msgid "Loads redefine variables even if there don't already exists"
msgstr ""
#: src/rougail/config.py:443
msgid "Default parameters for option type"
msgstr ""
#: src/rougail/convert.py:270
msgid "unknown type {0} for {1}" msgid "unknown type {0} for {1}"
msgstr "" msgstr ""
#: src/rougail/convert.py:1345 #: src/rougail/convert.py:402
msgid "duplicate dictionary file name {0}" msgid "family \"{0}\" define multiple time"
msgstr "" msgstr ""
#: src/rougail/convert.py:1392 #: src/rougail/convert.py:658
msgid "variable \"{0}\" define multiple time"
msgstr ""
#: src/rougail/convert.py:761
msgid "params must be a dict for {0}"
msgstr ""
#: src/rougail/convert.py:782
msgid "\"{0}\" has an invalid \"params\" for {1}: {2}"
msgstr ""
#: src/rougail/convert.py:1096
msgid "Cannot execute annotate multiple time" msgid "Cannot execute annotate multiple time"
msgstr "" msgstr ""
#: src/rougail/convert.py:1103
msgid "invalid \"structural\" definition ({0}), we cannot load any structural file!"
msgstr ""
#: src/rougail/error.py:67 #: src/rougail/error.py:67
msgid "{0} in {1}" msgid "{0} in {1}"
msgstr "" msgstr ""
#: src/rougail/path.py:209
msgid "A variable or a family located in the \"{0}\" namespace shall not be used in the \"{1}\" namespace"
msgstr ""
#: src/rougail/structural_commandline/annotator.py:67 #: src/rougail/structural_commandline/annotator.py:67
msgid "alternative_name \"{0}\" conflict with \"--help\"" msgid "alternative_name \"{0}\" conflict with \"--help\""
msgstr "" msgstr ""
@ -95,23 +171,59 @@ msgstr ""
msgid "conflict alternative_name \"{0}\": \"{1}\" and \"{2}\"" msgid "conflict alternative_name \"{0}\": \"{1}\" and \"{2}\""
msgstr "" msgstr ""
#: src/rougail/structural_commandline/annotator.py:95 #: src/rougail/structural_commandline/annotator.py:98
msgid "negative_description is mandatory for boolean variable, but \"{0}\" hasn't" msgid "negative_description is mandatory for boolean variable, but \"{0}\" hasn't"
msgstr "" msgstr ""
#: src/rougail/structural_commandline/annotator.py:104 #: src/rougail/structural_commandline/annotator.py:106
msgid "negative_description is only available for boolean variable, but \"{0}\" is \"{1}\"" msgid "negative_description is only available for boolean variable, but \"{0}\" is \"{1}\""
msgstr "" msgstr ""
#: src/rougail/update/update.py:738 #: src/rougail/structural_directory/__init__.py:127
msgid "not a XML file: {0}" msgid "duplicate dictionary file name {0}"
msgstr ""
#: src/rougail/structural_directory/config.py:32
msgid "Directories where dictionary files are placed"
msgstr ""
#: src/rougail/structural_directory/config.py:46
msgid "Sort dictionaries from differents directories"
msgstr ""
#: src/rougail/structural_directory/config.py:56
msgid "Main namespace name"
msgstr ""
#: src/rougail/structural_directory/config.py:67
msgid "Extra namespaces"
msgstr ""
#: src/rougail/structural_directory/config.py:76
msgid "Extra namespace name"
msgstr ""
#: src/rougail/structural_directory/config.py:82
msgid "Directories where extra dictionary files are placed"
msgstr ""
#: src/rougail/tiramisureflector.py:376
msgid "internal error, {0} is not a dynamic variable"
msgstr ""
#: src/rougail/user_datas.py:155
msgid "the variable \"{0}\" contains secrets and should not be defined in {1}"
msgstr ""
#: src/rougail/user_datas.py:215
msgid "the option \"{0}\" is an option description"
msgstr "" msgstr ""
#: src/rougail/utils.py:55 #: src/rougail/utils.py:55
msgid "invalid variable or family name \"{0}\" must only contains lowercase ascii character, number or _" msgid "invalid variable or family name \"{0}\" must only contains lowercase ascii character, number or _"
msgstr "" msgstr ""
#: src/rougail/utils.py:117 #: src/rougail/utils.py:113
msgid "error in jinja \"{0}\" for the variable \"{1}\": {2}" msgid "error in jinja \"{0}\" for the variable \"{1}\": {2}"
msgstr "" msgstr ""

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "rougail" name = "rougail"
version = "1.1.1" version = "1.2.0a11"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}] authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md" readme = "README.md"
description = "A consistency handling system that was initially designed in the configuration management" description = "A consistency handling system that was initially designed in the configuration management"

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -25,17 +25,14 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from tiramisu import Config, undefined from tiramisu import Config
from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError
from warnings import warn from warnings import warn
from typing import List
from re import compile, findall
from .convert import RougailConvert from .convert import RougailConvert
from .config import RougailConfig from .config import RougailConfig
from .update import RougailUpgrade
from .object_model import CONVERT_OPTION
from .utils import normalize_family from .utils import normalize_family
from .object_model import CONVERT_OPTION
from .user_datas import UserDatas
def tiramisu_display_name( def tiramisu_display_name(
@ -58,7 +55,7 @@ def tiramisu_display_name(
return f"{path}{comment}" return f"{path}{comment}"
class Rougail: class Rougail(UserDatas):
"""Main Rougail object""" """Main Rougail object"""
def __init__( def __init__(
@ -71,18 +68,10 @@ class Rougail:
self.converted = RougailConvert(self.rougailconfig) self.converted = RougailConvert(self.rougailconfig)
self.config = None self.config = None
def add_path_prefix(
self,
path_prefix: str,
) -> None:
"""Add a prefix"""
self.converted.load_config()
self.converted.parse_directories(path_prefix)
def run(self): def run(self):
"""Get Tiramisu Config""" """Get Tiramisu Config"""
if not self.config: if not self.config:
tiram_obj = self.converted.save(self.rougailconfig["tiramisu_cache"]) tiram_obj = self.converted.save()
optiondescription = {} optiondescription = {}
custom_types = { custom_types = {
custom.__name__: custom custom.__name__: custom
@ -104,223 +93,5 @@ class Rougail:
) )
return self.run() return self.run()
def user_datas(self, user_datas: List[dict]):
values = {}
errors = []
warnings = []
for datas in user_datas:
options = datas.get("options", {})
for name, data in datas.get("values", {}).items():
values[name] = {
"values": data,
"options": options.copy(),
}
errors.extend(datas.get("errors", []))
warnings.extend(datas.get("warnings", []))
self._auto_configure_dynamics(values)
while values:
value_is_set = False
for option in self._get_variable(self.config):
path = option.path()
if path not in values:
path = path.upper()
options = values.get(path, {}).get("options", {})
if path not in values or options.get("upper") is not True:
continue
else:
options = values[path].get("options", {})
value = values[path]["values"]
if option.ismulti():
if options.get("multi_separator") and not isinstance(value, list):
value = value.split(options["multi_separator"])
values[path]["values"] = value
if options.get("needs_convert"):
value = [convert_value(option, val) for val in value]
values[path]["values"] = value
values[path]["options"]["needs_convert"] = False
elif options.get("needs_convert"):
value = convert_value(option, value)
index = option.index()
if index is not None:
if not isinstance(value, list) or index >= len(value):
continue
value = value[index]
try:
option.value.set(value)
value_is_set = True
if index is not None:
values[path]["values"][index] = undefined
if set(values[path]["values"]) == {undefined}:
values.pop(path)
else:
values.pop(path)
except Exception as err:
if path != option.path():
values[option.path()] = values.pop(path)
if not value_is_set:
break
for path, data in values.items():
try:
option = self.config.option(path)
value = data["values"]
if option.isfollower():
for index, val in enumerate(value):
if val is undefined:
continue
self.config.option(path, index).value.set(val)
else:
option.value.set(value)
except AttributeError as err:
errors.append(str(err))
except (ValueError, LeadershipError) as err:
# errors.append(str(err).replace('"', "'"))
errors.append(str(err))
except PropertiesOptionError as err:
# warnings.append(f'"{err}" but is defined in "{self.filename}"')
warnings.append(str(err))
return {
"errors": errors,
"warnings": warnings,
}
def _get_variable(self, config): __all__ = ("Rougail", "RougailConfig")
for subconfig in config:
if subconfig.isoptiondescription():
yield from self._get_variable(subconfig)
else:
yield subconfig
def _auto_configure_dynamics(
self,
values,
):
cache = {}
added = []
for path, data in list(values.items()):
value = data["values"]
# for value in data['values'].items():
try:
option = self.config.option(path)
option.name()
except (ConfigError, PropertiesOptionError):
pass
except AttributeError:
config = self.config
current_path = ""
identifiers = []
for name in path.split(".")[:-1]:
if current_path:
current_path += "."
current_path += name
if current_path in cache:
config, identifier = cache[current_path]
identifiers.append(identifier)
else:
tconfig = config.option(name)
try:
tconfig.group_type()
config = tconfig
except AttributeError:
for tconfig in config.list(uncalculated=True):
if tconfig.isdynamic(only_self=True):
identifier = self._get_identifier(
tconfig.name(), name
)
if identifier is None:
continue
dynamic_variable = tconfig.information.get(
"dynamic_variable",
None,
)
if not dynamic_variable:
continue
option_type = self.config.option(
dynamic_variable
).information.get("type")
if identifiers:
for s in identifiers:
dynamic_variable = dynamic_variable.replace(
"{{ identifier }}", str(s), 1
)
if dynamic_variable not in values:
values[dynamic_variable] = {"values": []}
added.append(dynamic_variable)
elif dynamic_variable not in added:
continue
config = tconfig
# option_type = option.information.get('type')
typ = CONVERT_OPTION.get(option_type, {}).get(
"func"
)
if typ:
identifier = typ(identifier)
if (
identifier
not in values[dynamic_variable]["values"]
):
values[dynamic_variable]["values"].append(
identifier
)
identifiers.append(identifier)
cache[current_path] = config, identifier
break
else:
if option.isdynamic():
parent_option = self.config.option(path.rsplit(".", 1)[0])
identifiers = self._get_identifier(
parent_option.name(uncalculated=True),
parent_option.name(),
)
dynamic_variable = None
while True:
dynamic_variable = parent_option.information.get(
"dynamic_variable",
None,
)
if dynamic_variable:
break
parent_option = self.config.option(
parent_option.path().rsplit(".", 1)[0]
)
if "." not in parent_option.path():
parent_option = None
break
if not parent_option:
continue
identifiers = parent_option.identifiers()
for identifier in identifiers:
dynamic_variable = dynamic_variable.replace(
"{{ identifier }}", str(identifier), 1
)
if dynamic_variable not in values:
values[dynamic_variable] = {"values": []}
added.append(dynamic_variable)
elif dynamic_variable not in added:
continue
option_type = option.information.get("type")
typ = CONVERT_OPTION.get(option_type, {}).get("func")
if typ:
identifier = typ(identifier)
if identifier not in values[dynamic_variable]["values"]:
values[dynamic_variable]["values"].append(identifier)
cache[option.path()] = option, identifier
def _get_identifier(self, true_name, name) -> str:
regexp = true_name.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
return
return finded[0]
def convert_value(option, value):
if value == "":
return None
option_type = option.information.get("type")
func = CONVERT_OPTION.get(option_type, {}).get("func")
if func:
return func(value)
return value
__all__ = ("Rougail", "RougailConfig", "RougailUpgrade")

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -71,16 +71,38 @@ class SpaceAnnotator: # pylint: disable=R0903
if extra_annotator in ANNOTATORS: if extra_annotator in ANNOTATORS:
continue continue
get_annotators(ANNOTATORS, extra_annotator) get_annotators(ANNOTATORS, extra_annotator)
for plugin in objectspace.plugins: for structural in objectspace.structurals:
try: try:
get_annotators(ANNOTATORS, f"rougail.{plugin}", "annotator") get_annotators(
ANNOTATORS, f"rougail.structural_{structural}", "annotator"
)
except ModuleNotFoundError:
pass
for user_data in objectspace.user_datas:
try:
get_annotators(
ANNOTATORS, f"rougail.user_data_{user_data}", "annotator"
)
except ModuleNotFoundError:
pass
if objectspace.output:
try:
get_annotators(
ANNOTATORS, f"rougail.output_{objectspace.output}", "annotator"
)
except ModuleNotFoundError: except ModuleNotFoundError:
pass pass
annotators = ANNOTATORS["rougail.annotator"].copy() annotators = ANNOTATORS["rougail.annotator"].copy()
for extra_annotator in objectspace.extra_annotators: for extra_annotator in objectspace.extra_annotators:
annotators.extend(ANNOTATORS[extra_annotator]) annotators.extend(ANNOTATORS[extra_annotator])
for plugin in objectspace.plugins: for structural in objectspace.structurals:
annotators.extend(ANNOTATORS[f"rougail.{plugin}.annotator"]) annotators.extend(ANNOTATORS[f"rougail.structural_{structural}.annotator"])
for user_data in objectspace.user_datas:
annotators.extend(ANNOTATORS[f"rougail.user_data_{user_data}.annotator"])
if objectspace.output:
annotators.extend(
ANNOTATORS[f"rougail.output_{objectspace.output}.annotator"]
)
annotators = sorted(annotators, key=get_level) annotators = sorted(annotators, key=get_level)
functions = {} functions = {}
functions_files = objectspace.functions_files functions_files = objectspace.functions_files

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -124,11 +124,19 @@ class Annotator(Walk):
family.description = family.name family.description = family.name
if family.type == "dynamic" and isinstance( if family.type == "dynamic" and isinstance(
family.dynamic, VariableCalculation family.dynamic, VariableCalculation
):
path = family.dynamic.variable
if (
family.version != "1.0"
and self.objectspace.paths.regexp_relative.search(path)
): ):
path = self.objectspace.paths.get_full_path( path = self.objectspace.paths.get_full_path(
family.dynamic.variable, family.dynamic.variable,
family.path, family.path,
) )
if family.version == "1.0" and "{{ suffix }}" in path:
path = path.replace("{{ suffix }}", "{{ identifier }}")
self.objectspace.dynamics_variable.setdefault(path, []).append(family.path)
self.objectspace.informations.add(family.path, "dynamic_variable", path) self.objectspace.informations.add(family.path, "dynamic_variable", path)
def change_modes(self): def change_modes(self):

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -120,7 +120,7 @@ class Annotator(Walk):
else: else:
value = [] value = []
for calculation in frozen: for calculation in frozen:
calculation_copy = calculation.copy() calculation_copy = calculation.model_copy()
calculation_copy.attribute_name = "frozen" calculation_copy.attribute_name = "frozen"
calculation_copy.ori_path = calculation_copy.path calculation_copy.ori_path = calculation_copy.path
calculation_copy.path = path calculation_copy.path = path

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -92,7 +92,7 @@ class Annotator(Walk): # pylint: disable=R0903
elif variable.multi: elif variable.multi:
msg = _( msg = _(
'the variable "{0}" is multi but has a non list default value' 'the variable "{0}" is multi but has a non list default value'
).format(variable.name) ).format(variable.path)
raise DictConsistencyError(msg, 12, variable.xmlfiles) raise DictConsistencyError(msg, 12, variable.xmlfiles)
elif variable.path in self.objectspace.followers: elif variable.path in self.objectspace.followers:
self.objectspace.default_multi[variable.path] = variable.default self.objectspace.default_multi[variable.path] = variable.default

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -62,12 +62,6 @@ class Annotator(Walk): # pylint: disable=R0903
if not objectspace.paths: if not objectspace.paths:
return return
self.objectspace = objectspace self.objectspace = objectspace
if self.objectspace.main_namespace:
self.forbidden_name = [self.objectspace.main_namespace]
for extra in self.objectspace.extra_dictionaries:
self.forbidden_name.append(extra)
else:
self.forbidden_name = []
# default type inference from a default value with :term:`basic types` # default type inference from a default value with :term:`basic types`
self.basic_types = { self.basic_types = {
str: "string", str: "string",
@ -136,15 +130,7 @@ class Annotator(Walk): # pylint: disable=R0903
): ):
return return
# copy type and params # copy type and params
calculated_variable_path = variable.default.variable calculated_variable, identifier = variable.default.get_variable(self.objectspace)
calculated_variable, identifier = self.objectspace.paths.get_with_dynamic(
calculated_variable_path,
variable.default.path_prefix,
variable.path,
variable.version,
variable.namespace,
variable.xmlfiles,
)
if calculated_variable is None: if calculated_variable is None:
return return
variable.type = calculated_variable.type variable.type = calculated_variable.type

View file

@ -10,7 +10,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -26,12 +26,17 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from sys import version_info
from pathlib import Path from pathlib import Path
from tiramisu import Config from tiramisu import Config
from ruamel.yaml import YAML from ruamel.yaml import YAML
from .utils import _, load_modules, normalize_family from .utils import _, load_modules, normalize_family
from .convert import RougailConvert from .convert import RougailConvert
from .object_model import get_convert_option_types
if version_info.major == 3 and version_info.minor:
import rougail.structural_commandline.object_model
RENAMED = { RENAMED = {
"dictionaries_dir": "main_dictionaries", "dictionaries_dir": "main_dictionaries",
@ -60,31 +65,32 @@ def get_sub_modules():
def get_level(module): def get_level(module):
return module["level"] return float(module["level"]) + {
"structural": 0.1,
"user data": 0.2,
"output": 0.3,
}.get(module["process"])
class _RougailConfig: class _RougailConfig:
def __init__(self, backward_compatibility: bool, root, extra_vars: dict): def __init__(self, backward_compatibility: bool,
add_extra_options: bool):
self.backward_compatibility = backward_compatibility self.backward_compatibility = backward_compatibility
self.root = root self.add_extra_options = add_extra_options
self.config = Config( self.root = None
self.root,
)
self.config.property.read_only()
self.extra_vars = extra_vars
self.not_in_tiramisu = NOT_IN_TIRAMISU | extra_vars
for variable, default_value in self.not_in_tiramisu.items():
if not isinstance(default_value, str):
default_value = default_value.copy()
setattr(self, variable, default_value)
def copy(self): def copy(self):
rougailconfig = _RougailConfig( rougailconfig = _RougailConfig(
self.backward_compatibility, self.root, self.extra_vars self.backward_compatibility,
self.add_extra_options,
) )
if self.root:
rougailconfig.config.value.importation(self.config.value.exportation()) rougailconfig.config.value.importation(self.config.value.exportation())
rougailconfig.config.property.importation(self.config.property.exportation()) rougailconfig.config.property.importation(self.config.property.exportation())
rougailconfig.config.property.read_only() rougailconfig.config.property.read_only()
rougailconfig.root = self.root
rougailconfig.config = self.config
rougailconfig.extra_vars = self.extra_vars
for variable in self.not_in_tiramisu: for variable in self.not_in_tiramisu:
value = getattr(self, variable) value = getattr(self, variable)
if not isinstance(value, str): if not isinstance(value, str):
@ -92,11 +98,27 @@ class _RougailConfig:
setattr(rougailconfig, variable, value) setattr(rougailconfig, variable, value)
return rougailconfig return rougailconfig
def generate_config(self):
root, extra_vars = _rougail_config(self.backward_compatibility, self.add_extra_options)
self.root = root
self.config = Config(
self.root,
)
self.extra_vars = extra_vars
self.not_in_tiramisu = NOT_IN_TIRAMISU | extra_vars
for variable, default_value in self.not_in_tiramisu.items():
if not isinstance(default_value, str):
default_value = default_value.copy()
setattr(self, variable, default_value)
self.config.property.read_only()
def __setitem__( def __setitem__(
self, self,
key, key,
value, value,
) -> None: ) -> None:
if self.root is None:
self.generate_config()
if key in self.not_in_tiramisu: if key in self.not_in_tiramisu:
setattr(self, key, value) setattr(self, key, value)
else: else:
@ -122,6 +144,8 @@ class _RougailConfig:
self, self,
key, key,
) -> None: ) -> None:
if self.root is None:
self.generate_config()
if key in self.not_in_tiramisu: if key in self.not_in_tiramisu:
return getattr(self, key) return getattr(self, key)
if key == "export_with_import": if key == "export_with_import":
@ -182,19 +206,19 @@ class FakeRougailConvert(RougailConvert):
self.base_option_name = "baseoption" self.base_option_name = "baseoption"
self.export_with_import = True self.export_with_import = True
self.internal_functions = [] self.internal_functions = []
self.plugins = ["structural_commandline"] self.force_optional = False
self.structurals = ["commandline"]
self.user_datas = []
self.output = None
self.add_extra_options = self.add_extra_options self.add_extra_options = self.add_extra_options
self.tiramisu_cache = False
self.load_unexist_redefine = False
def get_rougail_config( def _rougail_config(
*,
backward_compatibility: bool = True, backward_compatibility: bool = True,
add_extra_options: bool = True, add_extra_options: bool = True,
) -> _RougailConfig: ) -> "OptionDescription":
if backward_compatibility:
main_namespace_default = "rougail"
else:
main_namespace_default = "null"
rougail_options = f"""default_dictionary_format_version: rougail_options = f"""default_dictionary_format_version:
description: Dictionary format version by default, if not specified in dictionary file description: Dictionary format version by default, if not specified in dictionary file
alternative_name: v alternative_name: v
@ -203,82 +227,8 @@ def get_rougail_config(
- '1.1' - '1.1'
mandatory: false mandatory: false
main_dictionaries:
description: 'Directories where dictionary files are placed'
type: unix_filename
alternative_name: m
params:
allow_relative: True
test_existence: True
types:
- directory
multi: true
sort_dictionaries_all:
description: Sort dictionaries from differents directories
negative_description: Sort dictionaries directory by directory
default: false
main_namespace:
description: Main namespace name
default: {main_namespace_default}
alternative_name: s
mandatory: false
extra_dictionaries:
description: Extra namespaces
type: leadership
disabled:
variable: main_namespace
when: null
names:
description: 'Extra namespace name'
alternative_name: xn
multi: true
mandatory: false
directories:
description: Directories where extra dictionary files are placed
alternative_name: xd
type: unix_filename
params:
allow_relative: true
test_existence: true
types:
- directory
multi: true
upgrade:
description: Update dictionaries to newest Rougail format version
negative_description: Do not update dictionaries to newest Rougail format version
default: false
upgrade_options:
description: Update informations
disabled:
variable: upgrade
when: false
main_dictionaries:
description: 'Directories where dictionary files will be placed'
default:
variable: __.main_dictionaries
extra_dictionary:
description: 'Directories where extra files will be placed'
type: unix_filename
params:
allow_relative: true
test_existence: true
types:
- directory
disabled:
variable: __.main_namespace
when: null
functions_files: functions_files:
description: File with functions description: {_("File with functions")}
alternative_name: c alternative_name: c
type: unix_filename type: unix_filename
params: params:
@ -290,74 +240,74 @@ functions_files:
mandatory: false mandatory: false
modes_level: modes_level:
description: All modes level available description: {_("All modes level available")}
multi: true multi: true
mandatory: false mandatory: false
""" """
if backward_compatibility: if backward_compatibility:
rougail_options += """ rougail_options += """ default:
default:
- basic - basic
- standard - standard
- advanced - advanced
""" """
rougail_options += """ rougail_options += f"""
default_family_mode: default_family_mode:
description: Default mode for a family description: {_("Default mode for a family")}
default: default:
jinja: | jinja: |
{% if modes_level %} {{% if modes_level %}}
{{ modes_level[0] }} {{{{ modes_level[0] }}}}
{% endif %} {{% endif %}}
disabled: disabled:
jinja: | jinja: |
{% if not modes_level %} {{% if not modes_level %}}
No mode No mode
{% endif %} {{% endif %}}
validators: validators:
- type: jinja - type: jinja
jinja: | jinja: |
{% if default_family_mode not in modes_level %} {{% if default_family_mode not in modes_level %}}
not in modes_level ({modes_level}) not in modes_level ({{modes_level}})
{% endif %} {{% endif %}}
commandline: false commandline: false
default_variable_mode: default_variable_mode:
description: Default mode for a variable description: {_("Default mode for a variable")}
default: default:
jinja: | jinja: |
{% if modes_level %} {{% if modes_level %}}
{% if modes_level | length == 1 %} {{% if modes_level | length == 1 %}}
{{ modes_level[0] }} {{{{ modes_level[0] }}}}
{% else %} {{% else %}}
{{ modes_level[1] }} {{{{ modes_level[1] }}}}
{% endif %} {{% endif %}}
{% endif %} {{% endif %}}
disabled: disabled:
jinja: | jinja: |
{% if not modes_level %} {{% if not modes_level %}}
No mode No mode
{% endif %} {{% endif %}}
validators: validators:
- type: jinja - type: jinja
jinja: | jinja: |
{% if default_variable_mode not in modes_level %} {{% if default_variable_mode not in modes_level %}}
not in modes_level ({modes_level}) not in modes_level ({{modes_level}})
{% endif %} {{% endif %}}
commandline: false commandline: false
base_option_name: base_option_name:
description: Option name for the base option description: {_("Option name for the base option")}
default: baseoption default: baseoption
commandline: false commandline: false
not_export_with_import: not_export_with_import:
description: In cache file, do not importation of Tiramisu and other dependencies description: {_("In cache file, do not importation of Tiramisu and other dependencies")}
negative_description: {_("In cache file, do importation of Tiramisu and other dependencies")}
default: false default: false
commandline: false commandline: false
tiramisu_cache: tiramisu_cache:
description: Tiramisu cache filename description: {_("Tiramisu cache filename")}
alternative_name: t alternative_name: t
type: unix_filename type: unix_filename
mandatory: false mandatory: false
@ -365,50 +315,58 @@ tiramisu_cache:
allow_relative: true allow_relative: true
internal_functions: internal_functions:
description: Name of internal functions that we can use as a function description: {_("Name of internal functions that we can use as a function")}
multi: true multi: true
mandatory: false mandatory: false
commandline: false commandline: false
extra_annotators: extra_annotators:
description: Name of extra annotators description: {_("Name of extra annotators")}
multi: true
mandatory: false
commandline: false
plugins:
description: Name of Rougail plugins
multi: true multi: true
mandatory: false mandatory: false
commandline: false commandline: false
suffix: suffix:
description: Suffix add to generated option name description: {_("Suffix add to generated options name")}
default: '' default: ''
mandatory: false mandatory: false
commandline: false commandline: false
force_optional:
description: {_("Every variables in calculation are optionals")}
negative_description: {_("Variables in calculation are not optional by default")}
default: False
load_unexist_redefine:
description: {_("Loads redefine variables even if there don't already exists")}
negative_description: {_("Loads redefine variables even if there don't already exists")}
commandline: false
default: False
""" """
processes = { processes = {
"structural": [], "structural": [],
"output": [],
"user data": [], "user data": [],
"output": [],
} }
processes_empty = []
for module in get_sub_modules().values(): for module in get_sub_modules().values():
data = module.get_rougail_config() data = module.get_rougail_config(backward_compatibility=backward_compatibility)
if data["process"]:
processes[data["process"]].append(data) processes[data["process"]].append(data)
else:
processes_empty.append(data["options"])
# reorder # reorder
for process in processes: for process in processes:
processes[process] = list(sorted(processes[process], key=get_level)) processes[process] = list(sorted(processes[process], key=get_level))
rougail_process = """step: # Load and exporter steps rougail_process = "step: # Load and exporter steps"
disabled:
variable: upgrade"""
for process in processes: for process in processes:
if processes[process]: if processes[process]:
objects = processes[process] objects = processes[process]
rougail_process += """ rougail_process += """
{NAME}: {NAME}:
description: Select for {NAME} description: Select for {NAME}
alternative_name: {NAME[0]}
choices: choices:
""".format( """.format(
NAME=normalize_family(process), NAME=normalize_family(process),
@ -416,26 +374,46 @@ suffix:
for obj in objects: for obj in objects:
rougail_process += f" - {obj['name']}\n" rougail_process += f" - {obj['name']}\n"
if process == "structural": if process == "structural":
rougail_process += " commandline: false" # rougail_process += """ commandline: false
rougail_process += """ multi: true
default:
- directory
"""
hidden_outputs = [
process["name"]
for process in processes["output"]
if process.get("allow_user_data", True)
]
if hidden_outputs:
rougail_process += """
hidden:
type: jinja
jinja: |
"""
for hidden_output in hidden_outputs:
rougail_process += """ {% if _.output == 'NAME' %}
Cannot load structural for NAME output
{% endif %}""".replace(
"NAME", hidden_output
)
elif process == "user data": elif process == "user data":
rougail_process += """ multi: true rougail_process += """ multi: true
mandatory: false mandatory: false"""
"""
hidden_outputs = [ hidden_outputs = [
process["name"] process["name"]
for process in processes["output"] for process in processes["output"]
if not process.get("allow_user_data", True) if not process.get("allow_user_data", True)
] ]
if hidden_outputs: if hidden_outputs:
rougail_process += """ hidden: rougail_process += """
hidden:
type: jinja type: jinja
jinja: | jinja: |
""" """
for hidden_output in hidden_outputs: for hidden_output in hidden_outputs:
rougail_process += """ {% if _.output == 'NAME' %} rougail_process += """ {% if _.output == 'NAME' %}
Cannot load user data for NAME output Cannot load user data for NAME output
{% endif %} {% endif %}""".replace(
""".replace(
"NAME", hidden_output "NAME", hidden_output
) )
elif objects: elif objects:
@ -443,10 +421,10 @@ suffix:
DEFAULT=objects[0]["name"] DEFAULT=objects[0]["name"]
) )
else: else:
if process == 'output': if process == "output":
prop = 'hidden' prop = "hidden"
else: else:
prop = 'disabled' prop = "disabled"
rougail_process += """ rougail_process += """
{NAME}: {NAME}:
description: Select for {NAME} description: Select for {NAME}
@ -460,9 +438,29 @@ suffix:
NAME=normalize_family(process), NAME=normalize_family(process),
PROP=prop, PROP=prop,
) )
rougail_process += f"""
default_params:
description: {_("Default parameters for option type")}
"""
for typ, params in get_convert_option_types():
rougail_process += f"""
{typ}:
"""
for key, key_type, multi, value in params:
rougail_process += f"""
{key}:
type: {key_type}
multi: {multi}
mandatory: false
default: {value}
"""
for process_empty in processes_empty:
rougail_process += process_empty
rougail_options += rougail_process rougail_options += rougail_process
# print(rougail_options)
convert = FakeRougailConvert(add_extra_options) convert = FakeRougailConvert(add_extra_options)
convert._init() convert.init()
convert.namespace = None convert.namespace = None
convert.parse_root_file( convert.parse_root_file(
"rougail.config", "rougail.config",
@ -471,26 +469,40 @@ suffix:
YAML().load(rougail_options), YAML().load(rougail_options),
) )
extra_vars = {} extra_vars = {}
for process in processes: objects = []
for obj in processes[process]: for obj in sorted(
[obj for objects in processes.values() for obj in objects], key=get_level
):
if "extra_vars" in obj: if "extra_vars" in obj:
extra_vars |= obj["extra_vars"] extra_vars |= obj["extra_vars"]
if not "options" in obj: if not "options" in obj:
continue continue
if not isinstance(obj["options"], list):
options = [obj["options"]]
else:
options = obj["options"]
for option in options:
convert.parse_root_file( convert.parse_root_file(
f'rougail.config.{obj["name"]}', f'rougail.config.{obj["name"]}',
"", "",
"1.1", "1.1",
YAML().load(obj["options"]), YAML().load(option),
) )
tiram_obj = convert.save(None) tiram_obj = convert.save()
optiondescription = {} optiondescription = {}
exec(tiram_obj, {}, optiondescription) # pylint: disable=W0122 exec(tiram_obj, {}, optiondescription) # pylint: disable=W0122
return optiondescription["option_0"], extra_vars
def get_rougail_config(
*,
backward_compatibility: bool = True,
add_extra_options: bool = True,
) -> _RougailConfig:
return _RougailConfig( return _RougailConfig(
backward_compatibility, backward_compatibility,
optiondescription["option_0"], add_extra_options,
extra_vars=extra_vars,
) )

View file

@ -10,7 +10,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -27,9 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import logging import logging
from itertools import chain
from pathlib import Path from pathlib import Path
from re import compile, findall
from typing import ( from typing import (
Any, Any,
Dict, Dict,
@ -42,8 +40,6 @@ from typing import (
get_type_hints, get_type_hints,
) )
from pydantic import ValidationError
from ruamel.yaml import YAML
from ruamel.yaml.comments import CommentedMap from ruamel.yaml.comments import CommentedMap
from pydantic import ValidationError from pydantic import ValidationError
@ -68,7 +64,8 @@ from .object_model import (
VariableCalculation, VariableCalculation,
) )
from .tiramisureflector import TiramisuReflector from .tiramisureflector import TiramisuReflector
from .utils import get_realpath, normalize_family, load_modules from .utils import load_modules
from .path import Paths
from .error import DictConsistencyError from .error import DictConsistencyError
property_types = Union[Literal[True], Calculation] property_types = Union[Literal[True], Calculation]
@ -87,6 +84,12 @@ class Property:
) -> None: ) -> None:
self._properties.setdefault(path, {})[property_] = value self._properties.setdefault(path, {})[property_] = value
def get(self, path: str) -> None:
return self._properties.setdefault(path, {})
def remove(self, path: str, property_: str) -> None:
del self._properties[path][property_]
def __getitem__( def __getitem__(
self, self,
path: str, path: str,
@ -100,218 +103,6 @@ class Property:
return path in self._properties return path in self._properties
class Paths:
regexp_relative = compile(r"^_*\.(.*)$")
def __init__(
self,
default_namespace: str,
) -> None:
self._data: Dict[str, Union[Variable, Family]] = {}
self._dynamics: Dict[str:str] = {}
if default_namespace is not None:
default_namespace = normalize_family(default_namespace)
self.default_namespace = default_namespace
self.path_prefix = None
def has_value(self) -> bool:
return self._data != {}
def add(
self,
path: str,
data: Any,
is_dynamic: bool,
dynamic: str,
*,
force: bool = False,
) -> None:
self._data[path] = data
if not force and is_dynamic:
self._dynamics[path] = dynamic
def get_full_path(
self,
path: str,
current_path: str,
):
relative, subpath = path.split(".", 1)
relative_len = len(relative)
path_len = current_path.count(".")
if path_len + 1 == relative_len:
return subpath
parent_path = current_path.rsplit(".", relative_len)[0]
return parent_path + "." + subpath
def get_with_dynamic(
self,
path: str,
identifier_path: str,
current_path: str,
version: str,
namespace: str,
xmlfiles: List[str],
) -> Any:
identifier = None
if version != "1.0" and self.regexp_relative.search(path):
path = self.get_full_path(
path,
current_path,
)
else:
path = get_realpath(path, identifier_path)
dynamic = None
# version 1.0
if version == "1.0":
if not path in self._data and "{{ suffix }}" not in path:
new_path = None
current_path = None
identifiers = []
for name in path.split("."):
parent_path = current_path
if current_path:
current_path += "." + name
else:
current_path = name
if current_path in self._data:
if new_path:
new_path += "." + name
else:
new_path = name
continue
for dynamic_path in self._dynamics:
if "." in dynamic_path:
parent_dynamic, name_dynamic = dynamic_path.rsplit(".", 1)
else:
parent_dynamic = None
name_dynamic = dynamic_path
if (
parent_dynamic == parent_path
and name_dynamic.endswith("{{ identifier }}")
and name == name_dynamic.replace("{{ identifier }}", "")
):
new_path += "." + name_dynamic
break
regexp = "^" + name_dynamic.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
continue
if finded[0] == "{{ identifier }}":
identifiers.append(None)
else:
identifiers.append(finded[0])
if new_path is None:
new_path = name_dynamic
else:
new_path += "." + name_dynamic
parent_path = dynamic_path
break
else:
if new_path:
new_path += "." + name
else:
new_path = name
path = new_path
else:
identifiers = None
if "{{ suffix }}" in path:
path = path.replace("{{ suffix }}", "{{ identifier }}")
elif not path in self._data:
current_path = None
parent_path = None
new_path = current_path
identifiers = []
for name in path.split("."):
if current_path:
current_path += "." + name
else:
current_path = name
# parent_path, name_path = path.rsplit('.', 1)
if current_path in self._data:
if new_path:
new_path += "." + name
else:
new_path = name
parent_path = current_path
continue
for dynamic_path in self._dynamics:
if "." in dynamic_path:
parent_dynamic, name_dynamic = dynamic_path.rsplit(".", 1)
else:
parent_dynamic = None
name_dynamic = dynamic_path
if (
"{{ identifier }}" not in name_dynamic
or parent_path != parent_dynamic
):
continue
regexp = "^" + name_dynamic.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
continue
if finded[0] == "{{ identifier }}":
identifiers.append(None)
else:
identifiers.append(finded[0])
if new_path is None:
new_path = name_dynamic
else:
new_path += "." + name_dynamic
parent_path = dynamic_path
break
else:
if new_path:
new_path += "." + name
else:
new_path = name
if "{{ identifier }}" in name:
identifiers.append(None)
parent_path = current_path
path = new_path
else:
identifiers = None
if path not in self._data:
return None, None
option = self._data[path]
option_namespace = option.namespace
if (
self.default_namespace not in [namespace, option_namespace]
and namespace != option_namespace
):
msg = _(
'A variable or a family located in the "{0}" namespace shall not be used in the "{1}" namespace'
).format(option_namespace, namespace)
raise DictConsistencyError(msg, 38, xmlfiles)
return option, identifiers
def __getitem__(
self,
path: str,
) -> Union[Family, Variable]:
if not path in self._data:
raise AttributeError(f"cannot find variable or family {path}")
return self._data[path]
def __contains__(
self,
path: str,
) -> bool:
return path in self._data
def __delitem__(
self,
path: str,
) -> None:
logging.info("remove empty family %s", path)
del self._data[path]
def is_dynamic(self, path: str) -> bool:
return path in self._dynamics
def get(self):
return self._data.values()
information_types = Dict[str, Union[str, int, float, bool]] information_types = Dict[str, Union[str, int, float, bool]]
@ -342,7 +133,7 @@ class ParserVariable:
def __init__(self, rougailconfig): def __init__(self, rougailconfig):
self.rougailconfig = rougailconfig self.rougailconfig = rougailconfig
self.load_config() self.load_config()
self.paths = Paths(self.main_namespace) self.paths = Paths(None)
self.families = [] self.families = []
self.variables = [] self.variables = []
self.parents = {".": []} self.parents = {".": []}
@ -350,6 +141,7 @@ class ParserVariable:
self.reflector_names = {} self.reflector_names = {}
self.leaders = [] self.leaders = []
self.followers = [] self.followers = []
self.dynamics_variable = {}
self.multis = {} self.multis = {}
self.default_multi = {} self.default_multi = {}
self.jinja = {} self.jinja = {}
@ -362,20 +154,11 @@ class ParserVariable:
self.properties = Property() self.properties = Property()
# self.choices = Appendable() # self.choices = Appendable()
self.has_dyn_option = False self.has_dyn_option = False
self.path_prefix = None
self.is_init = False self.is_init = False
super().__init__() super().__init__()
def load_config(self) -> None: def load_config(self) -> None:
rougailconfig = self.rougailconfig rougailconfig = self.rougailconfig
self.sort_dictionaries_all = rougailconfig["sort_dictionaries_all"]
try:
self.main_dictionaries = rougailconfig["main_dictionaries"]
except:
self.main_dictionaries = []
self.main_namespace = rougailconfig["main_namespace"]
if self.main_namespace:
self.extra_dictionaries = rougailconfig["extra_dictionaries"]
self.suffix = rougailconfig["suffix"] self.suffix = rougailconfig["suffix"]
self.default_dictionary_format_version = rougailconfig[ self.default_dictionary_format_version = rougailconfig[
"default_dictionary_format_version" "default_dictionary_format_version"
@ -390,35 +173,53 @@ class ParserVariable:
self.base_option_name = rougailconfig["base_option_name"] self.base_option_name = rougailconfig["base_option_name"]
self.export_with_import = rougailconfig["export_with_import"] self.export_with_import = rougailconfig["export_with_import"]
self.internal_functions = rougailconfig["internal_functions"] self.internal_functions = rougailconfig["internal_functions"]
self.force_optional = rougailconfig["force_optional"]
self.add_extra_options = rougailconfig[ self.add_extra_options = rougailconfig[
"structural_commandline.add_extra_options" "structural_commandline.add_extra_options"
] ]
self.plugins = rougailconfig["plugins"] self.structurals = rougailconfig["step.structural"]
self.user_datas = rougailconfig["step.user_data"]
self.output = rougailconfig["step.output"]
self.tiramisu_cache = rougailconfig["tiramisu_cache"]
self.load_unexist_redefine = rougailconfig["load_unexist_redefine"]
# change default initkwargs in CONVERT_OPTION
if hasattr(rougailconfig, 'config'):
for sub_od in rougailconfig.config.option('default_params'):
for option in sub_od:
if option.owner.isdefault():
continue
convert_option = CONVERT_OPTION[sub_od.name()]
if "initkwargs" not in convert_option:
convert_option["initkwargs"] = {}
convert_option["initkwargs"][option.name()] = option.value.get()
def _init(self): def init(self):
if self.is_init: if self.is_init:
return return
variable = Variable variable = Variable
family = Family family = Family
if self.plugins:
root = Path(__file__).parent root = Path(__file__).parent
for plugin in self.plugins: self.walker = None
module_path = root / plugin / "object_model.py" for structural_name in self.structurals:
structural = f"structural_{structural_name}"
module_path = root / structural / "__init__.py"
if not module_path.is_file(): if not module_path.is_file():
continue continue
module = load_modules( module = load_modules(f"rougail.{structural}", str(module_path))
f"rougail.{plugin}.object_model", str(module_path)
)
if "Variable" in module.__all__: if "Variable" in module.__all__:
variable = type( variable = type(
variable.__name__ + "_" + plugin, variable.__name__ + "_" + structural,
(variable, module.Variable), (variable, module.Variable),
{}, {},
) )
if "Family" in module.__all__: if "Family" in module.__all__:
family = type( family = type(
family.__name__ + "_" + plugin, (family, module.Family), {} family.__name__ + "_" + structural, (family, module.Family), {}
) )
if "Walker" in module.__all__:
if self.walker:
raise Exception("multiple walker defined!")
self.walker = module.Walker
self.variable = variable self.variable = variable
self.family = family self.family = family
self.dynamic = type(Dynamic.__name__, (Dynamic, family), {}) self.dynamic = type(Dynamic.__name__, (Dynamic, family), {})
@ -426,7 +227,7 @@ class ParserVariable:
# FIXME: only for format 1.0 # FIXME: only for format 1.0
self.family_types = hint["type"].__args__ # pylint: disable=W0201 self.family_types = hint["type"].__args__ # pylint: disable=W0201
self.family_attrs = frozenset( # pylint: disable=W0201 self.family_attrs = frozenset( # pylint: disable=W0201
set(hint) - {"name", "path", "xmlfiles"} | {"redefine"} set(hint) - {"name", "path", "xmlfiles"} | {"redefine", "exists"}
) )
self.family_calculations = self.search_calculation( # pylint: disable=W0201 self.family_calculations = self.search_calculation( # pylint: disable=W0201
hint hint
@ -588,6 +389,10 @@ class ParserVariable:
return return
family_obj = {} family_obj = {}
subfamily_obj = {} subfamily_obj = {}
if version != "1.0":
exists = obj.pop("exists", None)
else:
exists = None
force_to_attrs = list(self.list_attributes(obj)) force_to_attrs = list(self.list_attributes(obj))
for key, value in obj.items(): for key, value in obj.items():
if key in force_to_attrs: if key in force_to_attrs:
@ -599,12 +404,9 @@ class ParserVariable:
if path in self.paths: if path in self.paths:
# it's just for modify subfamily or subvariable, do not redefine # it's just for modify subfamily or subvariable, do not redefine
if family_obj: if family_obj:
if not obj.pop("redefine", False): if exists in [None, True] and not obj.pop("redefine", False):
raise DictConsistencyError( msg = _('family "{0}" define multiple time').format(path)
f'The family "{path}" already exists and it is not redefined', raise DictConsistencyError(msg, 32, self.paths[path].xmlfiles + [filename])
32,
[filename],
)
# convert to Calculation objects # convert to Calculation objects
self.parse_parameters( self.parse_parameters(
path, path,
@ -615,6 +417,7 @@ class ParserVariable:
version, version,
typ="family", typ="family",
) )
if self.load_unexist_redefine or exists in [None, True]:
self.paths.add( self.paths.add(
path, path,
self.paths[path].model_copy(update=obj), self.paths[path].model_copy(update=obj),
@ -628,10 +431,13 @@ class ParserVariable:
family_is_dynamic = True family_is_dynamic = True
parent_dynamic = path parent_dynamic = path
else: else:
if "redefine" in obj and obj["redefine"]: redefine = family_obj.pop("redefine", None)
if not self.load_unexist_redefine and exists is None and redefine:
raise Exception( raise Exception(
f'cannot redefine the inexisting family "{path}" in {filename}' f'cannot redefine the inexisting family "{path}" in {filename}'
) )
if not self.load_unexist_redefine and exists is True:
return
extra_attrs = set(family_obj) - self.family_attrs extra_attrs = set(family_obj) - self.family_attrs
if extra_attrs: if extra_attrs:
raise Exception(f"extra attrs ... {extra_attrs}") raise Exception(f"extra attrs ... {extra_attrs}")
@ -849,13 +655,14 @@ class ParserVariable:
family_is_leadership is True and first_variable is False, family_is_leadership is True and first_variable is False,
version, version,
) )
self.parse_params(path, obj) self.parse_params(path, obj, filename)
exists = obj.pop("exists", None)
if path in self.paths: if path in self.paths:
if "exists" in obj and not obj.pop("exists"): if not self.load_unexist_redefine and exists is False:
return return
if not obj.pop("redefine", False): if not obj.pop("redefine", False):
msg = f'Variable "{path}" already exists' msg = _('variable "{0}" define multiple time').format(path)
raise DictConsistencyError(msg, 45, [filename]) raise DictConsistencyError(msg, 45, self.paths[path].xmlfiles + [filename])
self.paths.add( self.paths.add(
path, path,
self.paths[path].model_copy(update=obj), self.paths[path].model_copy(update=obj),
@ -865,12 +672,13 @@ class ParserVariable:
) )
self.paths[path].xmlfiles.append(filename) self.paths[path].xmlfiles.append(filename)
else: else:
if "exists" in obj and obj.pop("exists"): if not self.load_unexist_redefine and exists is True:
# this variable must exist # this variable must exist
# but it's not the case # but it's not the case
# so do nothing # so do nothing
return return
if "redefine" in obj and obj["redefine"]: redefine = obj.pop("redefine", False)
if not self.load_unexist_redefine and redefine:
msg = f'cannot redefine the inexisting variable "{path}"' msg = f'cannot redefine the inexisting variable "{path}"'
raise DictConsistencyError(msg, 46, [filename]) raise DictConsistencyError(msg, 46, [filename])
obj["path"] = path obj["path"] = path
@ -951,12 +759,15 @@ class ParserVariable:
f"at index {idx}: {err}" f"at index {idx}: {err}"
) from err ) from err
def parse_params(self, path, obj): def parse_params(self, path, obj, filename):
"""Parse variable params""" """Parse variable params"""
if "params" not in obj: if "params" not in obj:
return return
if not isinstance(obj["params"], dict): if not isinstance(obj["params"], dict):
raise Exception(f"params must be a dict for {path}") raise DictConsistencyError(_("params must be a dict for {0}").format(path),
55,
[filename],
)
params = [] params = []
for key, val in obj["params"].items(): for key, val in obj["params"].items():
try: try:
@ -969,12 +780,14 @@ class ParserVariable:
is_follower=None, is_follower=None,
attribute=None, attribute=None,
family_is_dynamic=None, family_is_dynamic=None,
xmlfiles=None, xmlfiles=[filename],
) )
) )
except ValidationError as err: except ValidationError as err:
raise Exception( raise DictConsistencyError(
f'"{key}" has an invalid "params" for {path}: {err}' _('"{0}" has an invalid "params" for {1}: {2}').format(key, path, err),
54,
[filename],
) from err ) from err
obj["params"] = params obj["params"] = params
@ -993,7 +806,6 @@ class ParserVariable:
variable["namespace"] = self.namespace variable["namespace"] = self.namespace
variable["version"] = version variable["version"] = version
variable["path_prefix"] = self.path_prefix
variable["xmlfiles"] = filename variable["xmlfiles"] = filename
variable_type = self.get_family_or_variable_type(variable) variable_type = self.get_family_or_variable_type(variable)
obj = { obj = {
@ -1070,6 +882,9 @@ class ParserVariable:
return value["type"] in CALCULATION_TYPES return value["type"] in CALCULATION_TYPES
# auto set type # auto set type
typ = set(CALCULATION_TYPES) & set(value) typ = set(CALCULATION_TYPES) & set(value)
# XXX variable is also set to information
if typ == {"variable", "information"}:
typ = {"information"}
if len(typ) == 1: if len(typ) == 1:
value["type"] = list(typ)[0] value["type"] = list(typ)[0]
return True return True
@ -1094,7 +909,6 @@ class ParserVariable:
typ = calculation_object.pop("type") typ = calculation_object.pop("type")
calculation_object["attribute_name"] = attribute calculation_object["attribute_name"] = attribute
calculation_object["path_prefix"] = self.path_prefix
calculation_object["path"] = path calculation_object["path"] = path
calculation_object["inside_list"] = inside_list calculation_object["inside_list"] = inside_list
calculation_object["version"] = version calculation_object["version"] = version
@ -1109,6 +923,9 @@ class ParserVariable:
if isinstance(val, dict) and "type" not in val: if isinstance(val, dict) and "type" not in val:
# auto set type # auto set type
param_typ = set(CALCULATION_TYPES) & set(val) 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: if len(param_typ) == 1:
val["type"] = list(param_typ)[0] val["type"] = list(param_typ)[0]
if not isinstance(val, dict) or "type" not in val: if not isinstance(val, dict) or "type" not in val:
@ -1127,11 +944,17 @@ class ParserVariable:
val["is_follower"] = is_follower val["is_follower"] = is_follower
val["attribute"] = attribute val["attribute"] = attribute
val["xmlfiles"] = xmlfiles val["xmlfiles"] = xmlfiles
if param_typ not in PARAM_TYPES:
raise DictConsistencyError(
f'unknown type "{param_typ}" for "{path}"',
52,
xmlfiles,
)
try: try:
params.append(PARAM_TYPES[param_typ](**val)) params.append(PARAM_TYPES[param_typ](**val))
except ValidationError as err: except ValidationError as err:
raise DictConsistencyError( raise DictConsistencyError(
f'"{attribute}" has an invalid "{key}" for {path}: {err}', f'"{attribute}" has an invalid "{key}" for "{path}": {err}',
29, 29,
xmlfiles, xmlfiles,
) from err ) from err
@ -1164,7 +987,7 @@ class RougailConvert(ParserVariable):
def __init__(self, rougailconfig) -> None: def __init__(self, rougailconfig) -> None:
self.annotator = False self.annotator = False
self.yaml = YAML() self.has_namespace = False
super().__init__(rougailconfig) super().__init__(rougailconfig)
def search_calculation( def search_calculation(
@ -1194,81 +1017,20 @@ class RougailConvert(ParserVariable):
inside_list.append(key) inside_list.append(key)
return inside_list, outside_list return inside_list, outside_list
def parse_directories( def create_namespace(
self, self, namespace_description: str, namespace_path: Optional[str] = None
path_prefix: Optional[str] = None,
) -> None: ) -> None:
"""Parse directories content""" if namespace_path is None:
self._init()
if path_prefix:
n_path_prefix = normalize_family(path_prefix)
if n_path_prefix in self.parents:
raise Exception("pfffff")
root_parent = n_path_prefix
self.path_prefix = n_path_prefix
self.namespace = None
self.add_family(
n_path_prefix,
n_path_prefix,
{"description": path_prefix},
"",
False,
None,
"",
)
else:
root_parent = "."
if self.main_namespace:
directory_dict = chain(
(
(
self.main_namespace,
self.main_dictionaries,
),
),
self.extra_dictionaries.items(),
)
for namespace, extra_dirs in directory_dict:
if namespace is None:
self.namespace = namespace
else:
self.namespace = normalize_family(namespace)
if root_parent == ".":
namespace_path = self.namespace namespace_path = self.namespace
else:
namespace_path = f"{root_parent}.{self.namespace}"
if namespace_path in self.parents:
raise Exception("pfff")
for idx, filename in enumerate(self.get_sorted_filename(extra_dirs)):
if not idx:
self.parse_family( self.parse_family(
"", "",
self.namespace, self.namespace,
namespace_path, namespace_path,
{ {
"description": namespace, "description": namespace_description,
}, },
"", "",
) )
self.parse_variable_file(
filename,
namespace_path,
)
else:
self.namespace = None
if root_parent == ".":
namespace_path = ""
else:
namespace_path = f"{root_parent}"
if namespace_path in self.parents:
raise Exception("pfff")
for filename in self.get_sorted_filename(self.main_dictionaries):
self.parse_variable_file(
filename,
namespace_path,
)
if path_prefix:
self.path_prefix = None
def get_comment( def get_comment(
self, self,
@ -1283,27 +1045,6 @@ class RougailConvert(ParserVariable):
comment = comment.value[1:].strip() comment = comment.value[1:].strip()
return comment return comment
def parse_variable_file(
self,
filename: str,
path: str,
) -> None:
"""Parse file"""
with open(filename, encoding="utf8") as file_fh:
objects = self.yaml.load(file_fh)
version = self.validate_file_version(
objects,
filename,
)
if objects is None:
return
self.parse_root_file(
filename,
path,
version,
objects,
)
def parse_root_file( def parse_root_file(
self, self,
filename: str, filename: str,
@ -1322,38 +1063,6 @@ class RougailConvert(ParserVariable):
comment, comment,
) )
def get_sorted_filename(
self,
directories: Union[str, List[str]],
) -> Iterator[str]:
"""Sort filename"""
if not isinstance(directories, list):
directories = [directories]
if self.sort_dictionaries_all:
filenames = {}
for directory_name in directories:
directory = Path(directory_name)
if not directory.is_dir():
continue
if not self.sort_dictionaries_all:
filenames = {}
for file_path in directory.iterdir():
if file_path.suffix not in [".yml", ".yaml"]:
continue
if file_path.name in filenames:
raise DictConsistencyError(
_("duplicate dictionary file name {0}").format(file_path.name),
78,
[filenames[file_path.name][1]],
)
filenames[file_path.name] = str(file_path)
if not self.sort_dictionaries_all:
for filename in sorted(filenames):
yield filenames[filename]
if self.sort_dictionaries_all:
for filename in sorted(filenames):
yield filenames[filename]
def validate_file_version( def validate_file_version(
self, self,
obj: dict, obj: dict,
@ -1386,6 +1095,7 @@ class RougailConvert(ParserVariable):
): ):
"""Apply annotation""" """Apply annotation"""
if not self.paths.has_value(): if not self.paths.has_value():
self.init()
self.parse_directories() self.parse_directories()
if self.annotator: if self.annotator:
raise DictConsistencyError( raise DictConsistencyError(
@ -1394,6 +1104,13 @@ class RougailConvert(ParserVariable):
SpaceAnnotator(self) SpaceAnnotator(self)
self.annotator = True self.annotator = True
def parse_directories(self) -> None:
if not self.walker:
msg = _('invalid "structural" definition ({0}), we cannot load any structural file!').format(self.structurals)
raise DictConsistencyError(msg, 51, None)
self.init()
self.walker(self)
def reflect(self) -> None: def reflect(self) -> None:
"""Apply TiramisuReflector""" """Apply TiramisuReflector"""
functions_files = [ functions_files = [
@ -1406,13 +1123,13 @@ class RougailConvert(ParserVariable):
def save( def save(
self, self,
filename: str,
): ):
"""Return tiramisu object declaration as a string""" """Return tiramisu object declaration as a string"""
self._init() self.init()
self.annotate() self.annotate()
self.reflect() self.reflect()
output = self.reflector.get_text() + "\n" output = self.reflector.get_text() + "\n"
filename = self.tiramisu_cache
if filename: if filename:
with open(filename, "w", encoding="utf-8") as tiramisu: with open(filename, "w", encoding="utf-8") as tiramisu:
tiramisu.write(output) tiramisu.write(output)

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -69,10 +69,6 @@ class DictConsistencyError(Exception):
self.errno = errno self.errno = errno
class UpgradeError(Exception):
"""Error during XML upgrade"""
## ---- generic exceptions ---- ## ---- generic exceptions ----
@ -81,6 +77,10 @@ class NotFoundError(Exception):
pass pass
class ExtentionError(Exception):
pass
## ---- specific exceptions ---- ## ---- specific exceptions ----

View file

@ -8,7 +8,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the

View file

@ -1,7 +1,7 @@
"""Rougail object model """Rougail object model
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2023-2024 Copyright (C) 2023-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -27,7 +27,8 @@ from pydantic import (
ConfigDict, ConfigDict,
) )
from tiramisu import undefined from tiramisu import undefined
from .utils import get_jinja_variable_to_param, get_realpath import tiramisu
from .utils import get_jinja_variable_to_param
from .error import DictConsistencyError, VariableCalculationDependencyError from .error import DictConsistencyError, VariableCalculationDependencyError
BASETYPE = Union[StrictBool, StrictInt, StrictFloat, StrictStr, None] BASETYPE = Union[StrictBool, StrictInt, StrictFloat, StrictStr, None]
@ -105,6 +106,35 @@ CONVERT_OPTION = {
} }
def get_convert_option_types():
for typ, datas in CONVERT_OPTION.items():
obj = getattr(tiramisu, datas["opttype"])
initkwargs = datas.get("initkwargs", {})
if obj == tiramisu.SymLinkOption:
continue
if obj == tiramisu.ChoiceOption:
inst = obj('a', 'a', ('a',), **initkwargs)
else:
inst = obj('a', 'a', **initkwargs)
extra = getattr(inst, '_extra', {})
if not extra:
continue
params = []
for key, value in extra.items():
if key.startswith('_'):
continue
multi = False
if isinstance(value, bool):
key_type = 'boolean'
elif isinstance(value, str):
key_type = 'string'
elif isinstance(value, list):
key_type = 'string'
multi = True
params.append((key, key_type, multi, value))
yield typ, params
class Param(BaseModel): class Param(BaseModel):
key: str key: str
model_config = ConfigDict(extra="forbid") model_config = ConfigDict(extra="forbid")
@ -178,7 +208,6 @@ PARAM_TYPES = {
class Calculation(BaseModel): class Calculation(BaseModel):
path_prefix: Optional[str]
path: str path: str
inside_list: bool inside_list: bool
version: str version: str
@ -189,12 +218,6 @@ class Calculation(BaseModel):
model_config = ConfigDict(extra="forbid") model_config = ConfigDict(extra="forbid")
def get_realpath(
self,
path: str,
) -> str:
return get_realpath(path, self.path_prefix)
def get_params(self, objectspace): def get_params(self, objectspace):
if not self.params: if not self.params:
return {} return {}
@ -208,7 +231,6 @@ class Calculation(BaseModel):
path = self.ori_path path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
param["variable"], param["variable"],
self.path_prefix,
path, path,
self.version, self.version,
self.namespace, self.namespace,
@ -220,7 +242,12 @@ class Calculation(BaseModel):
raise DictConsistencyError(msg, 22, self.xmlfiles) raise DictConsistencyError(msg, 22, self.xmlfiles)
continue continue
if not isinstance(variable, objectspace.variable): if not isinstance(variable, objectspace.variable):
raise Exception("pfff it's a family") if isinstance(variable, objectspace.family):
msg = f'the variable "{variable["name"]}" is in fact a family in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 42, self.xmlfiles)
else:
msg = f'unknown object "{variable}" in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 44, self.xmlfiles)
param["variable"] = variable param["variable"] = variable
if identifier: if identifier:
param["identifier"] = identifier param["identifier"] = identifier
@ -232,7 +259,6 @@ class Calculation(BaseModel):
path = self.ori_path path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
param["variable"], param["variable"],
self.path_prefix,
path, path,
self.version, self.version,
self.namespace, self.namespace,
@ -314,7 +340,6 @@ class JinjaCalculation(Calculation):
objectspace, objectspace,
variable.xmlfiles, variable.xmlfiles,
objectspace.functions, objectspace.functions,
self.path_prefix,
self.version, self.version,
self.namespace, self.namespace,
): ):
@ -332,6 +357,7 @@ class JinjaCalculation(Calculation):
} }
if self.version != "1.0": if self.version != "1.0":
default["params"][true_path]["propertyerror"] = False default["params"][true_path]["propertyerror"] = False
default["params"][true_path]["optional"] = True
if identifier: if identifier:
default["params"][true_path]["identifier"] = identifier default["params"][true_path]["identifier"] = identifier
return default return default
@ -412,15 +438,18 @@ class _VariableCalculation(Calculation):
path = self.ori_path path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
self.variable, self.variable,
self.path_prefix,
path, path,
self.version, self.version,
self.namespace, self.namespace,
self.xmlfiles, self.xmlfiles,
) )
if variable and not isinstance(variable, objectspace.variable): if variable and not isinstance(variable, objectspace.variable):
# FIXME remove the pfff if isinstance(variable, objectspace.family):
raise Exception("pfff it's a family") msg = f'the variable "{variable.path}" is in fact a family in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 47, self.xmlfiles)
else:
msg = f'unknown object "{variable}" in attribute "{self.attribute_name}" for "{self.path}"'
raise DictConsistencyError(msg, 48, self.xmlfiles)
return variable, identifier return variable, identifier
def get_params( def get_params(
@ -432,13 +461,21 @@ class _VariableCalculation(Calculation):
needs_multi: Optional[bool] = None, needs_multi: Optional[bool] = None,
): ):
if not variable: if not variable:
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" for variable "{self.path}"' if not objectspace.force_optional:
if self.ori_path is None:
path = self.path
else:
path = self.ori_path
msg = f'Variable not found "{self.variable}" for attribut "{self.attribute_name}" in variable "{path}"'
raise DictConsistencyError(msg, 88, self.xmlfiles) raise DictConsistencyError(msg, 88, self.xmlfiles)
return {None: [["example"]]}
param = { param = {
"type": "variable", "type": "variable",
"variable": variable, "variable": variable,
"propertyerror": self.propertyerror, "propertyerror": self.propertyerror,
} }
if isinstance(self, VariableCalculation) and self.optional:
param["optional"] = self.optional
if identifier: if identifier:
param["identifier"] = identifier param["identifier"] = identifier
params = {None: [param]} params = {None: [param]}
@ -488,6 +525,12 @@ class _VariableCalculation(Calculation):
raise DictConsistencyError(msg, 21, self.xmlfiles) raise DictConsistencyError(msg, 21, self.xmlfiles)
else: else:
params[None][0]["index"] = {"index": {"type": "index"}} params[None][0]["index"] = {"index": {"type": "index"}}
if self.path in objectspace.followers:
multi = objectspace.multis[self.path] == "submulti"
else:
multi = self.path in objectspace.multis
if multi and not self.inside_list:
params["__internal_multi"] = True
return params return params
@ -503,7 +546,11 @@ class VariableCalculation(_VariableCalculation):
msg = f'"{self.attribute_name}" variable shall not have an "optional" attribute for variable "{self.variable}"' msg = f'"{self.attribute_name}" variable shall not have an "optional" attribute for variable "{self.variable}"'
raise DictConsistencyError(msg, 33, self.xmlfiles) raise DictConsistencyError(msg, 33, self.xmlfiles)
variable, identifier = self.get_variable(objectspace) variable, identifier = self.get_variable(objectspace)
if not variable and self.optional: if (
not variable
and self.optional
or (objectspace.force_optional and self.attribute_name == "default")
):
raise VariableCalculationDependencyError() raise VariableCalculationDependencyError()
params = self.get_params( params = self.get_params(
objectspace, objectspace,
@ -517,7 +564,8 @@ class VariableCalculation(_VariableCalculation):
class VariablePropertyCalculation(_VariableCalculation): class VariablePropertyCalculation(_VariableCalculation):
attribute_name: Literal[*PROPERTY_ATTRIBUTE] # For python 3.9 attribute_name: Literal[*PROPERTY_ATTRIBUTE]
attribute_name: Literal["frozen", "hidden", "disabled", "mandatory"]
when: Any = undefined when: Any = undefined
when_not: Any = undefined when_not: Any = undefined
@ -532,6 +580,7 @@ class VariablePropertyCalculation(_VariableCalculation):
identifier, identifier,
needs_multi=False, needs_multi=False,
) )
if params[None] and "variable" in params[None][0]:
variable = params[None][0]["variable"] variable = params[None][0]["variable"]
if self.when is not undefined: if self.when is not undefined:
if self.version == "1.0": if self.version == "1.0":
@ -553,9 +602,9 @@ class VariablePropertyCalculation(_VariableCalculation):
raise Exception("only boolean!") raise Exception("only boolean!")
when = True when = True
inverse = False inverse = False
params[None].insert(0, self.attribute_name)
params["when"] = when params["when"] = when
params["inverse"] = inverse params["inverse"] = inverse
params[None].insert(0, self.attribute_name)
return { return {
"function": "variable_to_property", "function": "variable_to_property",
"params": params, "params": params,
@ -587,14 +636,19 @@ class InformationCalculation(Calculation):
path = self.ori_path path = self.ori_path
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
self.variable, self.variable,
self.path_prefix,
path, path,
self.version, self.version,
self.namespace, self.namespace,
self.xmlfiles, self.xmlfiles,
) )
if variable is None or identifier is not None: if variable is None:
raise Exception("pfff") if not objectspace.force_optional:
msg = f'cannot find variable "{self.variable}" for the information "{self.information}" when calculating "{self.attribute_name}"'
raise DictConsistencyError(msg, 40, variable.xmlfiles)
if identifier is not None:
msg = f'identifier not allowed for the information "{self.information}" when calculating "{self.attribute_name}"'
raise DictConsistencyError(msg, 41, variable.xmlfiles)
if variable:
params[None][0]["variable"] = variable params[None][0]["variable"] = variable
if self.default_values: if self.default_values:
params["__default_value"] = self.default_values params["__default_value"] = self.default_values
@ -631,7 +685,8 @@ class IdentifierCalculation(_IdentifierCalculation):
class IdentifierPropertyCalculation(_IdentifierCalculation): class IdentifierPropertyCalculation(_IdentifierCalculation):
attribute_name: Literal[*PROPERTY_ATTRIBUTE] # for python 3.9 attribute_name: Literal[*PROPERTY_ATTRIBUTE]
attribute_name: Literal["frozen", "hidden", "disabled", "mandatory"]
when: Any = undefined when: Any = undefined
when_not: Any = undefined when_not: Any = undefined
@ -684,16 +739,16 @@ class IndexCalculation(Calculation):
CALCULATION_TYPES = { CALCULATION_TYPES = {
"jinja": JinjaCalculation, "jinja": JinjaCalculation,
"variable": VariableCalculation,
"information": InformationCalculation, "information": InformationCalculation,
"variable": VariableCalculation,
"identifier": IdentifierCalculation, "identifier": IdentifierCalculation,
"suffix": IdentifierCalculation, "suffix": IdentifierCalculation,
"index": IndexCalculation, "index": IndexCalculation,
} }
CALCULATION_PROPERTY_TYPES = { CALCULATION_PROPERTY_TYPES = {
"jinja": JinjaCalculation, "jinja": JinjaCalculation,
"variable": VariablePropertyCalculation,
"information": InformationCalculation, "information": InformationCalculation,
"variable": VariablePropertyCalculation,
"identifier": IdentifierPropertyCalculation, "identifier": IdentifierPropertyCalculation,
"index": IndexCalculation, "index": IndexCalculation,
} }
@ -702,14 +757,18 @@ BASETYPE_CALC = Union[StrictBool, StrictInt, StrictFloat, StrictStr, Calculation
class Family(BaseModel): class Family(BaseModel):
name: str name: str
# informations
description: Optional[str] = None description: Optional[str] = None
type: Literal["family", "leadership", "dynamic"] = "family"
path: str
help: Optional[str] = None help: Optional[str] = None
mode: Optional[str] = None mode: Optional[str] = None
# validation
type: Literal["family", "leadership", "dynamic"] = "family"
# properties
hidden: Union[bool, Calculation] = False hidden: Union[bool, Calculation] = False
disabled: Union[bool, Calculation] = False disabled: Union[bool, Calculation] = False
# others
namespace: Optional[str] namespace: Optional[str]
path: str
version: str version: str
xmlfiles: List[str] = [] xmlfiles: List[str] = []
@ -723,30 +782,34 @@ class Dynamic(Family):
class Variable(BaseModel): class Variable(BaseModel):
# type will be set dynamically in `annotator/value.py`, default is None
type: str = None
name: str name: str
# user informations
description: Optional[str] = None description: Optional[str] = None
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
regexp: Optional[str] = None
params: Optional[List[Param]] = None
validators: Optional[List[Calculation]] = None
multi: Optional[bool] = None
unique: Optional[bool] = None
help: Optional[str] = None help: Optional[str] = None
hidden: Union[bool, Calculation] = False mode: Optional[str] = None
disabled: Union[bool, Calculation] = False examples: Optional[list] = None
test: Optional[list] = None
# validations
## type will be set dynamically in `annotator/value.py`, default is None
type: str = None
params: Optional[List[Param]] = None
regexp: Optional[str] = None
choices: Optional[Union[List[BASETYPE_CALC], Calculation]] = None
multi: Optional[bool] = None
validators: Optional[List[Calculation]] = None
# value
default: Union[List[BASETYPE_CALC], BASETYPE_CALC] = None
# properties
auto_save: bool = False
mandatory: Union[None, bool, Calculation] = None mandatory: Union[None, bool, Calculation] = None
empty: Union[None, bool, Calculation] = True empty: Union[None, bool, Calculation] = True
auto_save: bool = False unique: Optional[bool] = None
mode: Optional[str] = None hidden: Union[bool, Calculation] = False
test: Optional[list] = None disabled: Union[bool, Calculation] = False
examples: Optional[list] = None # others
path: str path: str
namespace: Optional[str] namespace: Optional[str]
version: str version: str
path_prefix: Optional[str]
xmlfiles: List[str] = [] xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True) model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True)
@ -759,7 +822,6 @@ class SymLink(BaseModel):
opt: Variable opt: Variable
namespace: Optional[str] namespace: Optional[str]
version: str version: str
path_prefix: Optional[str]
xmlfiles: List[str] = [] xmlfiles: List[str] = []
model_config = ConfigDict(extra="forbid") model_config = ConfigDict(extra="forbid")

240
src/rougail/path.py Normal file
View file

@ -0,0 +1,240 @@
"""
Copyright (C) 2024-2025
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 <http://www.gnu.org/licenses/>.
"""
from typing import (
Any,
Dict,
List,
Union,
)
import logging
from re import compile, findall
from .i18n import _
from .object_model import Family, Variable
from .utils import normalize_family
class Paths:
regexp_relative = compile(r"^_*\.(.*)$")
def __init__(
self,
default_namespace: str,
) -> None:
self._data: Dict[str, Union[Variable, Family]] = {}
self._dynamics: Dict[str:str] = {}
if default_namespace is not None:
default_namespace = normalize_family(default_namespace)
self.default_namespace = default_namespace
def has_value(self) -> bool:
return self._data != {}
def add(
self,
path: str,
data: Any,
is_dynamic: bool,
dynamic: str,
*,
force: bool = False,
) -> None:
self._data[path] = data
if not force and is_dynamic:
self._dynamics[path] = dynamic
def get_full_path(
self,
path: str,
current_path: str,
):
relative, subpath = path.split(".", 1)
relative_len = len(relative)
path_len = current_path.count(".")
if path_len + 1 == relative_len:
return subpath
parent_path = current_path.rsplit(".", relative_len)[0]
return parent_path + "." + subpath
def get_with_dynamic(
self,
path: str,
# identifier_path: str,
current_path: str,
version: str,
namespace: str,
xmlfiles: List[str],
) -> Any:
identifier = None
if version != "1.0" and self.regexp_relative.search(path):
path = self.get_full_path(
path,
current_path,
)
# elif identifier_path:
# path = f"{identifier_path}.{path}"
dynamic = None
# version 1.0
if version == "1.0":
if not path in self._data and "{{ suffix }}" not in path:
new_path = None
current_path = None
identifiers = []
for name in path.split("."):
parent_path = current_path
if current_path:
current_path += "." + name
else:
current_path = name
if current_path in self._data:
if new_path:
new_path += "." + name
else:
new_path = name
continue
for dynamic_path in self._dynamics:
if "." in dynamic_path:
parent_dynamic, name_dynamic = dynamic_path.rsplit(".", 1)
else:
parent_dynamic = None
name_dynamic = dynamic_path
if (
parent_dynamic == parent_path
and name_dynamic.endswith("{{ identifier }}")
and name == name_dynamic.replace("{{ identifier }}", "")
):
new_path += "." + name_dynamic
break
regexp = "^" + name_dynamic.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
continue
if finded[0] == "{{ identifier }}":
identifiers.append(None)
else:
identifiers.append(finded[0])
if new_path is None:
new_path = name_dynamic
else:
new_path += "." + name_dynamic
parent_path = dynamic_path
break
else:
if new_path:
new_path += "." + name
else:
new_path = name
path = new_path
else:
identifiers = None
if "{{ suffix }}" in path:
path = path.replace("{{ suffix }}", "{{ identifier }}")
elif not path in self._data:
current_path = None
parent_path = None
new_path = current_path
identifiers = []
for name in path.split("."):
if current_path:
current_path += "." + name
else:
current_path = name
# parent_path, name_path = path.rsplit('.', 1)
if current_path in self._data:
if new_path:
new_path += "." + name
else:
new_path = name
parent_path = current_path
continue
for dynamic_path in self._dynamics:
if "." in dynamic_path:
parent_dynamic, name_dynamic = dynamic_path.rsplit(".", 1)
else:
parent_dynamic = None
name_dynamic = dynamic_path
if (
"{{ identifier }}" not in name_dynamic
or parent_path != parent_dynamic
):
continue
regexp = "^" + name_dynamic.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
continue
if finded[0] == "{{ identifier }}":
identifiers.append(None)
else:
identifiers.append(finded[0])
if new_path is None:
new_path = name_dynamic
else:
new_path += "." + name_dynamic
parent_path = dynamic_path
break
else:
if new_path:
new_path += "." + name
else:
new_path = name
if "{{ identifier }}" in name:
identifiers.append(None)
parent_path = current_path
path = new_path
else:
identifiers = None
if path not in self._data:
return None, None
option = self._data[path]
option_namespace = option.namespace
if (
self.default_namespace not in [namespace, option_namespace]
and namespace != option_namespace
):
msg = _(
'A variable or a family located in the "{0}" namespace shall not be used in the "{1}" namespace'
).format(option_namespace, namespace)
raise DictConsistencyError(msg, 38, xmlfiles)
return option, identifiers
def __getitem__(
self,
path: str,
) -> Union[Family, Variable]:
if not path in self._data:
raise AttributeError(f"cannot find variable or family {path}")
return self._data[path]
def __contains__(
self,
path: str,
) -> bool:
return path in self._data
def __delitem__(
self,
path: str,
) -> None:
logging.info("remove empty family %s", path)
del self._data[path]
def is_dynamic(self, path: str) -> bool:
return path in self._dynamics
def get(self):
return self._data.values()

View file

@ -1,6 +1,6 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -16,4 +16,7 @@ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from .update import RougailUpgrade from .object_model import Variable, Family
__all__ = ("Variable", "Family")

View file

@ -1,7 +1,7 @@
"""Annotate to add specify attribute for tiramisu-cmdline """Annotate to add specify attribute for tiramisu-cmdline
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -91,6 +91,9 @@ class Annotator(Walk):
def manage_negative_description(self, variable) -> None: def manage_negative_description(self, variable) -> None:
if not variable.negative_description: if not variable.negative_description:
if variable.type == "boolean" and not self.objectspace.add_extra_options: if variable.type == "boolean" and not self.objectspace.add_extra_options:
if variable.name == variable.description:
variable.negative_description = variable.name
else:
raise DictConsistencyError( raise DictConsistencyError(
_( _(
'negative_description is mandatory for boolean variable, but "{0}" hasn\'t' 'negative_description is mandatory for boolean variable, but "{0}" hasn\'t'
@ -98,8 +101,7 @@ class Annotator(Walk):
200, 200,
variable.xmlfiles, variable.xmlfiles,
) )
return elif variable.type != "boolean":
if variable.type != "boolean":
raise DictConsistencyError( raise DictConsistencyError(
_( _(
'negative_description is only available for boolean variable, but "{0}" is "{1}"' 'negative_description is only available for boolean variable, but "{0}" is "{1}"'
@ -107,6 +109,7 @@ class Annotator(Walk):
201, 201,
variable.xmlfiles, variable.xmlfiles,
) )
if variable.negative_description:
self.objectspace.informations.add( self.objectspace.informations.add(
variable.path, "negative_description", variable.negative_description variable.path, "negative_description", variable.negative_description
) )

View file

@ -2,7 +2,7 @@
Config file for Rougail-structural_commandline Config file for Rougail-structural_commandline
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -27,12 +27,14 @@ def get_rougail_config(
structural_commandline: structural_commandline:
description: Configuration rougail-structural_commandline description: Configuration rougail-structural_commandline
commandline: false commandline: false
add_extra_options: add_extra_options:
description: Add extra options to tiramisu-cmdline-parser description: Add extra options to tiramisu-cmdline-parser
negative_description: Remove extra options to tiramisu-cmdline-parser
default: true default: true
""" """
return { return {
"name": "exporter", "name": "cmdline",
"process": "structural", "process": "structural",
"options": options, "options": options,
"level": 20, "level": 20,

View file

@ -1,7 +1,7 @@
"""Annotate to add specify attribute for tiramisu-cmdline """Annotate to add specify attribute for tiramisu-cmdline
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -29,6 +29,3 @@ class Variable(BaseModel):
class Family(BaseModel): class Family(BaseModel):
commandline: bool = True commandline: bool = True
__all__ = ("Variable", "Family")

View file

@ -0,0 +1,155 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2022-2025
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 <http://www.gnu.org/licenses/>.
"""
from typing import Union, List, Iterator, Optional
from itertools import chain
from pathlib import Path
from ruamel.yaml import YAML
from ..utils import normalize_family
from ..path import Paths
from ..error import DictConsistencyError
from ..i18n import _
class Walker:
def __init__(
self,
convert,
) -> None:
"""Parse directories content"""
self.convert = convert
self.yaml = YAML()
rougailconfig = self.convert.rougailconfig
self.sort_dictionaries_all = rougailconfig["sort_dictionaries_all"]
if rougailconfig["main_namespace"]:
self.convert.paths = Paths(rougailconfig["main_namespace"])
self.load_with_extra(
rougailconfig["extra_dictionaries"],
rougailconfig["main_namespace"],
rougailconfig["main_dictionaries"],
)
else:
self.convert.namespace = None
namespace_path = ""
if namespace_path in self.convert.parents:
raise Exception("pfff")
for filename in self.get_sorted_filename(
rougailconfig["main_dictionaries"]
):
self.parse_variable_file(
filename,
namespace_path,
)
def load_with_extra(
self,
extra_structures: dict,
main_namespace: Optional[str] = None,
main_structures: Optional[List[str]] = None,
) -> None:
self.convert.has_namespace = True
if main_namespace:
directory_dict = chain(
(
(
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)
self.parse_variable_file(
filename,
namespace_path,
)
def get_sorted_filename(
self,
directories: Union[str, List[str]],
) -> Iterator[str]:
"""Sort filename"""
if not isinstance(directories, list):
directories = [directories]
if self.sort_dictionaries_all:
filenames = {}
for directory_name in directories:
directory = Path(directory_name)
if not self.sort_dictionaries_all:
filenames = {}
if directory.is_file():
self.get_filename(directory, filenames)
else:
for file_path in directory.iterdir():
self.get_filename(file_path, filenames)
if not self.sort_dictionaries_all:
for filename in sorted(filenames):
yield filenames[filename]
if self.sort_dictionaries_all:
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"]:
return
if file_path.name in filenames:
raise DictConsistencyError(
_("duplicate dictionary file name {0}").format(file_path.name),
78,
[filenames[file_path.name], str(file_path)],
)
filenames[file_path.name] = str(file_path)
def parse_variable_file(
self,
filename: str,
path: str,
) -> None:
"""Parse file"""
with open(filename, encoding="utf8") as file_fh:
objects = self.yaml.load(file_fh)
version = self.convert.validate_file_version(
objects,
filename,
)
if objects is None:
return
self.convert.parse_root_file(
filename,
path,
version,
objects,
)
__all__ = ("Walker",)

View file

@ -0,0 +1,100 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2024-2025
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 <http://www.gnu.org/licenses/>.
"""
from ..utils import _
def get_rougail_config(
*,
backward_compatibility=True,
) -> dict:
if backward_compatibility:
main_namespace_default = "rougail"
else:
main_namespace_default = "null"
options = f"""
main_dictionaries:
description: {_("Directories where dictionary files are placed")}
type: unix_filename
alternative_name: m
params:
allow_relative: True
test_existence: True
multi: true
disabled:
jinja: >-
{{% if 'directory' not in step.structural %}}
directory is not in step.structural
{{% endif %}}
sort_dictionaries_all:
description: {_("Sort dictionaries from differents directories")}
negative_description: Sort dictionaries directory by directory
default: false
disabled:
jinja: >-
{{% if 'directory' not in step.structural %}}
directory is not in step.structural
{{% endif %}}
main_namespace:
description: {_("Main namespace name")}
default: {main_namespace_default}
alternative_name: s
mandatory: false
disabled:
jinja: >-
{{% if 'directory' not in step.structural %}}
directory is not in step.structural
{{% endif %}}
extra_dictionaries:
description: {_("Extra namespaces")}
type: leadership
disabled:
jinja: >-
{{% if 'directory' not in step.structural %}}
directory is not in step.structural
{{% endif %}}
names:
description: {_("Extra namespace name")}
alternative_name: xn
multi: true
mandatory: false
directories:
description: {_("Directories where extra dictionary files are placed")}
alternative_name: xd
type: unix_filename
params:
allow_relative: true
test_existence: true
types:
- directory
multi: true
"""
return {
"name": "directory",
"process": "structural",
"options": options,
"level": 5,
}
__all__ = "get_rougail_config"

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -27,10 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Any from typing import Any
try:
from tiramisu5 import DynOptionDescription, calc_value
except ModuleNotFoundError:
from tiramisu import DynOptionDescription, calc_value
from importlib.machinery import SourceFileLoader as _SourceFileLoader from importlib.machinery import SourceFileLoader as _SourceFileLoader
from importlib.util import ( from importlib.util import (
spec_from_loader as _spec_from_loader, spec_from_loader as _spec_from_loader,
@ -40,8 +36,8 @@ from jinja2 import StrictUndefined, DictLoader
from jinja2.sandbox import SandboxedEnvironment from jinja2.sandbox import SandboxedEnvironment
from rougail.object_model import CONVERT_OPTION from rougail.object_model import CONVERT_OPTION
from rougail.error import display_xmlfiles from rougail.error import display_xmlfiles
from tiramisu import function_waiting_for_error from tiramisu import DynOptionDescription, calc_value, function_waiting_for_error
from tiramisu.error import ValueWarning, ConfigError, PropertiesOptionError from tiramisu.error import ValueWarning, ConfigError, PropertiesOptionError, CancelParam
from .utils import normalize_family from .utils import normalize_family
@ -102,8 +98,10 @@ def load_functions(path):
func[function] = getattr(func_, function) func[function] = getattr(func_, function)
def rougail_calc_value(*args, __default_value=None, **kwargs): def rougail_calc_value(*args, __default_value=None, __internal_multi=False, **kwargs):
values = calc_value(*args, **kwargs) values = calc_value(*args, **kwargs)
if values is None and __internal_multi:
values = []
if __default_value is not None and values in [None, []]: if __default_value is not None and values in [None, []]:
return __default_value return __default_value
return values return values
@ -128,8 +126,14 @@ def jinja_to_function(
if "." in key: if "." in key:
c_kw = kw c_kw = kw
path, var = key.rsplit(".", 1) path, var = key.rsplit(".", 1)
if isinstance(value, CancelParam):
count_o_path = value.origin_path.count(".") - value.current_path.count(
"."
)
path = path.rsplit(".", count_o_path)[0]
for subkey in path.split("."): for subkey in path.split("."):
c_kw = c_kw.setdefault(subkey, {}) c_kw = c_kw.setdefault(subkey, {})
if not isinstance(value, CancelParam):
c_kw[var] = value c_kw[var] = value
else: else:
if key in kw: if key in kw:
@ -161,7 +165,7 @@ def jinja_to_function(
return values return values
def variable_to_property(prop, value, when, inverse): def variable_to_property(prop, value, when, inverse, **kwargs):
if isinstance(value, PropertiesOptionError): if isinstance(value, PropertiesOptionError):
raise value from value raise value from value
if inverse: if inverse:

View file

@ -10,7 +10,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -87,7 +87,7 @@ class TiramisuReflector:
continue continue
self.text["header"].append(f"load_functions('{funcs_path}')") self.text["header"].append(f"load_functions('{funcs_path}')")
if self.objectspace.export_with_import: if self.objectspace.export_with_import:
if objectspace.main_namespace: if self.objectspace.has_namespace:
self.text["header"].extend( self.text["header"].extend(
[ [
"try:", "try:",
@ -339,6 +339,7 @@ class Common:
return self.build_option_param( return self.build_option_param(
param["variable"], param["variable"],
param.get("propertyerror", True), param.get("propertyerror", True),
param.get("optional", False),
param.get("identifier"), param.get("identifier"),
param.get("dynamic"), param.get("dynamic"),
param.get("whole", False), param.get("whole", False),
@ -355,6 +356,7 @@ class Common:
self, self,
variable, variable,
propertyerror, propertyerror,
optional: bool,
identifier: Optional[str], identifier: Optional[str],
dynamic, dynamic,
whole: bool, whole: bool,
@ -370,6 +372,11 @@ class Common:
) )
params = [f"{option_name}"] params = [f"{option_name}"]
if identifier is not None: if identifier is not None:
if not self.objectspace.paths.is_dynamic(variable.path):
msg = _("internal error, {0} is not a dynamic variable").format(
variable.path
)
raise DictConsistencyError(msg, 49, self.elt.xmlfiles)
param_type = "ParamDynOption" param_type = "ParamDynOption"
identifiers = [] identifiers = []
for ident in identifier: for ident in identifier:
@ -377,6 +384,8 @@ class Common:
ident = self.convert_str(ident) ident = self.convert_str(ident)
identifiers.append(str(ident)) identifiers.append(str(ident))
params.append("[" + ", ".join(identifiers) + "]") params.append("[" + ", ".join(identifiers) + "]")
if optional:
params.append("optional=True")
else: else:
param_type = "ParamOption" param_type = "ParamOption"
if not propertyerror: if not propertyerror:
@ -393,7 +402,7 @@ class Common:
kwargs = [] kwargs = []
if "params" in child: if "params" in child:
for key, value in child["params"].items(): for key, value in child["params"].items():
if not key: if key is None:
for val in value: for val in value:
new_args.append(self.populate_param(val)) new_args.append(self.populate_param(val))
else: else:

File diff suppressed because it is too large Load diff

247
src/rougail/user_datas.py Normal file
View file

@ -0,0 +1,247 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2022-2025
distribued with GPL-2 or later license
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
from typing import List
from re import findall
from tiramisu import undefined, Calculation
from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError, CancelParam
from .i18n import _
from .object_model import CONVERT_OPTION
class UserDatas:
def __init__(self, config) -> None:
self.config = config
def user_datas(self, user_datas: List[dict]):
self.values = {}
self.errors = []
self.warnings = []
self._populate_values(user_datas)
self._auto_configure_dynamics()
self._populate_config()
self._populate_error_warnings()
return {
"errors": self.errors,
"warnings": self.warnings,
}
def _populate_values(self, user_datas):
for datas in user_datas:
options = datas.get("options", {})
source = datas["source"]
for name, data in datas.get("values", {}).items():
self.values[name] = {
"source": source,
"values": data,
"options": options.copy(),
}
self.errors.extend(datas.get("errors", []))
self.warnings.extend(datas.get("warnings", []))
def _get_variable(self, config):
for subconfig in config:
if subconfig.isoptiondescription():
yield from self._get_variable(subconfig)
else:
yield subconfig
def _auto_configure_dynamics(self):
cache = {}
added = []
for path, data in list(self.values.items()):
value = data["values"]
try:
option = self.config.option(path)
option.name()
except (ConfigError, PropertiesOptionError):
pass
except AttributeError:
self._not_found_is_dynamic(self.config, path, cache, added)
def _not_found_is_dynamic(self, config, path, cache, added):
"""if path is not found, check if parent is a dynamic family"""
current_path = ""
identifiers = []
# get parent
for name in path.split(".")[:-1]:
if current_path:
current_path += "."
current_path += name
if current_path in cache:
config, identifier = cache[current_path]
identifiers.append(identifier)
continue
tconfig = config.option(name)
try:
tconfig.group_type()
# object exists, so current config is the temporary config
config = tconfig
if config.isdynamic(only_self=True):
identifiers.append(config.identifiers()[-1])
except AttributeError:
# try to found the good dynamic family
for tconfig in config.list(uncalculated=True):
if not tconfig.isdynamic(only_self=True):
# it's not a dynamic variable
continue
identifier = self._get_identifier(tconfig.name(), name)
if identifier is None:
# it's a dynamic variable but doesn't match the current name
continue
dynamic_variable = tconfig.information.get(
"dynamic_variable",
None,
)
if not dynamic_variable:
# it's the good dynamic variable but it's not linked to a variable
# so cannot change the variable
continue
option_type = self.config.option(dynamic_variable).information.get(
"type"
)
dyn_options_values = (
self.config.option(dynamic_variable).get().impl_getdefault()
)
if "{{ identifier }}" in dynamic_variable:
for s in identifiers:
dynamic_variable = dynamic_variable.replace(
"{{ identifier }}", str(s), 1
)
if dynamic_variable not in self.values and not dyn_options_values:
self.values[dynamic_variable] = {"values": []}
added.append(dynamic_variable)
elif dynamic_variable not in added:
continue
config = tconfig
identifiers.append(identifier)
typ = CONVERT_OPTION.get(option_type, {}).get("func")
if typ:
identifier = typ(identifier)
if identifier not in self.values[dynamic_variable]["values"]:
self.values[dynamic_variable]["values"].append(identifier)
cache[current_path] = config, identifier
break
def _populate_config(self):
while self.values:
value_is_set = False
for option in self._get_variable(self.config):
path = option.path()
if path not in self.values:
continue
options = self.values[path].get("options", {})
if options.get('allow_secrets_variables', True) is False and option.type() == 'password':
self.errors.append(_('the variable "{0}" contains secrets and should not be defined in {1}').format(path, self.values[path]["source"]))
continue
value = self.values[path]["values"]
needs_convert = options.get("needs_convert", False)
# converted value
if option.ismulti():
if options.get("multi_separator") and not isinstance(value, list):
value = value.split(options["multi_separator"])
self.values[path]["values"] = value
if option.issubmulti():
value = [[val] for val in value]
if needs_convert:
if option.issubmulti():
for idx, val in enumerate(value):
value[idx] = [convert_value(option, v) for v in val]
else:
value = [convert_value(option, val) for val in value]
self.values[path]["values"] = value
self.values[path]["options"]["needs_convert"] = False
elif needs_convert:
value = convert_value(option, value)
index = option.index()
if index is not None:
if not isinstance(value, list) or index >= len(value):
continue
value = value[index]
try:
option.value.set(value)
value_is_set = True
# value is correctly set, remove variable to the set
if index is not None:
# if it's a follower waiting for all followers are sets
self.values[path]["values"][index] = undefined
if set(self.values[path]["values"]) == {undefined}:
self.values.pop(path)
else:
self.values.pop(path)
except Exception:
if path != option.path():
self.values[option.path()] = self.values.pop(path)
if not value_is_set:
break
def _get_identifier(self, true_name, name) -> str:
if true_name == "{{ identifier }}":
return name
regexp = true_name.replace("{{ identifier }}", "(.*)")
finded = findall(regexp, name)
if len(finded) != 1 or not finded[0]:
return None
return finded[0]
def _populate_error_warnings(self):
# we don't find variable, apply value just to get error or warning messages
for path, data in self.values.items():
try:
option = self.config.option(path)
if option.isoptiondescription():
self.errors.warnings(
_('the option "{0}" is an option description').format(option.path())
)
continue
value = data["values"]
if option.isfollower():
for index, val in enumerate(value):
if val is undefined or isinstance(val, CancelParam):
continue
self.config.option(path, index).value.set(val)
else:
option.value.set(value)
except AttributeError as err:
self.warnings.append(str(err))
except (ValueError, LeadershipError) as err:
self.warnings.append(str(err))
except PropertiesOptionError as err:
self.warnings.append(str(err))
def convert_value(option, value):
if value == "":
return None
option_type = option.information.get("type")
if option_type == "choice":
choices = option.value.list()
if value not in choices and isinstance(value, str):
# FIXME add other tests (boolean, float, ...)
if value.isnumeric() and int(value) in choices:
value = int(value)
func = CONVERT_OPTION.get(option_type, {}).get("func")
if func:
return func(value)
return value

View file

@ -9,7 +9,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021 Copyright (C) 2019-2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -78,13 +78,10 @@ def load_modules(name, module) -> List[str]:
return eosfunc return eosfunc
def get_realpath( # def get_realpath(
path: str, # path: str,
path_prefix: str, # ) -> str:
) -> str: # return path
if path_prefix:
return f"{path_prefix}.{path}"
return path
def get_jinja_variable_to_param( def get_jinja_variable_to_param(
@ -93,7 +90,6 @@ def get_jinja_variable_to_param(
objectspace, objectspace,
xmlfiles, xmlfiles,
functions, functions,
path_prefix,
version, version,
namespace, namespace,
): ):
@ -118,6 +114,8 @@ def get_jinja_variable_to_param(
jinja_text, current_path, err jinja_text, current_path, err
) )
raise DictConsistencyError(msg, 39, xmlfiles) from err raise DictConsistencyError(msg, 39, xmlfiles) from err
except AttributeError:
pass
variables = list(variables) variables = list(variables)
variables.sort(reverse=True) variables.sort(reverse=True)
founded_variables = {} founded_variables = {}
@ -125,7 +123,6 @@ def get_jinja_variable_to_param(
for variable_path in variables: for variable_path in variables:
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
variable_path, variable_path,
path_prefix,
current_path, current_path,
version, version,
namespace, namespace,
@ -152,7 +149,6 @@ def get_jinja_variable_to_param(
vpath = vpath.rsplit(".", 1)[0] vpath = vpath.rsplit(".", 1)[0]
variable, identifier = objectspace.paths.get_with_dynamic( variable, identifier = objectspace.paths.get_with_dynamic(
vpath, vpath,
path_prefix,
current_path, current_path,
version, version,
namespace, namespace,

View file

@ -0,0 +1,8 @@
version: 1.1
file:
type: unix_filename
params:
allow_relative: true
default:
test/unknown_file

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,15 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
optiondescription_1 = OptionDescription(name="1", doc="1", children=[], properties=frozenset({"advanced"}))
optiondescription_2 = OptionDescription(name="2", doc="2", children=[], properties=frozenset({"advanced"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_2])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,3 +0,0 @@
---
_version: '1.1'
version: # a variable

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="version", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_6 = StrOption(name="version", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_6], properties=frozenset({"basic"}))
optiondescription_4 = OptionDescription(name="2", doc="2", children=[optiondescription_5], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_4])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,3 +0,0 @@
---
version: '1.0'
empty:

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="empty", doc="empty", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_6 = StrOption(name="empty", doc="empty", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_6], properties=frozenset({"basic"}))
optiondescription_4 = OptionDescription(name="2", doc="2", children=[optiondescription_5], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_4])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,10 +0,0 @@
---
version: 1.1
var1: "no" # a first variable
var2:
description: a second variable
multi: true
default:
jinja: |
{{ _.var1 }}
description: the value of var1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:
@ -12,6 +12,6 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_rougail.var2'] = "{{ _.var1 }}\n" dict_env['default_rougail.var2'] = "{{ _.var1 }}\n"
option_2 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_2 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.var2"), '_.var1': ParamOption(option_2, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_3 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_2default_calculated/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.var2"), '_.var1': ParamOption(option_2, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"})) optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -1,23 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_1.rougail.var2'] = "{{ _.var1 }}\n"
dict_env['default_2.rougail.var2'] = "{{ _.var1 }}\n"
option_3 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_4 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_1.rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("1.rougail.var2"), '_.var1': ParamOption(option_3, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_7 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_8 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_2.rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("2.rougail.var2"), '_.var1': ParamOption(option_7, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"standard"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,11 +2,11 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_var2'] = "{{ _.var1 }}\n" dict_env['default_var2'] = "{{ _.var1 }}\n"
option_1 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_1 = StrOption(name="var1", doc="a first variable", default="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("var2"), '_.var1': ParamOption(option_1, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_2 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_2default_calculated/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("var2"), '_.var1': ParamOption(option_1, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])

View file

@ -1,15 +0,0 @@
---
version: 1.1
var1: # a first variable
- 'no'
- 'yes'
- maybe
var2:
description: a second variable
multi: true
default:
jinja: |
{% for val in _.var1 %}
{{ val }}
{% endfor %}
description: the value of _.var1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:
@ -12,6 +12,6 @@ ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_rougail.var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n" dict_env['default_rougail.var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n"
option_2 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_2 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_3 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated_multi/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.var2"), '_.var1': ParamOption(option_2, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_3 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_2default_calculated_multi/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("rougail.var2"), '_.var1': ParamOption(option_2, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"})) optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -1,23 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_1.rougail.var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n"
dict_env['default_2.rougail.var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n"
option_3 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_4 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_1.rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated_multi/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("1.rougail.var2"), '_.var1': ParamOption(option_3, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_7 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_8 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_2.rougail.var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated_multi/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("2.rougail.var2"), '_.var1': ParamOption(option_7, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"standard"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,11 +2,11 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['default_var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n" dict_env['default_var2'] = "{% for val in _.var1 %}\n{{ val }}\n{% endfor %}\n"
option_1 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_1 = StrOption(name="var1", doc="a first variable", multi=True, default=["no", "yes", "maybe"], default_multi="no", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_2 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_2default_calculated_multi/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("var2"), '_.var1': ParamOption(option_1, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'}) option_2 = StrOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("default_var2"), '__internal_type': ParamValue("string"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_2default_calculated_multi/rougail/00-base.yml']), '__internal_attribute': ParamValue("default"), '__internal_variable': ParamValue("var2"), '_.var1': ParamOption(option_1, notraisepropertyerror=True)})), properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])

View file

@ -1,15 +0,0 @@
---
version: 1.1
var1:
description: a first variable
multi: true
type: domainname
params:
allow_ip: true
var2:
description: a second variable
default:
type: variable
variable: _.var1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:
@ -11,6 +11,6 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'}) option_2 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'})
option_3 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_2)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'}) option_3 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_2)), kwargs={'__internal_multi': ParamValue(True)})), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"basic"})) optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2, option_3], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -1,21 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'})
option_4 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_3)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_7 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'})
option_8 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_7)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"basic"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,10 +2,10 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
option_1 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'}) option_1 = DomainnameOption(name="var1", doc="a first variable", multi=True, type="domainname", allow_ip=True, properties=frozenset({"basic", "mandatory"}), informations={'type': 'domainname'})
option_2 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_1)))), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'}) option_2 = DomainnameOption(name="var2", doc="a second variable", multi=True, default=Calculation(func['calc_value'], Params((ParamOption(option_1)), kwargs={'__internal_multi': ParamValue(True)})), type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_2])

View file

@ -1,4 +0,0 @@
---
version: '1.0'
var1:
description: a variable

View file

@ -1,4 +0,0 @@
---
version: "1.0"
var2:
description: a variable

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,21 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="var1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_4 = StrOption(name="var2", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_7 = StrOption(name="var1", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
option_8 = StrOption(name="var2", doc="a variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'string'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"basic"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,5 +0,0 @@
---
version: '1.0'
without_type:
description: a variable
default: non

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="without_type", doc="a variable", default="non", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_6 = StrOption(name="without_type", doc="a variable", default="non", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, 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])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,18 +0,0 @@
---
version: '1.1'
var1: true # the first variable
var2:
description: the second variable
default: true
var3:
description: the third variable
type: boolean
default: true
var4: false # the forth variable
var5:
description: the fifth variable
default: false
var6:
description: the sixth variable
type: boolean
default: false

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,29 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = BoolOption(name="var1", doc="the first variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_4 = BoolOption(name="var2", doc="the second variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_5 = BoolOption(name="var3", doc="the third variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_6 = BoolOption(name="var4", doc="the forth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_7 = BoolOption(name="var5", doc="the fifth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_8 = BoolOption(name="var6", doc="the sixth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4, option_5, option_6, option_7, option_8], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_11 = BoolOption(name="var1", doc="the first variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_12 = BoolOption(name="var2", doc="the second variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_13 = BoolOption(name="var3", doc="the third variable", default=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_14 = BoolOption(name="var4", doc="the forth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_15 = BoolOption(name="var5", doc="the fifth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
option_16 = BoolOption(name="var6", doc="the sixth variable", default=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'boolean'})
optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_11, option_12, option_13, option_14, option_15, option_16], properties=frozenset({"standard"}))
optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_9])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,6 +0,0 @@
---
version: '1.1'
variable:
description: a variable
type: boolean
mandatory: false

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = BoolOption(name="variable", doc="a variable", default=True, properties=frozenset({"standard"}), informations={'type': 'boolean'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_6 = BoolOption(name="variable", doc="a variable", default=True, properties=frozenset({"standard"}), informations={'type': 'boolean'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, 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])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,42 +0,0 @@
---
version: '1.1'
var1:
description: the first variable
choices:
- a
- b
- c
var2:
description: the second variable
choices:
- a
- b
- c
var3:
description: the third variable
choices:
- a
- b
- c
mandatory: false
var4:
description: the forth variable
choices:
- null
- b
- c
mandatory: false
var5:
description: the fifth variable
choices:
- a
- b
- c
default: a
var6:
description: the sixth variable
choices:
- 1
- 2
- 3
default: 1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,29 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = ChoiceOption(name="var1", doc="the first variable", values=("a", "b", "c"), properties=frozenset({"basic", "mandatory"}), informations={'type': 'choice'})
option_4 = ChoiceOption(name="var2", doc="the second variable", values=("a", "b", "c"), properties=frozenset({"basic", "mandatory"}), informations={'type': 'choice'})
option_5 = ChoiceOption(name="var3", doc="the third variable", values=("a", "b", "c", None), properties=frozenset({"standard"}), informations={'type': 'choice'})
option_6 = ChoiceOption(name="var4", doc="the forth variable", values=(None, "b", "c"), properties=frozenset({"standard"}), informations={'type': 'choice'})
option_7 = ChoiceOption(name="var5", doc="the fifth variable", values=("a", "b", "c"), default="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
option_8 = ChoiceOption(name="var6", doc="the sixth variable", values=(1, 2, 3), default=1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4, option_5, option_6, option_7, option_8], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_11 = ChoiceOption(name="var1", doc="the first variable", values=("a", "b", "c"), properties=frozenset({"basic", "mandatory"}), informations={'type': 'choice'})
option_12 = ChoiceOption(name="var2", doc="the second variable", values=("a", "b", "c"), properties=frozenset({"basic", "mandatory"}), informations={'type': 'choice'})
option_13 = ChoiceOption(name="var3", doc="the third variable", values=("a", "b", "c", None), properties=frozenset({"standard"}), informations={'type': 'choice'})
option_14 = ChoiceOption(name="var4", doc="the forth variable", values=(None, "b", "c"), properties=frozenset({"standard"}), informations={'type': 'choice'})
option_15 = ChoiceOption(name="var5", doc="the fifth variable", values=("a", "b", "c"), default="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
option_16 = ChoiceOption(name="var6", doc="the sixth variable", values=(1, 2, 3), default=1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_11, option_12, option_13, option_14, option_15, option_16], properties=frozenset({"basic"}))
optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_9])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,12 +0,0 @@
---
version: 1.1
var:
description: a variable
default: 9
choices:
jinja: |
{% for n in trange(0, 10) %}
{{ n }}
{% endfor %}
return_type: 'number'
description: choices is 0 to 9

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:
@ -11,6 +11,6 @@ ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['choices_rougail.var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n" dict_env['choices_rougail.var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n"
option_2 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_rougail.var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_6choice_calculation/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("rougail.var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'}) option_2 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_rougail.var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_6choice_calculation/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("rougail.var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_2], properties=frozenset({"standard"})) 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]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -1,21 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['choices_1.rougail.var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n"
dict_env['choices_2.rougail.var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n"
option_3 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_1.rougail.var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_6choice_calculation/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("1.rougail.var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_6 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_2.rougail.var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_6choice_calculation/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("2.rougail.var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, 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])

View file

@ -2,10 +2,10 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")
dict_env['choices_var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n" dict_env['choices_var'] = "{% for n in trange(0, 10) %}\n{{ n }}\n{% endfor %}\n"
option_1 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['tests/dictionaries/00_6choice_calculation/dictionaries/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'}) option_1 = ChoiceOption(name="var", doc="a variable", values=Calculation(func['jinja_to_function'], Params((), kwargs={'__internal_jinja': ParamValue("choices_var"), '__internal_type': ParamValue("number"), '__internal_multi': ParamValue(True), '__internal_files': ParamValue(['../rougail-tests/structures/00_6choice_calculation/rougail/00-base.yml']), '__internal_attribute': ParamValue("choices"), '__internal_variable': ParamValue("var")})), default=9, properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1])

View file

@ -1,11 +0,0 @@
---
version: '1.1'
var1: # a second variable
- a
- b
- c
var2:
description: a first variable
default: a
choices:
variable: _.var1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,21 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="var1", doc="a second variable", multi=True, default=["a", "b", "c"], default_multi="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_4 = ChoiceOption(name="var2", doc="a first variable", values=Calculation(func['calc_value'], Params((ParamOption(option_3)))), default="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_7 = StrOption(name="var1", doc="a second variable", multi=True, default=["a", "b", "c"], default_multi="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'string'})
option_8 = ChoiceOption(name="var2", doc="a first variable", values=Calculation(func['calc_value'], Params((ParamOption(option_7)))), default="a", properties=frozenset({"mandatory", "standard"}), informations={'type': 'choice'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"standard"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,9 +0,0 @@
---
version: '1.1'
custom1:
description: the first variable
type: custom
custom2:
description: the seconf variable
type: custom
default: value

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,21 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = CustomOption(name="custom1", doc="the first variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'custom'})
option_4 = CustomOption(name="custom2", doc="the seconf variable", default="value", properties=frozenset({"mandatory", "standard"}), informations={'type': 'custom'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4], properties=frozenset({"basic"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"basic"}))
option_7 = CustomOption(name="custom1", doc="the first variable", properties=frozenset({"basic", "mandatory"}), informations={'type': 'custom'})
option_8 = CustomOption(name="custom2", doc="the seconf variable", default="value", properties=frozenset({"mandatory", "standard"}), informations={'type': 'custom'})
optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_7, option_8], properties=frozenset({"basic"}))
optiondescription_5 = OptionDescription(name="2", doc="2", children=[optiondescription_6], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_5])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,6 +0,0 @@
---
version: '1.1'
variable:
description: a domain name variable
type: domainname
default: my.domain.name

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = DomainnameOption(name="variable", doc="a domain name variable", default="my.domain.name", type="domainname", allow_ip=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_6 = DomainnameOption(name="variable", doc="a domain name variable", default="my.domain.name", type="domainname", allow_ip=False, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, 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])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,8 +0,0 @@
---
version: '1.1'
variable:
description: a domain name variable
type: domainname
default: my.domain.name
params:
allow_ip: true

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,19 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = DomainnameOption(name="variable", doc="a domain name variable", default="my.domain.name", type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_6 = DomainnameOption(name="variable", doc="a domain name variable", default="my.domain.name", type="domainname", allow_ip=True, properties=frozenset({"mandatory", "standard"}), informations={'type': 'domainname'})
optiondescription_5 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, 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])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,18 +0,0 @@
---
version: '1.1'
var1: 0.0 # the first variable
var2:
description: the second variable
default: 0.0
var3:
description: the third variable
type: float
default: 0.0
var4: 10.1 # the forth variable
var5:
description: the fifth variable
default: 10.1
var6:
description: the sixth variable
type: float
default: 10.1

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,29 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = FloatOption(name="var1", doc="the first variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_4 = FloatOption(name="var2", doc="the second variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_5 = FloatOption(name="var3", doc="the third variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_6 = FloatOption(name="var4", doc="the forth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_7 = FloatOption(name="var5", doc="the fifth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_8 = FloatOption(name="var6", doc="the sixth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4, option_5, option_6, option_7, option_8], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_11 = FloatOption(name="var1", doc="the first variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_12 = FloatOption(name="var2", doc="the second variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_13 = FloatOption(name="var3", doc="the third variable", default=0.0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_14 = FloatOption(name="var4", doc="the forth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_15 = FloatOption(name="var5", doc="the fifth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
option_16 = FloatOption(name="var6", doc="the sixth variable", default=10.1, properties=frozenset({"mandatory", "standard"}), informations={'type': 'float'})
optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_11, option_12, option_13, option_14, option_15, option_16], properties=frozenset({"standard"}))
optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_9])

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic") ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard") ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced") ALLOWED_LEADER_PROPERTIES.add("advanced")

View file

@ -1,18 +0,0 @@
---
version: '1.1'
var1: 0 # the first variable
var2:
description: the second variable
default: 0
var3:
description: the third variable
type: number
default: 0
var4: 10 # this forth variable
var5:
description: the fifth variable
default: 10
var6:
description: the sixth variable
type: number
default: 10

View file

@ -2,7 +2,7 @@ from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('tests/dictionaries/../eosfunc/test.py') load_functions('../rougail-tests/funcs/test.py')
try: try:
groups.namespace groups.namespace
except: except:

View file

@ -1,29 +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
load_functions('tests/dictionaries/../eosfunc/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = IntOption(name="var1", doc="the first variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_4 = IntOption(name="var2", doc="the second variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_5 = IntOption(name="var3", doc="the third variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_6 = IntOption(name="var4", doc="this forth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_7 = IntOption(name="var5", doc="the fifth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_8 = IntOption(name="var6", doc="the sixth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
optiondescription_2 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_3, option_4, option_5, option_6, option_7, option_8], properties=frozenset({"standard"}))
optiondescription_1 = OptionDescription(name="1", doc="1", children=[optiondescription_2], properties=frozenset({"standard"}))
option_11 = IntOption(name="var1", doc="the first variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_12 = IntOption(name="var2", doc="the second variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_13 = IntOption(name="var3", doc="the third variable", default=0, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_14 = IntOption(name="var4", doc="this forth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_15 = IntOption(name="var5", doc="the fifth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
option_16 = IntOption(name="var6", doc="the sixth variable", default=10, properties=frozenset({"mandatory", "standard"}), informations={'type': 'number'})
optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[option_11, option_12, option_13, option_14, option_15, option_16], properties=frozenset({"standard"}))
optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10], properties=frozenset({"standard"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_9])

Some files were not shown because too many files have changed in this diff Show more