Compare commits

..

3 commits

Author SHA1 Message Date
fecab8aca6 bump: version 1.2.0a23 → 1.2.0a24 2025-05-12 09:13:57 +02:00
97cc2460b2 fix: upgrade translation 2025-05-12 08:52:59 +02:00
5a4bb343b0 fix: black 2025-05-12 08:45:39 +02:00
37 changed files with 855 additions and 276 deletions

View file

@ -1,3 +1,10 @@
## 1.2.0a24 (2025-05-12)
### Fix
- upgrade translation
- black
## 1.2.0a23 (2025-05-09)
### Fix

View file

@ -5,8 +5,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2025-05-08 21:35+0200\n"
"PO-Revision-Date: 2025-05-08 21:37+0200\n"
"POT-Creation-Date: 2025-05-12 08:45+0200\n"
"PO-Revision-Date: 2025-05-12 08:52+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
@ -16,31 +16,31 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.5\n"
#: src/rougail/annotator/family.py:152
#: src/rougail/annotator/family.py:150
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
"le mode d'une variable par défaut \"{0}\" n'est pas un mode valide, les "
"modes valides sont {1}"
#: src/rougail/annotator/family.py:158
#: src/rougail/annotator/family.py:156
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
"le mode d'une famille par défaut \"{0}\" n'est pas un mode valide, les modes "
"valides sont {1}"
#: src/rougail/annotator/family.py:190
#: src/rougail/annotator/family.py:188
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, les modes valides "
"sont {2}"
#: src/rougail/annotator/family.py:194
#: src/rougail/annotator/family.py:192
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr ""
"le mode \"{0}\" pour \"{1}\" n'est pas un mode valide, aucun mode ne sont "
"définis"
#: src/rougail/annotator/family.py:258
#: src/rougail/annotator/family.py:256
msgid ""
"the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the "
"higher family mode \"{2}\""
@ -48,7 +48,7 @@ msgstr ""
"la variable \"{0}\" est obligatoire, donc en mode \"{1}\", mais la famille a "
"un mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:296
#: src/rougail/annotator/family.py:294
msgid ""
"the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode "
"\"{2}\""
@ -56,7 +56,7 @@ msgstr ""
"la variable suiveuse \"{0}\" a le mode \"{1}\" mais la variable leader a un "
"mode supérieur \"{2}\""
#: src/rougail/annotator/family.py:329
#: src/rougail/annotator/family.py:327
msgid ""
"the family \"{0}\" is in \"{1}\" mode but variables and families inside have "
"the higher modes \"{2}\""
@ -64,7 +64,7 @@ msgstr ""
"la famille \"{0}\" a le mode \"{1}\" mais les variables et les familles à "
"l'intérieur ont des modes supérieurs \"{2}\""
#: src/rougail/annotator/family.py:347
#: src/rougail/annotator/family.py:345
msgid ""
"the variable \"{0}\" is in \"{1}\" mode but family has the higher family "
"mode \"{2}\""
@ -89,7 +89,7 @@ msgstr ""
msgid "the variable \"{0}\" is a \"choice\" variable but don't have any choice"
msgstr "la variable \"{0}\" a une variable à \"choix\" mais n'a aucun choix"
#: src/rougail/annotator/value.py:135
#: src/rougail/annotator/value.py:137
msgid "the variable \"{0}\" is a \"regexp\" variable but don't have any regexp"
msgstr ""
"la variable \"{0}\" a une variable \"regexp\" mais n'a pas de \"regexp\""
@ -102,14 +102,14 @@ msgstr ""
"seul une variable de type \"unix_user\" ou \"secret\" peut avoir l'attribut "
"\"secret_manager\", mais \"{0}\" a le type \"{1}\""
#: src/rougail/annotator/variable.py:89
#: src/rougail/annotator/variable.py:93
msgid ""
"the variable \"{0}\" has attribute \"secret_manager\" but is a multi variable"
msgstr ""
"la variable \"{0}\" a l'attribut \"secret_manager\" mais est une variable "
"multiple"
#: src/rougail/annotator/variable.py:92
#: src/rougail/annotator/variable.py:98
msgid ""
"the variable \"{0}\" has attribute \"secret_manager\" so must not have "
"default value"
@ -117,19 +117,19 @@ msgstr ""
"la variable \"{0}\" a l'attribut \"secret_manager\" donc ne devrait pas "
"avoir de valeur par défaut"
#: src/rougail/annotator/variable.py:202
#: src/rougail/annotator/variable.py:227
msgid ""
"the variable \"{0}\" has regexp attribut but has not the \"regexp\" type"
msgstr ""
"la variable \"{0}\" a un attribut regexp mais n'a pas le type \"regexp\""
#: src/rougail/annotator/variable.py:245
#: src/rougail/annotator/variable.py:270
msgid ""
"the variable \"{0}\" has choices attribut but has not the \"choice\" type"
msgstr ""
"la variable \"{0}\" a un attribut choices mais n'a pas le type \"choice\""
#: src/rougail/annotator/variable.py:273
#: src/rougail/annotator/variable.py:298
msgid ""
"the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}"
msgstr ""
@ -203,11 +203,11 @@ msgstr "Le patron est au format Jinja"
msgid "Select for {0}"
msgstr "Sélection pour {0}"
#: src/rougail/config.py:457
#: src/rougail/config.py:458
msgid "Override default parameters for option type"
msgstr "Sur charger les paramètre par défaut pour le type d'option"
#: src/rougail/config.py:460
#: src/rougail/config.py:461
msgid "Default parameters for option type"
msgstr "Paramètre par défaut pour le type d'option"
@ -219,19 +219,19 @@ msgstr "type {0} inconnu pour {1}"
msgid "family \"{0}\" define multiple time"
msgstr "la famille \"{0}\" est définit plusieurs fois"
#: src/rougail/convert.py:667
#: src/rougail/convert.py:668
msgid "variable \"{0}\" define multiple time"
msgstr "la variable \"{0}\" est définit plusieurs fois"
#: src/rougail/convert.py:767
#: src/rougail/convert.py:766
msgid "params must be a dict for {0}"
msgstr "params doit être une dict pour {0}"
#: src/rougail/convert.py:788
#: src/rougail/convert.py:787
msgid "\"{0}\" has an invalid \"params\" for {1}: {2}"
msgstr "\"{0}\" a un attribut \"params\" invalide pour {1}: {2}"
#: src/rougail/convert.py:802
#: src/rougail/convert.py:801
msgid "secret_manager must be a dict for {0}"
msgstr "secret_manager doit être une dict pour {0}"
@ -246,8 +246,8 @@ msgstr ""
"définition invalide pour la définition des \"structures\" ({0}), aucun "
"fichier de structure ne peut être chargé !"
#: src/rougail/error.py:67 src/rougail/tiramisu.py:50
#: src/rougail/user_datas.py:253
#: src/rougail/error.py:67 src/rougail/tiramisu.py:60
#: src/rougail/user_datas.py:354 src/rougail/user_datas.py:357
msgid "{0} in {1}"
msgstr "{0} dans {1}"
@ -255,41 +255,41 @@ msgstr "{0} dans {1}"
msgid "unknown boolean value \"{0}\""
msgstr "valeur du booléen inconnue \"{0}\""
#: src/rougail/object_model.py:181
#: src/rougail/object_model.py:187
msgid "cannot find variable \"{0}\" defined in attribute \"{1}\" for \"{2}\""
msgstr ""
"ne peut trouver la variable \"{0}\" défini dans l'attribut \"{1}\" pour "
"\"{2}\""
#: src/rougail/object_model.py:185
#: src/rougail/object_model.py:193
msgid ""
"the variable \"{0}\" is in fact a family in attribute \"{1}\" for \"{2}\""
msgstr ""
"la variable \"{0}\" est en faite une famille dans l'attribut \"{1}\" pour "
"\"{2}\""
#: src/rougail/object_model.py:188 src/rougail/object_model.py:478
#: src/rougail/object_model.py:198 src/rougail/object_model.py:525
msgid "unknown object \"{0}\" in attribute \"{1}\" for \"{2}\""
msgstr "objet inconnu \"{0}\" dans l'attribut \"{1}\" pour \"{2}\""
#: src/rougail/object_model.py:205
#: src/rougail/object_model.py:217
msgid ""
"identifier parameter for \"{0}\" in \"{1}\" cannot be set none dynamic family"
msgstr ""
"le paramètre identifier pour \"{0}\" dans \"{1}\" ne peut être placé pour "
"une famille non dynamique"
#: src/rougail/object_model.py:228
#: src/rougail/object_model.py:246
msgid "cannot find variable \"{0}\" defined in \"{1}\" for \"{2}\""
msgstr "ne peut trouver la variable \"{0}\" défini dans \"{1}\" pour \"{2}\""
#: src/rougail/object_model.py:231
#: src/rougail/object_model.py:251
msgid "variable \"{0}\" defined in \"{1}\" for \"{2}\" is a dynamic variable"
msgstr ""
"la variable \"{0}\" défini dans \"{1}\" pour \"{2}\" est une variable "
"dynamique"
#: src/rougail/object_model.py:242
#: src/rougail/object_model.py:268
msgid ""
"the variable \"{0}\" is not a follower, so cannot have index type for param "
"in \"{1}\""
@ -297,7 +297,7 @@ msgstr ""
"la variable \"{0}\" n'est pas suiveuse, donc ne peut avoir de type index "
"comme paramètre dans \"{1}\""
#: src/rougail/object_model.py:475
#: src/rougail/object_model.py:520
msgid ""
"a variable \"{0}\" is needs in attribute \"{1}\" for \"{2}\" but it's a "
"family"
@ -305,7 +305,7 @@ msgstr ""
"une variable \"{0}\" est nécessaire pour l'attribut \"{1}\" pour \"{2}\" "
"mais c'est une famille"
#: src/rougail/object_model.py:495
#: src/rougail/object_model.py:544
msgid ""
"variable \"{0}\" has an attribute \"{1}\" calculated with the unknown "
"variable \"{2}\""
@ -313,7 +313,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\" calculé avec la variable "
"inconnue \"{2}\""
#: src/rougail/object_model.py:531
#: src/rougail/object_model.py:593
msgid ""
"the variable \"{0}\" has an invalid \"{1}\" the variable \"{2}\" is in a sub "
"dynamic option"
@ -321,14 +321,14 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", la variable \"{2}\" est "
"dans une sous option dynamique"
#: src/rougail/object_model.py:534
#: src/rougail/object_model.py:602
msgid ""
"the leader \"{0}\" has an invalid \"{1}\" the follower \"{2}\" is a multi"
msgstr ""
"la variable meneuse \"{0}\" a un attribut invalide \"{1}\", la variable "
"suiveuse \"{2}\" est multiple"
#: src/rougail/object_model.py:550
#: src/rougail/object_model.py:644
msgid ""
"the variable \"{0}\" has an invalid attribute \"{1}\", the variable \"{2}\" "
"must not be multi"
@ -336,7 +336,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", la variable \"{2}\" ne "
"doit pas être multiple"
#: src/rougail/object_model.py:555
#: src/rougail/object_model.py:658
msgid ""
"the variable \"{0}\" has an invalid attribute \"{1}\", the variable must not "
"be a multi or the variable \"{2}\" must be multi"
@ -344,7 +344,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", la variable ne doit pas "
"être multiple ou la variable \"{2}\" doit être multiple"
#: src/rougail/object_model.py:560
#: src/rougail/object_model.py:672
msgid ""
"the variable \"{0}\" has an invalid attribute \"{1}\", the variable must be "
"a multi or the variable \"{2}\" must not be multi"
@ -352,7 +352,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", la variable doit être "
"multiple ou la variable \"{2}\" ne doit pas être multiple"
#: src/rougail/object_model.py:565
#: src/rougail/object_model.py:686
msgid ""
"the variable \"{0}\" has an invalid attribute \"{1}\", the variable \"{2}\" "
"is multi but is inside a list"
@ -360,7 +360,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", la variable \"{2}\" est "
"multiple mais est dans une liste"
#: src/rougail/object_model.py:579
#: src/rougail/object_model.py:704
msgid ""
"\"{0}\" attribut shall not have an \"optional\" attribute for variable "
"\"{1}\""
@ -368,7 +368,7 @@ msgstr ""
"l'attribut \"{0}\" ne devrait pas avoir d'attribut \"optional\" pour la "
"variable \"{1}\""
#: src/rougail/object_model.py:591
#: src/rougail/object_model.py:724
msgid ""
"variable \"{0}\" has a default value calculated with \"{1}\" which has "
"incompatible type"
@ -376,7 +376,7 @@ msgstr ""
"la variable \"{0}\" a une valeur par défaut calculé a partir de \"{1}\" "
"laquelle a un type incompatible"
#: src/rougail/object_model.py:629
#: src/rougail/object_model.py:770
msgid ""
"\"when\" is not allowed in format version 1.0 for attribute \"{0}\" for "
"variable \"{1}\""
@ -384,7 +384,7 @@ msgstr ""
"\"when\" n'est pas autorisé avec le format en version 1.0 pour l'attribut "
"\"{0}\" pour la variable \"{1}\""
#: src/rougail/object_model.py:632
#: src/rougail/object_model.py:775
msgid ""
"the variable \"{0}\" has an invalid attribute \"{1}\", \"when\" and "
"\"when_not\" cannot set together"
@ -392,7 +392,7 @@ msgstr ""
"la variable \"{0}\" a un attribut invalide \"{1}\", \"when\" et \"when_not\" "
"ne peuvent pas être défini ensemble"
#: src/rougail/object_model.py:638
#: src/rougail/object_model.py:783
msgid ""
"\"when_not\" is not allowed in format version 1.0 for attribute \"{0}\" for "
"variable \"{1}\""
@ -400,7 +400,7 @@ msgstr ""
"\"when_not\" n'est pas autorisé au format 1.0 pour l'attribut \"{0}\" pour "
"la variable variable \"{1}\""
#: src/rougail/object_model.py:693
#: src/rougail/object_model.py:840
msgid ""
"cannot find variable \"{0}\" for the information \"{1}\" when calculating "
"\"{2}\""
@ -408,18 +408,18 @@ msgstr ""
"ne peut trouver la variable \"{0}\" pour l'information \"{1}\" lors du "
"calcul de \"{2}\""
#: src/rougail/object_model.py:696
#: src/rougail/object_model.py:845
msgid ""
"identifier not allowed for the information \"{0}\" when calculating \"{1}\""
msgstr ""
"identifier n'est pas autorisé pour l'information \"{0}\" lors du calcul de "
"\"{1}\""
#: src/rougail/object_model.py:747
#: src/rougail/object_model.py:898
msgid "\"when\" is not allowed in format version 1.0 for attribute \"{0}\""
msgstr "\"when\" n'est pas autorisé au format 1.0 pour l'attribut \"{0}\""
#: src/rougail/object_model.py:751 src/rougail/object_model.py:759
#: src/rougail/object_model.py:904 src/rougail/object_model.py:914
msgid ""
"the identifier has an invalid attribute \"{0}\", \"when\" and \"when_not\" "
"cannot set together"
@ -427,7 +427,7 @@ msgstr ""
"l'identifiant a un attribut invalide \"{0}\", \"when\" et \"when_not\" ne "
"peuvent pas être défini ensemble"
#: src/rougail/object_model.py:782
#: src/rougail/object_model.py:939
msgid ""
"the variable \"{0}\" is not a follower, so cannot have index type for \"{1}\""
msgstr ""
@ -480,7 +480,7 @@ msgstr ""
"Répertoires où sont placés les fichiers de structure de l'espace de nom "
"supplémentaire"
#: src/rougail/tiramisu.py:175
#: src/rougail/tiramisu.py:187
msgid ""
"cannot calculating \"{0}\" attribute for variable \"{1}\" in {2} with "
"parameters \"{3}\": {4}"
@ -488,34 +488,95 @@ msgstr ""
"ne peut calculer l'attribut \"{0}\" pour la variable \"{1}\" dans {2} avec "
"les paramètres \"{3}\" : {4}"
#: src/rougail/tiramisureflector.py:364
#: src/rougail/tiramisureflector.py:363
msgid "internal error, {0} is not a dynamic variable"
msgstr "erreur interne, \"{0}\" n'est pas une variable dynamique"
#: src/rougail/user_datas.py:116
#: src/rougail/user_datas.py:118
msgid ""
"cannot load variable path \"{0}\", the identifier \"{1}\" is not valid in {2}"
msgstr ""
"ne peut charger la variable \"{0}\", l'identifiant \"{1}\" n'est pas valide "
"dans {2}"
#: src/rougail/user_datas.py:171
#: src/rougail/user_datas.py:196
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:236
msgid ""
"the variable \"{0}\" is a family, so cannot set the value \"{1}\" in {2}"
msgstr ""
"la variable \"{0}\" est une famille, donc ne peut avoir l'avoir \"{1}\" dans "
"{2}"
#: src/rougail/user_datas.py:218
msgid "loaded from {0}"
msgstr "chargée depuis {0}"
#: src/rougail/user_datas.py:251
#: src/rougail/user_datas.py:258
msgid ""
"cannot set the value \"{0}\" to the family {1}, it will be ignored when "
"loading from {2}"
msgstr ""
"impossible de définir la valeur \"{0}\" à la famille {1}, elle sera ignorée "
"lors du chargement depuis {0}"
#: src/rougail/user_datas.py:270
msgid ""
"variable or family \"{0}\" does not exist, it will be ignored when loading "
"from {1}"
msgstr ""
"la variable ou la famille \"{0}\" n'existe pas, elle sera ignorée lors du "
"chargement depuis {1}"
#: src/rougail/user_datas.py:276
msgid ""
"\"{0}\" is the name of a dynamic family, it will be ignored when loading "
"from {1}"
msgstr ""
"\"{0}\" est le nom d'une famille dynamique, il sera ignoré lors du "
"chargement depuis {1}"
#: src/rougail/user_datas.py:282
msgid "{0} loaded from {1}"
msgstr "{0} chargée depuis {1}"
#: src/rougail/user_datas.py:311
msgid ""
"variable {0} at index \"{1}\" is {2}, it will be ignored when loading from "
"{3}"
msgstr ""
"la variable {0} à l'index \"{1}\" est {2}, elle sera ignorée lors du "
"chargement depuis {3}"
#: src/rougail/user_datas.py:322
msgid ""
"family {0} is {1}, {2} at index \"{3}\" will be ignored when loading from {4}"
msgstr ""
"la famille {0} est {1}, {2} à l'index \"{3}\" sera ignorée lors du "
"chargement depuis {4}"
#: src/rougail/user_datas.py:335
msgid "variable {0} is {1}, it will be ignored when loading from {2}"
msgstr ""
"la variable {0} est {1}, elle sera ignorée lors du chargement depuis {2}"
#: src/rougail/user_datas.py:343
msgid "family {0} is {1}, {2} will be ignored when loading from {3}"
msgstr "la famille {0} est {1}, {2} sera ignorée lors du chargement depuis {3}"
#: src/rougail/user_datas.py:362
msgid ""
"the value \"{0}\" is invalid for {1} at index \"{2}\", {3}, it will be "
"ignored when loading from {4}"
msgstr ""
"la valeur \"{0}\" n'est pas valide pour {1} à l'index \"{2}\", {3}, elle "
"sera ignorée lors du chargement depuis {4}"
#: src/rougail/user_datas.py:373
msgid ""
"the value \"{0}\" is invalid for {1}, {2}, it will be ignored when loading "
"from {3}"
msgstr ""
"la valeur \"{0}\" n'est pas valide pour {1}, {2}, elle sera ignorée lors du "
"chargement depuis {3}"
#: src/rougail/utils.py:55
msgid ""
"invalid variable or family name \"{0}\" must only contains lowercase ascii "
@ -528,6 +589,12 @@ msgstr ""
msgid "error in jinja \"{0}\" for the variable \"{1}\": {2}"
msgstr "erreur dans Jinja \"{0}\" pour la variable \"{1}\": {2}"
#~ msgid ""
#~ "the variable \"{0}\" is a family, so cannot set the value \"{1}\" in {2}"
#~ msgstr ""
#~ "la variable \"{0}\" est une famille, donc ne peut avoir l'avoir \"{1}\" "
#~ "dans {2}"
#~ msgid "the follower \"{0}\" without multi attribute can only have one value"
#~ msgstr ""
#~ "la variable suiveuse \"{0}\" sans l'attribut multi peut avoir seulement "

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-05-08 21:37+0200\n"
"POT-Creation-Date: 2025-05-12 08:52+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,35 +15,35 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: src/rougail/annotator/family.py:152
#: src/rougail/annotator/family.py:150
msgid "default variable mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
#: src/rougail/annotator/family.py:158
#: src/rougail/annotator/family.py:156
msgid "default family mode \"{0}\" is not a valid mode, valid modes are {1}"
msgstr ""
#: src/rougail/annotator/family.py:190
#: src/rougail/annotator/family.py:188
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, valid modes are {2}"
msgstr ""
#: src/rougail/annotator/family.py:194
#: src/rougail/annotator/family.py:192
msgid "mode \"{0}\" for \"{1}\" is not a valid mode, no modes are available"
msgstr ""
#: src/rougail/annotator/family.py:258
#: src/rougail/annotator/family.py:256
msgid "the variable \"{0}\" is mandatory so in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:296
#: src/rougail/annotator/family.py:294
msgid "the follower \"{0}\" is in \"{1}\" mode but leader have the higher mode \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:329
#: src/rougail/annotator/family.py:327
msgid "the family \"{0}\" is in \"{1}\" mode but variables and families inside have the higher modes \"{2}\""
msgstr ""
#: src/rougail/annotator/family.py:347
#: src/rougail/annotator/family.py:345
msgid "the variable \"{0}\" is in \"{1}\" mode but family has the higher family mode \"{2}\""
msgstr ""
@ -59,7 +59,7 @@ msgstr ""
msgid "the variable \"{0}\" is a \"choice\" variable but don't have any choice"
msgstr ""
#: src/rougail/annotator/value.py:135
#: src/rougail/annotator/value.py:137
msgid "the variable \"{0}\" is a \"regexp\" variable but don't have any regexp"
msgstr ""
@ -67,23 +67,23 @@ msgstr ""
msgid "only \"unix_user\" or \"secret\" variable type can have \"secret_manager\" attribute, but \"{0}\" has type \"{1}\""
msgstr ""
#: src/rougail/annotator/variable.py:89
#: src/rougail/annotator/variable.py:93
msgid "the variable \"{0}\" has attribute \"secret_manager\" but is a multi variable"
msgstr ""
#: src/rougail/annotator/variable.py:92
#: src/rougail/annotator/variable.py:98
msgid "the variable \"{0}\" has attribute \"secret_manager\" so must not have default value"
msgstr ""
#: src/rougail/annotator/variable.py:202
#: src/rougail/annotator/variable.py:227
msgid "the variable \"{0}\" has regexp attribut but has not the \"regexp\" type"
msgstr ""
#: src/rougail/annotator/variable.py:245
#: src/rougail/annotator/variable.py:270
msgid "the variable \"{0}\" has choices attribut but has not the \"choice\" type"
msgstr ""
#: src/rougail/annotator/variable.py:273
#: src/rougail/annotator/variable.py:298
msgid "the variable \"{0}\" has an unvalid default value \"{1}\" should be in {2}"
msgstr ""
@ -151,11 +151,11 @@ msgstr ""
msgid "Select for {0}"
msgstr ""
#: src/rougail/config.py:457
#: src/rougail/config.py:458
msgid "Override default parameters for option type"
msgstr ""
#: src/rougail/config.py:460
#: src/rougail/config.py:461
msgid "Default parameters for option type"
msgstr ""
@ -167,19 +167,19 @@ msgstr ""
msgid "family \"{0}\" define multiple time"
msgstr ""
#: src/rougail/convert.py:667
#: src/rougail/convert.py:668
msgid "variable \"{0}\" define multiple time"
msgstr ""
#: src/rougail/convert.py:767
#: src/rougail/convert.py:766
msgid "params must be a dict for {0}"
msgstr ""
#: src/rougail/convert.py:788
#: src/rougail/convert.py:787
msgid "\"{0}\" has an invalid \"params\" for {1}: {2}"
msgstr ""
#: src/rougail/convert.py:802
#: src/rougail/convert.py:801
msgid "secret_manager must be a dict for {0}"
msgstr ""
@ -191,8 +191,8 @@ msgstr ""
msgid "invalid \"structural\" definition ({0}), we cannot load any structural file!"
msgstr ""
#: src/rougail/error.py:67 src/rougail/tiramisu.py:50
#: src/rougail/user_datas.py:253
#: src/rougail/error.py:67 src/rougail/tiramisu.py:60
#: src/rougail/user_datas.py:354 src/rougail/user_datas.py:357
msgid "{0} in {1}"
msgstr ""
@ -200,103 +200,103 @@ msgstr ""
msgid "unknown boolean value \"{0}\""
msgstr ""
#: src/rougail/object_model.py:181
#: src/rougail/object_model.py:187
msgid "cannot find variable \"{0}\" defined in attribute \"{1}\" for \"{2}\""
msgstr ""
#: src/rougail/object_model.py:185
#: src/rougail/object_model.py:193
msgid "the variable \"{0}\" is in fact a family in attribute \"{1}\" for \"{2}\""
msgstr ""
#: src/rougail/object_model.py:188 src/rougail/object_model.py:478
#: src/rougail/object_model.py:198 src/rougail/object_model.py:525
msgid "unknown object \"{0}\" in attribute \"{1}\" for \"{2}\""
msgstr ""
#: src/rougail/object_model.py:205
#: src/rougail/object_model.py:217
msgid "identifier parameter for \"{0}\" in \"{1}\" cannot be set none dynamic family"
msgstr ""
#: src/rougail/object_model.py:228
#: src/rougail/object_model.py:246
msgid "cannot find variable \"{0}\" defined in \"{1}\" for \"{2}\""
msgstr ""
#: src/rougail/object_model.py:231
#: src/rougail/object_model.py:251
msgid "variable \"{0}\" defined in \"{1}\" for \"{2}\" is a dynamic variable"
msgstr ""
#: src/rougail/object_model.py:242
#: src/rougail/object_model.py:268
msgid "the variable \"{0}\" is not a follower, so cannot have index type for param in \"{1}\""
msgstr ""
#: src/rougail/object_model.py:475
#: src/rougail/object_model.py:520
msgid "a variable \"{0}\" is needs in attribute \"{1}\" for \"{2}\" but it's a family"
msgstr ""
#: src/rougail/object_model.py:495
#: src/rougail/object_model.py:544
msgid "variable \"{0}\" has an attribute \"{1}\" calculated with the unknown variable \"{2}\""
msgstr ""
#: src/rougail/object_model.py:531
#: src/rougail/object_model.py:593
msgid "the variable \"{0}\" has an invalid \"{1}\" the variable \"{2}\" is in a sub dynamic option"
msgstr ""
#: src/rougail/object_model.py:534
#: src/rougail/object_model.py:602
msgid "the leader \"{0}\" has an invalid \"{1}\" the follower \"{2}\" is a multi"
msgstr ""
#: src/rougail/object_model.py:550
#: src/rougail/object_model.py:644
msgid "the variable \"{0}\" has an invalid attribute \"{1}\", the variable \"{2}\" must not be multi"
msgstr ""
#: src/rougail/object_model.py:555
#: src/rougail/object_model.py:658
msgid "the variable \"{0}\" has an invalid attribute \"{1}\", the variable must not be a multi or the variable \"{2}\" must be multi"
msgstr ""
#: src/rougail/object_model.py:560
#: src/rougail/object_model.py:672
msgid "the variable \"{0}\" has an invalid attribute \"{1}\", the variable must be a multi or the variable \"{2}\" must not be multi"
msgstr ""
#: src/rougail/object_model.py:565
#: src/rougail/object_model.py:686
msgid "the variable \"{0}\" has an invalid attribute \"{1}\", the variable \"{2}\" is multi but is inside a list"
msgstr ""
#: src/rougail/object_model.py:579
#: src/rougail/object_model.py:704
msgid "\"{0}\" attribut shall not have an \"optional\" attribute for variable \"{1}\""
msgstr ""
#: src/rougail/object_model.py:591
#: src/rougail/object_model.py:724
msgid "variable \"{0}\" has a default value calculated with \"{1}\" which has incompatible type"
msgstr ""
#: src/rougail/object_model.py:629
#: src/rougail/object_model.py:770
msgid "\"when\" is not allowed in format version 1.0 for attribute \"{0}\" for variable \"{1}\""
msgstr ""
#: src/rougail/object_model.py:632
#: src/rougail/object_model.py:775
msgid "the variable \"{0}\" has an invalid attribute \"{1}\", \"when\" and \"when_not\" cannot set together"
msgstr ""
#: src/rougail/object_model.py:638
#: src/rougail/object_model.py:783
msgid "\"when_not\" is not allowed in format version 1.0 for attribute \"{0}\" for variable \"{1}\""
msgstr ""
#: src/rougail/object_model.py:693
#: src/rougail/object_model.py:840
msgid "cannot find variable \"{0}\" for the information \"{1}\" when calculating \"{2}\""
msgstr ""
#: src/rougail/object_model.py:696
#: src/rougail/object_model.py:845
msgid "identifier not allowed for the information \"{0}\" when calculating \"{1}\""
msgstr ""
#: src/rougail/object_model.py:747
#: src/rougail/object_model.py:898
msgid "\"when\" is not allowed in format version 1.0 for attribute \"{0}\""
msgstr ""
#: src/rougail/object_model.py:751 src/rougail/object_model.py:759
#: src/rougail/object_model.py:904 src/rougail/object_model.py:914
msgid "the identifier has an invalid attribute \"{0}\", \"when\" and \"when_not\" cannot set together"
msgstr ""
#: src/rougail/object_model.py:782
#: src/rougail/object_model.py:939
msgid "the variable \"{0}\" is not a follower, so cannot have index type for \"{1}\""
msgstr ""
@ -340,30 +340,66 @@ msgstr ""
msgid "Directories where extra dictionary files are placed"
msgstr ""
#: src/rougail/tiramisu.py:175
#: src/rougail/tiramisu.py:187
msgid "cannot calculating \"{0}\" attribute for variable \"{1}\" in {2} with parameters \"{3}\": {4}"
msgstr ""
#: src/rougail/tiramisureflector.py:364
#: src/rougail/tiramisureflector.py:363
msgid "internal error, {0} is not a dynamic variable"
msgstr ""
#: src/rougail/user_datas.py:116
#: src/rougail/user_datas.py:118
msgid "cannot load variable path \"{0}\", the identifier \"{1}\" is not valid in {2}"
msgstr ""
#: src/rougail/user_datas.py:171
#: src/rougail/user_datas.py:196
msgid "the variable \"{0}\" contains secrets and should not be defined in {1}"
msgstr ""
#: src/rougail/user_datas.py:236
msgid "the variable \"{0}\" is a family, so cannot set the value \"{1}\" in {2}"
#: src/rougail/user_datas.py:218
msgid "loaded from {0}"
msgstr ""
#: src/rougail/user_datas.py:251
#: src/rougail/user_datas.py:258
msgid "cannot set the value \"{0}\" to the family {1}, it will be ignored when loading from {2}"
msgstr ""
#: src/rougail/user_datas.py:270
msgid "variable or family \"{0}\" does not exist, it will be ignored when loading from {1}"
msgstr ""
#: src/rougail/user_datas.py:276
msgid "\"{0}\" is the name of a dynamic family, it will be ignored when loading from {1}"
msgstr ""
#: src/rougail/user_datas.py:282
msgid "{0} loaded from {1}"
msgstr ""
#: src/rougail/user_datas.py:311
msgid "variable {0} at index \"{1}\" is {2}, it will be ignored when loading from {3}"
msgstr ""
#: src/rougail/user_datas.py:322
msgid "family {0} is {1}, {2} at index \"{3}\" will be ignored when loading from {4}"
msgstr ""
#: src/rougail/user_datas.py:335
msgid "variable {0} is {1}, it will be ignored when loading from {2}"
msgstr ""
#: src/rougail/user_datas.py:343
msgid "family {0} is {1}, {2} will be ignored when loading from {3}"
msgstr ""
#: src/rougail/user_datas.py:362
msgid "the value \"{0}\" is invalid for {1} at index \"{2}\", {3}, it will be ignored when loading from {4}"
msgstr ""
#: src/rougail/user_datas.py:373
msgid "the value \"{0}\" is invalid for {1}, {2}, it will be ignored when loading from {3}"
msgstr ""
#: src/rougail/utils.py:55
msgid "invalid variable or family name \"{0}\" must only contains lowercase ascii character, number or _"
msgstr ""

View file

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

View file

@ -50,7 +50,9 @@ def tiramisu_display_name(
comment = doc if doc and doc != kls.impl_getname() else ""
if "{{ identifier }}" in comment and subconfig.identifiers:
comment = comment.replace("{{ identifier }}", str(subconfig.identifiers[-1]))
path_in_description = values.get_information(context_subconfig, 'path_in_description', True)
path_in_description = values.get_information(
context_subconfig, "path_in_description", True
)
if path_in_description or not comment:
comment = f" ({comment})" if comment else ""
if path_in_description is False:

View file

@ -1 +1 @@
__version__ = "1.2.0a23"
__version__ = "1.2.0a24"

View file

@ -140,9 +140,7 @@ class Annotator(Walk):
family.path
)
self.objectspace.informations.add(family.path, "dynamic_variable", path)
self.objectspace.informations.add(
family.path, "ymlfiles", family.xmlfiles
)
self.objectspace.informations.add(family.path, "ymlfiles", family.xmlfiles)
def change_modes(self):
"""change the mode of variables"""

View file

@ -115,7 +115,9 @@ class Annotator(Walk): # pylint: disable=R0903
if isinstance(variable.choices, Calculation):
continue
if variable.choices is None:
msg = _('the variable "{0}" is a "choice" variable but don\'t have any choice').format(variable.path)
msg = _(
'the variable "{0}" is a "choice" variable but don\'t have any choice'
).format(variable.path)
raise DictConsistencyError(msg, 19, variable.xmlfiles)
if not variable.mandatory and not variable.multi:
self.add_choice_nil(variable)
@ -132,5 +134,7 @@ class Annotator(Walk): # pylint: disable=R0903
if variable.type != "regexp":
continue
if variable.regexp is None:
msg = _('the variable "{0}" is a "regexp" variable but don\'t have any regexp').format(variable.path)
msg = _(
'the variable "{0}" is a "regexp" variable but don\'t have any regexp'
).format(variable.path)
raise DictConsistencyError(msg, 66, variable.xmlfiles)

View file

@ -83,13 +83,21 @@ class Annotator(Walk): # pylint: disable=R0903
continue
path = variable.path
if variable.type not in ["unix_user", "secret"]:
msg = _('only "unix_user" or "secret" variable type can have "secret_manager" attribute, but "{0}" has type "{1}"')
raise DictConsistencyError(msg.format(path, variable.type), 56, variable.xmlfiles)
msg = _(
'only "unix_user" or "secret" variable type can have "secret_manager" attribute, but "{0}" has type "{1}"'
)
raise DictConsistencyError(
msg.format(path, variable.type), 56, variable.xmlfiles
)
if variable.multi and path not in self.objectspace.leaders:
msg = _('the variable "{0}" has attribute "secret_manager" but is a multi variable')
msg = _(
'the variable "{0}" has attribute "secret_manager" but is a multi variable'
)
raise DictConsistencyError(msg.format(path), 57, variable.xmlfiles)
if variable.default is not None:
msg = _('the variable "{0}" has attribute "secret_manager" so must not have default value')
msg = _(
'the variable "{0}" has attribute "secret_manager" so must not have default value'
)
raise DictConsistencyError(msg.format(path), 59, variable.xmlfiles)
def convert_variable(self):
@ -106,9 +114,11 @@ class Annotator(Walk): # pylint: disable=R0903
self.objectspace.informations.add(
variable.path, "ymlfiles", variable.xmlfiles
)
if variable.version != '1.0' and isinstance(variable.default, VariableCalculation):
calculated_variable_path, calculated_variable, identifier = variable.default.get_variable(
self.objectspace
if variable.version != "1.0" and isinstance(
variable.default, VariableCalculation
):
calculated_variable_path, calculated_variable, identifier = (
variable.default.get_variable(self.objectspace)
)
else:
calculated_variable = None
@ -144,15 +154,27 @@ class Annotator(Walk): # pylint: disable=R0903
return
if variable.path in self.objectspace.leaders:
variable.multi = self.objectspace.multis[variable.path] = True
elif variable.version != "1.0" and isinstance(variable.default, VariableCalculation):
calculated_variable_path, calculated_variable, identifier = variable.default.get_variable(
self.objectspace
elif variable.version != "1.0" and isinstance(
variable.default, VariableCalculation
):
calculated_variable_path, calculated_variable, identifier = (
variable.default.get_variable(self.objectspace)
)
if calculated_variable is not None:
if calculated_variable.multi is None:
self._convert_variable_multi(calculated_variable)
variable.multi = calc_multi_for_type_variable(variable, calculated_variable_path, calculated_variable, self.objectspace)[1]
if calculated_variable.path in self.objectspace.followers and variable.mandatory is calculated_variable.mandatory is False and calculated_variable.path.rsplit(".", 1)[0] != variable.path.rsplit(".", 1)[0]:
variable.multi = calc_multi_for_type_variable(
variable,
calculated_variable_path,
calculated_variable,
self.objectspace,
)[1]
if (
calculated_variable.path in self.objectspace.followers
and variable.mandatory is calculated_variable.mandatory is False
and calculated_variable.path.rsplit(".", 1)[0]
!= variable.path.rsplit(".", 1)[0]
):
variable.empty = False
else:
variable.multi = isinstance(variable.default, list)
@ -163,15 +185,18 @@ class Annotator(Walk): # pylint: disable=R0903
calculated_variable,
) -> None:
# if a variable has a variable as default value, that means the type/params or multi should has same value
if not isinstance(variable.default, VariableCalculation) or variable.type is not None:
if (
not isinstance(variable.default, VariableCalculation)
or variable.type is not None
):
return
# copy type and params
variable.type = calculated_variable.type
if variable.params is None and calculated_variable.params is not None:
variable.params = calculated_variable.params
if variable.type == 'choice' and variable.choices is None:
if variable.type == "choice" and variable.choices is None:
variable.choices = calculated_variable.choices
if variable.type == 'regexp' and variable.regexp is None:
if variable.type == "regexp" and variable.regexp is None:
variable.regexp = calculated_variable.regexp
def _convert_variable(

View file

@ -381,8 +381,8 @@ secret_manager:
rougail_process += """
alternative_name: {NAME[0]}
""".format(
NAME=normalize_family(process),
)
NAME=normalize_family(process),
)
rougail_process += """
choices:
"""
@ -409,8 +409,9 @@ secret_manager:
rougail_process += """ {% if _.output is not propertyerror and _.output == 'NAME' %}
Cannot load structural for NAME output
{% endif %}
""".replace("NAME", hidden_output
)
""".replace(
"NAME", hidden_output
)
elif process == "user data":
rougail_process += """ multi: true
mandatory: false"""
@ -475,7 +476,7 @@ default_params:
mandatory: false
default: {value}
"""
# print(rougail_process)
# print(rougail_process)
rougail_options += rougail_process
convert = FakeRougailConvert(add_extra_options)
convert.init()

View file

@ -188,7 +188,7 @@ class ParserVariable:
self.output = None
self.tiramisu_cache = rougailconfig["tiramisu_cache"]
self.load_unexist_redefine = rougailconfig["load_unexist_redefine"]
self.secret_pattern = rougailconfig['secret_manager.pattern']
self.secret_pattern = rougailconfig["secret_manager.pattern"]
# change default initkwargs in CONVERT_OPTION
if hasattr(rougailconfig, "config"):
for sub_od in rougailconfig.config.option("default_params"):
@ -505,7 +505,7 @@ class ParserVariable:
for key, value in obj.items():
if not isinstance(key, str):
raise DictConsistencyError(
f'a key is not in string format: {key}',
f"a key is not in string format: {key}",
103,
[filename],
)
@ -648,7 +648,8 @@ class ParserVariable:
raise DictConsistencyError(
f'"{path}" is not a valid variable, there are additional '
f'attributes: "{", ".join(extra_attrs)}"',
65, [filename]
65,
[filename],
)
self.parse_parameters(
path,
@ -687,9 +688,7 @@ class ParserVariable:
msg = f'cannot redefine the inexisting variable "{path}"'
raise DictConsistencyError(msg, 46, [filename])
obj["path"] = path
self.add_variable(
name, obj, filename, family_is_dynamic, parent_dynamic
)
self.add_variable(name, obj, filename, family_is_dynamic, parent_dynamic)
if family_is_leadership:
if first_variable:
self.leaders.append(path)
@ -803,10 +802,11 @@ class ParserVariable:
64,
[filename],
)
secret_manager = {"type": "jinja",
"jinja": self.secret_pattern,
"params": obj["secret_manager"],
}
secret_manager = {
"type": "jinja",
"jinja": self.secret_pattern,
"params": obj["secret_manager"],
}
self.set_calculation(
obj,
"secret_manager",

View file

@ -151,7 +151,9 @@ class Param(BaseModel):
) -> None:
super().__init__(**kwargs)
def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict:
def to_param(
self, attribute_name, objectspace, path, version, namespace, xmlfiles
) -> dict:
return self.model_dump()
@ -167,8 +169,12 @@ class VariableParam(Param):
whole: bool = False
optional: bool = False
def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict:
param = super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles)
def to_param(
self, attribute_name, objectspace, path, version, namespace, xmlfiles
) -> dict:
param = super().to_param(
attribute_name, objectspace, path, version, namespace, xmlfiles
)
variable, identifier = objectspace.paths.get_with_dynamic(
param["variable"],
path,
@ -178,14 +184,20 @@ class VariableParam(Param):
)
if not variable:
if not param.get("optional"):
msg = _('cannot find variable "{0}" defined in attribute "{1}" for "{2}"').format(param["variable"], attribute_name, path)
msg = _(
'cannot find variable "{0}" defined in attribute "{1}" for "{2}"'
).format(param["variable"], attribute_name, path)
raise DictConsistencyError(msg, 22, xmlfiles)
return None
if isinstance(variable, objectspace.family):
msg = _('the variable "{0}" is in fact a family in attribute "{1}" for "{2}"').format(variable["name"], attribute_name, path)
msg = _(
'the variable "{0}" is in fact a family in attribute "{1}" for "{2}"'
).format(variable["name"], attribute_name, path)
raise DictConsistencyError(msg, 42, xmlfiles)
if not isinstance(variable, objectspace.variable):
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(variable, attribute_name, path)
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(
variable, attribute_name, path
)
raise DictConsistencyError(msg, 44, xmlfiles)
param["variable"] = variable
if identifier:
@ -202,7 +214,9 @@ class IdentifierParam(Param):
**kwargs,
) -> None:
if not kwargs["family_is_dynamic"]:
msg = _('identifier parameter for "{0}" in "{1}" cannot be set none dynamic family').format(kwargs["attribute"], kwargs["path"])
msg = _(
'identifier parameter for "{0}" in "{1}" cannot be set none dynamic family'
).format(kwargs["attribute"], kwargs["path"])
raise DictConsistencyError(msg, 10, kwargs["xmlfiles"])
super().__init__(**kwargs)
@ -212,8 +226,12 @@ class InformationParam(Param):
information: str
variable: Optional[str] = None
def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict:
param = super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles)
def to_param(
self, attribute_name, objectspace, path, version, namespace, xmlfiles
) -> dict:
param = super().to_param(
attribute_name, objectspace, path, version, namespace, xmlfiles
)
if not param["variable"]:
del param["variable"]
return param
@ -225,10 +243,14 @@ class InformationParam(Param):
xmlfiles,
)
if not variable:
msg = _('cannot find variable "{0}" defined in "{1}" for "{2}"').format(param["variable"], attribute_name, path)
msg = _('cannot find variable "{0}" defined in "{1}" for "{2}"').format(
param["variable"], attribute_name, path
)
raise DictConsistencyError(msg, 14, xmlfiles)
if identifier:
msg = _('variable "{0}" defined in "{1}" for "{2}" is a dynamic variable').format(param["variable"], attribute_name, path)
msg = _(
'variable "{0}" defined in "{1}" for "{2}" is a dynamic variable'
).format(param["variable"], attribute_name, path)
raise DictConsistencyError(msg, 15, xmlfiles)
param["variable"] = variable
return param
@ -237,25 +259,37 @@ class InformationParam(Param):
class IndexParam(Param):
type: str
def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict:
if path not in objectspace.followers and (attribute_name != 'validators' or path not in objectspace.multis):
msg = _('the variable "{0}" is not a follower, so cannot have index type for param in "{1}"').format(path, attribute)
def to_param(
self, attribute_name, objectspace, path, version, namespace, xmlfiles
) -> dict:
if path not in objectspace.followers and (
attribute_name != "validators" or path not in objectspace.multis
):
msg = _(
'the variable "{0}" is not a follower, so cannot have index type for param in "{1}"'
).format(path, attribute)
raise DictConsistencyError(msg, 25, xmlfiles)
return super().to_param(attribute_name, objectspace, path, version, namespace, xmlfiles)
return super().to_param(
attribute_name, objectspace, path, version, namespace, xmlfiles
)
class NamespaceParam(Param):
type: str
namespace: str
def to_param(self, attribute_name, objectspace, path, version, namespace, xmlfiles) -> dict:
def to_param(
self, attribute_name, objectspace, path, version, namespace, xmlfiles
) -> dict:
namespace = self.namespace
if namespace:
namespace = objectspace.paths[namespace].description
return {'type': 'any',
'value': namespace,
'key': self.key,
}
return {
"type": "any",
"value": namespace,
"key": self.key,
}
PARAM_TYPES = {
"any": AnyParam,
@ -287,7 +321,14 @@ class Calculation(BaseModel):
path = self.ori_path
params = {}
for param_obj in self.params:
param = param_obj.to_param(self.attribute_name, objectspace, path, self.version, self.namespace, self.xmlfiles)
param = param_obj.to_param(
self.attribute_name,
objectspace,
path,
self.version,
self.namespace,
self.xmlfiles,
)
if param is None:
continue
params[param.pop("key")] = param
@ -454,13 +495,17 @@ class _VariableCalculation(Calculation):
path = self.path
else:
path = self.ori_path
if self.version != "1.0" and objectspace.paths.regexp_relative.search(self.variable):
if self.version != "1.0" and objectspace.paths.regexp_relative.search(
self.variable
):
variable_full_path = objectspace.paths.get_full_path(
self.variable,
path,
)
elif self.version == "1.0" and "{{ suffix }}" in self.variable:
variable_full_path = self.variable.replace("{{ suffix }}", "{{ identifier }}")
variable_full_path = self.variable.replace(
"{{ suffix }}", "{{ identifier }}"
)
else:
variable_full_path = self.variable
variable, identifier = objectspace.paths.get_with_dynamic(
@ -472,10 +517,14 @@ class _VariableCalculation(Calculation):
)
if variable and not isinstance(variable, objectspace.variable):
if isinstance(variable, objectspace.family):
msg = _('a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family').format(variable_full_path, self.attribute_name, self.path)
msg = _(
'a variable "{0}" is needs in attribute "{1}" for "{2}" but it\'s a family'
).format(variable_full_path, self.attribute_name, self.path)
raise DictConsistencyError(msg, 47, self.xmlfiles)
else:
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(variable, self.attribute_name, self.path)
msg = _('unknown object "{0}" in attribute "{1}" for "{2}"').format(
variable, self.attribute_name, self.path
)
raise DictConsistencyError(msg, 48, self.xmlfiles)
return variable_full_path, variable, identifier
@ -492,7 +541,9 @@ class _VariableCalculation(Calculation):
path = self.path
else:
path = self.ori_path
msg = _('variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"').format(path, self.attribute_name, self.variable)
msg = _(
'variable "{0}" has an attribute "{1}" calculated with the unknown variable "{2}"'
).format(path, self.attribute_name, self.variable)
raise DictConsistencyError(msg, 88, self.xmlfiles)
return {None: [["example"]]}
param = {
@ -509,7 +560,9 @@ class _VariableCalculation(Calculation):
params["__default_value"] = self.default_values
if self.allow_none:
params["allow_none"] = True
self.check_multi(objectspace, variable_in_calculation_path, variable_in_calculation)
self.check_multi(
objectspace, variable_in_calculation_path, variable_in_calculation
)
if self.path in objectspace.followers:
multi = objectspace.multis[self.path] == "submulti"
else:
@ -518,51 +571,123 @@ class _VariableCalculation(Calculation):
params["__internal_multi"] = True
return params
def check_multi(self, objectspace, variable_in_calculation_path, variable_in_calculation):
def check_multi(
self, objectspace, variable_in_calculation_path, variable_in_calculation
):
if self.ori_path is None:
path = self.path
else:
path = self.ori_path
local_variable = objectspace.paths[path]
local_variable_multi, variable_in_calculation_multi = calc_multi_for_type_variable(local_variable, variable_in_calculation_path, variable_in_calculation, objectspace)
local_variable_multi, variable_in_calculation_multi = (
calc_multi_for_type_variable(
local_variable,
variable_in_calculation_path,
variable_in_calculation,
objectspace,
)
)
if self.attribute_name == "default":
if variable_in_calculation_multi == 'submulti':
if variable_in_calculation_multi == "submulti":
if objectspace.paths.is_dynamic(variable_in_calculation.path):
msg = _('the variable "{0}" has an invalid "{1}" the variable "{2}" is in a sub dynamic option').format(local_variable.path, self.attribute_name, variable_in_calculation.path)
msg = _(
'the variable "{0}" has an invalid "{1}" the variable "{2}" is in a sub dynamic option'
).format(
local_variable.path,
self.attribute_name,
variable_in_calculation.path,
)
raise DictConsistencyError(msg, 69, self.xmlfiles)
else:
msg = _('the leader "{0}" has an invalid "{1}" the follower "{2}" is a multi').format(local_variable.path, self.attribute_name, variable_in_calculation.path)
msg = _(
'the leader "{0}" has an invalid "{1}" the follower "{2}" is a multi'
).format(
local_variable.path,
self.attribute_name,
variable_in_calculation.path,
)
raise DictConsistencyError(msg, 74, self.xmlfiles)
if not self.inside_list:
if local_variable_multi != variable_in_calculation_multi:
if local_variable_multi:
self.check_variable_in_calculation_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi)
self.check_variable_in_calculation_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi)
self.check_variable_in_calculation_multi(
local_variable.path,
variable_in_calculation_path,
variable_in_calculation_multi,
)
self.check_variable_in_calculation_not_multi(
local_variable.path,
variable_in_calculation_path,
variable_in_calculation_multi,
)
else:
self.check_variable_in_calculation_in_list_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi)
self.check_variable_in_calculation_in_list_not_multi(
local_variable.path,
variable_in_calculation_path,
variable_in_calculation_multi,
)
elif self.attribute_name in ["choices", "dynamic"]:
# calculated variable must be a multi
if not self.inside_list:
self.check_variable_in_calculation_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi)
self.check_variable_in_calculation_multi(
local_variable.path,
variable_in_calculation_path,
variable_in_calculation_multi,
)
else:
self.check_variable_in_calculation_in_list_not_multi(local_variable.path, variable_in_calculation_path, variable_in_calculation_multi)
self.check_variable_in_calculation_in_list_not_multi(
local_variable.path,
variable_in_calculation_path,
variable_in_calculation_multi,
)
elif variable_in_calculation_multi is True:
msg = _('the variable "{0}" has an invalid attribute "{1}", the variable "{2}" must not be multi').format(local_variable.path, self.attribute_name, variable_in_calculation_path)
msg = _(
'the variable "{0}" has an invalid attribute "{1}", the variable "{2}" must not be multi'
).format(
local_variable.path, self.attribute_name, variable_in_calculation_path
)
raise DictConsistencyError(msg, 23, self.xmlfiles)
def check_variable_in_calculation_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi):
def check_variable_in_calculation_multi(
self,
local_variable_path,
variable_in_calculation_path,
variable_in_calculation_multi,
):
if variable_in_calculation_multi is False:
msg = _('the variable "{0}" has an invalid attribute "{1}", the variable must not be a multi or the variable "{2}" must be multi').format(local_variable_path, self.attribute_name, variable_in_calculation_path)
msg = _(
'the variable "{0}" has an invalid attribute "{1}", the variable must not be a multi or the variable "{2}" must be multi'
).format(
local_variable_path, self.attribute_name, variable_in_calculation_path
)
raise DictConsistencyError(msg, 20, self.xmlfiles)
def check_variable_in_calculation_not_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi):
def check_variable_in_calculation_not_multi(
self,
local_variable_path,
variable_in_calculation_path,
variable_in_calculation_multi,
):
if variable_in_calculation_multi is True:
msg = _('the variable "{0}" has an invalid attribute "{1}", the variable must be a multi or the variable "{2}" must not be multi').format(local_variable_path, self.attribute_name, variable_in_calculation_path)
msg = _(
'the variable "{0}" has an invalid attribute "{1}", the variable must be a multi or the variable "{2}" must not be multi'
).format(
local_variable_path, self.attribute_name, variable_in_calculation_path
)
raise DictConsistencyError(msg, 21, self.xmlfiles)
def check_variable_in_calculation_in_list_not_multi(self, local_variable_path, variable_in_calculation_path, variable_in_calculation_multi):
def check_variable_in_calculation_in_list_not_multi(
self,
local_variable_path,
variable_in_calculation_path,
variable_in_calculation_multi,
):
if variable_in_calculation_multi is True:
msg = _('the variable "{0}" has an invalid attribute "{1}", the variable "{2}" is multi but is inside a list').format(local_variable_path, self.attribute_name, variable_in_calculation_path)
msg = _(
'the variable "{0}" has an invalid attribute "{1}", the variable "{2}" is multi but is inside a list'
).format(
local_variable_path, self.attribute_name, variable_in_calculation_path
)
raise DictConsistencyError(msg, 18, self.xmlfiles)
@ -576,9 +701,15 @@ class VariableCalculation(_VariableCalculation):
objectspace,
) -> dict:
if self.attribute_name != "default" and self.optional:
msg = _('"{0}" attribut shall not have an "optional" attribute for variable "{1}"').format(self.attribute_name, self.variable)
msg = _(
'"{0}" attribut shall not have an "optional" attribute for variable "{1}"'
).format(self.attribute_name, self.variable)
raise DictConsistencyError(msg, 33, self.xmlfiles)
variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier = self.get_variable(objectspace)
(
variable_in_calculation_path,
variable_in_calculation,
variable_in_calculation_identifier,
) = self.get_variable(objectspace)
if (
not variable_in_calculation
and self.optional
@ -587,8 +718,12 @@ class VariableCalculation(_VariableCalculation):
raise VariableCalculationDependencyError()
if variable_in_calculation and self.attribute_name == "default":
local_variable = objectspace.paths[self.path]
if CONVERT_OPTION.get(local_variable.type, {}).get("func", str) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str):
msg = _('variable "{0}" has a default value calculated with "{1}" which has incompatible type').format(self.path, self.variable)
if CONVERT_OPTION.get(local_variable.type, {}).get(
"func", str
) != CONVERT_OPTION.get(variable_in_calculation.type, {}).get("func", str):
msg = _(
'variable "{0}" has a default value calculated with "{1}" which has incompatible type'
).format(self.path, self.variable)
raise DictConsistencyError(msg, 67, self.xmlfiles)
params = self.get_params(
objectspace,
@ -613,29 +748,41 @@ class VariablePropertyCalculation(_VariableCalculation):
self,
objectspace,
) -> dict:
variable_in_calculation_path, variable_in_calculation, variable_in_calculation_identifier = self.get_variable(objectspace)
(
variable_in_calculation_path,
variable_in_calculation,
variable_in_calculation_identifier,
) = self.get_variable(objectspace)
params = self.get_params(
objectspace,
variable_in_calculation_path,
variable_in_calculation,
variable_in_calculation_identifier,
)
if objectspace.force_optional and (not params[None] or "variable" not in params[None][0]):
if objectspace.force_optional and (
not params[None] or "variable" not in params[None][0]
):
params = {None: [None, None, False]}
else:
variable = params[None][0]["variable"]
if self.when is not undefined:
if self.version == "1.0":
msg = _('"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"').format(self.attribute_name, self.path)
msg = _(
'"when" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
).format(self.attribute_name, self.path)
raise DictConsistencyError(msg, 103, variable.xmlfiles)
if self.when_not is not undefined:
msg = _('the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together').format(self.path, self.attribute_name)
msg = _(
'the variable "{0}" has an invalid attribute "{1}", "when" and "when_not" cannot set together'
).format(self.path, self.attribute_name)
raise DictConsistencyError(msg, 31, variable.xmlfiles)
when = self.when
inverse = False
elif self.when_not is not undefined:
if self.version == "1.0":
msg = _('"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"').format(self.attribute_name, self.path)
msg = _(
'"when_not" is not allowed in format version 1.0 for attribute "{0}" for variable "{1}"'
).format(self.attribute_name, self.path)
raise DictConsistencyError(msg, 104, variable.xmlfiles)
when = self.when_not
inverse = True
@ -650,7 +797,7 @@ class VariablePropertyCalculation(_VariableCalculation):
params["when"] = when
params["inverse"] = inverse
params[None].insert(0, self.attribute_name)
func = 'variable_to_property'
func = "variable_to_property"
return {
"function": func,
"params": params,
@ -690,10 +837,14 @@ class InformationCalculation(Calculation):
)
if variable is None:
if not objectspace.force_optional:
msg = _('cannot find variable "{0}" for the information "{1}" when calculating "{2}"').format(self.variable, self.information, self.attribute_name)
msg = _(
'cannot find variable "{0}" for the information "{1}" when calculating "{2}"'
).format(self.variable, self.information, self.attribute_name)
raise DictConsistencyError(msg, 40, variable.xmlfiles)
if identifier is not None:
msg = _('identifier not allowed for the information "{0}" when calculating "{1}"').format(self.information, self.attribute_name)
msg = _(
'identifier not allowed for the information "{0}" when calculating "{1}"'
).format(self.information, self.attribute_name)
raise DictConsistencyError(msg, 41, variable.xmlfiles)
if variable:
params[None][0]["variable"] = variable
@ -744,11 +895,15 @@ class IdentifierPropertyCalculation(_IdentifierCalculation):
objectspace,
) -> dict:
if self.version == "1.0":
msg = _('"when" is not allowed in format version 1.0 for attribute "{0}"').format(self.attribute_name)
msg = _(
'"when" is not allowed in format version 1.0 for attribute "{0}"'
).format(self.attribute_name)
raise DictConsistencyError(msg, 105, variable.xmlfiles)
if self.when is not undefined:
if self.when_not is not undefined:
msg = _('the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together').format(self.attribute_name)
msg = _(
'the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together'
).format(self.attribute_name)
raise DictConsistencyError(msg, 35, variable.xmlfiles)
when = self.when
inverse = False
@ -756,7 +911,9 @@ class IdentifierPropertyCalculation(_IdentifierCalculation):
when = self.when_not
inverse = True
else:
msg = _('the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together').format(self.attribute_name)
msg = _(
'the identifier has an invalid attribute "{0}", "when" and "when_not" cannot set together'
).format(self.attribute_name)
raise DictConsistencyError
params = {
None: [self.attribute_name, self.get_identifier()],
@ -779,7 +936,9 @@ class IndexCalculation(Calculation):
objectspace,
) -> dict:
if self.path not in objectspace.followers:
msg = _('the variable "{0}" is not a follower, so cannot have index type for "{1}"').format(self.path, self.attribute_name)
msg = _(
'the variable "{0}" is not a follower, so cannot have index type for "{1}"'
).format(self.path, self.attribute_name)
raise DictConsistencyError(msg, 60, self.xmlfiles)
return {
"function": "calc_value",
@ -809,7 +968,7 @@ CALCULATION_TYPES = {
"information": InformationCalculation,
"variable": VariableCalculation,
"identifier": IdentifierCalculation,
# FOR VERSION 1.0
# FOR VERSION 1.0
"suffix": IdentifierCalculation,
"index": IndexCalculation,
"namespace": NamespaceCalculation,

View file

@ -37,17 +37,29 @@ from jinja2.sandbox import SandboxedEnvironment
from rougail.object_model import CONVERT_OPTION
from rougail.error import display_xmlfiles
from tiramisu import DynOptionDescription, calc_value, function_waiting_for_error
from tiramisu.error import ValueWarning, ConfigError, PropertiesOptionError, CancelParam, errors
from tiramisu.error import (
ValueWarning,
ConfigError,
PropertiesOptionError,
CancelParam,
errors,
)
from .utils import normalize_family
from .i18n import _
ori_raise_carry_out_calculation_error = errors.raise_carry_out_calculation_error
def raise_carry_out_calculation_error(subconfig, *args, **kwargs):
try:
ori_raise_carry_out_calculation_error(subconfig, *args, **kwargs)
except ConfigError as err:
ymlfiles = subconfig.config_bag.context.get_values().get_information(subconfig, 'ymlfiles', [])
raise ConfigError(_('{0} in {1}').format(err, display_xmlfiles(ymlfiles)))
ymlfiles = subconfig.config_bag.context.get_values().get_information(
subconfig, "ymlfiles", []
)
raise ConfigError(_("{0} in {1}").format(err, display_xmlfiles(ymlfiles)))
errors.raise_carry_out_calculation_error = raise_carry_out_calculation_error
@ -124,7 +136,7 @@ def kw_to_string(kw, root=None):
if root is None:
path = name
else:
path = root + '.' + name
path = root + "." + name
if isinstance(data, dict):
yield from kw_to_string(data, root=path)
else:
@ -172,11 +184,21 @@ def jinja_to_function(
except Exception as err:
kw_str = ", ".join(kw_to_string(kw))
raise ConfigError(
_('cannot calculating "{0}" attribute for variable "{1}" in {2} with parameters "{3}": {4}').format(__internal_attribute, __internal_variable, display_xmlfiles(__internal_files), kw_str, err)
_(
'cannot calculating "{0}" attribute for variable "{1}" in {2} with parameters "{3}": {4}'
).format(
__internal_attribute,
__internal_variable,
display_xmlfiles(__internal_files),
kw_str,
err,
)
) from err
convert = CONVERT_OPTION[__internal_type].get("func", str)
if __internal_multi:
values = [convert(val.strip()) for val in values.split("\n") if val.strip() != ""]
values = [
convert(val.strip()) for val in values.split("\n") if val.strip() != ""
]
if not values and __default_value is not None:
return __default_value
return values

View file

@ -290,9 +290,10 @@ class Common:
):
"""Populate variable parameters"""
if not isinstance(param, dict):
param = {"type": "any",
"value": param,
}
param = {
"type": "any",
"value": param,
}
if param["type"] == "value":
return f"ParamValue({param['value']})"
if param["type"] == "information":
@ -331,9 +332,7 @@ class Common:
return f'ParamInformation("{param["information"]}", {default}, option={option_name})'
else:
# if we want to get information from the a parent family
information = (
f'ParamInformation("{param["information"]}", {default})'
)
information = f'ParamInformation("{param["information"]}", {default})'
information_name = self.tiramisu.get_information_name()
self.tiramisu.text["option"].append(
f"{information_name} = {information}"

View file

@ -26,6 +26,7 @@ from rougail.utils import normalize_family, undefined
from tiramisu import Calculation
from tiramisu.error import (
PropertiesOptionError,
AttributeOptionError,
LeadershipError,
ConfigError,
CancelParam,
@ -44,6 +45,7 @@ class UserDatas:
self.values = {}
self.errors = []
self.warnings = []
self.show_secrets = False
self._populate_values(user_datas)
self._auto_configure_dynamics()
self._populate_config()
@ -113,7 +115,9 @@ class UserDatas:
continue
identifier = self._get_identifier(tconfig.name(), name)
if identifier != normalize_family(identifier):
msg = _('cannot load variable path "{0}", the identifier "{1}" is not valid in {2}').format(path, identifier, data["source"])
msg = _(
'cannot load variable path "{0}", the identifier "{1}" is not valid in {2}'
).format(path, identifier, data["source"])
self.warnings.append(msg)
continue
if identifier is None:
@ -155,6 +159,27 @@ class UserDatas:
cache[current_path] = config, identifier
break
def convert_value(self, path, option, options, value):
# converted value
needs_convert = options.get("needs_convert", False)
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)
return value
def _populate_config(self):
while self.values:
value_is_set = False
@ -173,33 +198,25 @@ class UserDatas:
).format(path, self.values[path]["source"])
)
continue
value = self.values[path]["values"]
needs_convert = options.get("needs_convert", False)
value = self.convert_value(
path, option, options, self.values[path]["values"]
)
# 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]
if option.isleader():
len_leader = len(option.value.get())
if len_leader:
for idx in range(len_leader - 1, -1, -1):
option.value.pop(idx)
try:
option.value.set(value)
option.information.set(
"loaded_from", _("loaded from {0}").format(options["source"])
)
value_is_set = True
# value is correctly set, remove variable to the set
if index is not None:
@ -224,33 +241,144 @@ class UserDatas:
return None
return finded[0]
def _display_value(self, option, value):
if not self.show_secrets and option.type() == "password":
return "*" * 10
return value
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():
for path, options in self.values.items():
value = options["values"]
option = self.config.option(path)
try:
option = self.config.option(path)
value = data["values"]
if option.isoptiondescription():
if value:
self.warnings.append(
_('the variable "{0}" is a family, so cannot set the value "{1}" in {2}').format(
option.path(),
value,
data["source"],
_(
'cannot set the value "{0}" to the family {1}, it will be ignored when loading from {2}'
).format(
self._display_value(option, value),
option.description(with_quote=True),
options["source"],
)
)
continue
if option.isfollower():
for index, val in enumerate(value):
except AttributeOptionError as err:
if err.code == "option-not-found":
self.warnings.append(
_(
'variable or family "{0}" does not exist, it will be ignored when loading from {1}'
).format(err.path, options["source"])
)
elif err.code == "option-dynamic":
self.warnings.append(
_(
'"{0}" is the name of a dynamic family, it will be ignored when loading from {1}'
).format(option.description(with_quote=True), options["source"])
)
else:
self.warnings.append(
_("{0} loaded from {1}").format(err, options["source"])
)
continue
value = self.convert_value(
path, option, self.values[path].get("options", {}), value
)
if option.isfollower():
indexes = range(len(value))
else:
indexes = [None]
for index in indexes:
try:
if option.isfollower():
val = value[index]
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(_('{0} loaded from {1}').format(err, data["source"]))
except (ValueError, LeadershipError, PropertiesOptionError) as err:
self.warnings.append(_('{0} in {1}').format(err, data["source"]))
else:
option.value.set(value)
except PropertiesOptionError as err:
if err.code == "property-error":
properties = err.display_properties(
force_property=True, add_quote=False
)
err_path = err._subconfig.path
display_name = option.description(with_quote=True)
if index is not None:
if path == err_path:
self.warnings.append(
_(
'variable {0} at index "{1}" is {2}, it will be ignored when loading from {3}'
).format(
display_name,
index,
properties,
options["source"],
)
)
else:
self.warnings.append(
_(
'family {0} is {1}, {2} at index "{3}" will be ignored when loading from {4}'
).format(
err._name,
properties,
display_name,
index,
options["source"],
)
)
else:
if path == err_path:
self.warnings.append(
_(
"variable {0} is {1}, it will be ignored when loading from {2}"
).format(
display_name, properties, options["source"]
)
)
else:
self.warnings.append(
_(
"family {0} is {1}, {2} will be ignored when loading from {3}"
).format(
err._name,
properties,
display_name,
options["source"],
)
)
else:
self.warnings.append(
_("{0} in {1}").format(err, options["source"])
)
except LeadershipError as err:
self.warnings.append(_("{0} in {1}").format(err, options["source"]))
except ValueError as err:
err.prefix = ""
if index is not None:
self.warnings.append(
_(
'the value "{0}" is invalid for {1} at index "{2}", {3}, it will be ignored when loading from {4}'
).format(
self._display_value(option, value),
option.description(with_quote=True),
err,
options["source"],
)
)
else:
self.warnings.append(
_(
'the value "{0}" is invalid for {1}, {2}, it will be ignored when loading from {3}'
).format(
self._display_value(option, value),
option.description(with_quote=True),
err,
options["source"],
)
)
def convert_value(option, value):
@ -265,5 +393,8 @@ def convert_value(option, value):
value = int(value)
func = CONVERT_OPTION.get(option_type, {}).get("func")
if func:
return func(value)
try:
return func(value)
except:
pass
return value

View file

@ -162,7 +162,13 @@ def get_jinja_variable_to_param(
for variable_path, data in founded_variables.items():
yield data[1], data[0], variable_path
def calc_multi_for_type_variable(local_variable: 'Variable', variable_in_calculation_path: str, variable_in_calculation: 'Variable', objectspace: 'RougailConvert') -> Union[bool, str]:
def calc_multi_for_type_variable(
local_variable: "Variable",
variable_in_calculation_path: str,
variable_in_calculation: "Variable",
objectspace: "RougailConvert",
) -> Union[bool, str]:
variable_in_calculation_multi = variable_in_calculation.multi
if local_variable.path in objectspace.families:
# it's a family
@ -171,33 +177,39 @@ def calc_multi_for_type_variable(local_variable: 'Variable', variable_in_calcula
local_variable_multi = local_variable.multi
# variable is a leader
if variable_in_calculation.path in objectspace.leaders:
local_variable_parent = local_variable.path.rsplit('.', 1)[0]
variable_in_calculation_parent = variable_in_calculation.path.rsplit('.', 1)[0]
local_variable_parent = local_variable.path.rsplit(".", 1)[0]
variable_in_calculation_parent = variable_in_calculation.path.rsplit(
".", 1
)[0]
if local_variable_parent == variable_in_calculation_parent:
variable_in_calculation_multi = False
# variable is a follower
elif variable_in_calculation.path in objectspace.followers:
local_variable_parent = local_variable.path.rsplit('.', 1)[0]
variable_in_calculation_parent = variable_in_calculation.path.rsplit('.', 1)[0]
local_variable_parent = local_variable.path.rsplit(".", 1)[0]
variable_in_calculation_parent = variable_in_calculation.path.rsplit(
".", 1
)[0]
if local_variable_parent != variable_in_calculation_parent:
if variable_in_calculation_multi:
variable_in_calculation_multi = 'submulti'
variable_in_calculation_multi = "submulti"
else:
variable_in_calculation_multi = True
# variable is in a dynamic family
if objectspace.paths.is_dynamic(variable_in_calculation.path):
common_path = get_common_path(local_variable.path, variable_in_calculation_path)
common_path = get_common_path(
local_variable.path, variable_in_calculation_path
)
common_variable_path = variable_in_calculation_path
if common_path:
common_variable_path = common_variable_path[len(common_path) + 1:]
count_identifiers = common_variable_path.count('{{ identifier }}')
common_variable_path = common_variable_path[len(common_path) + 1 :]
count_identifiers = common_variable_path.count("{{ identifier }}")
if count_identifiers == 1:
if variable_in_calculation_multi is False:
variable_in_calculation_multi = True
else:
variable_in_calculation_multi = 'submulti'
variable_in_calculation_multi = "submulti"
elif count_identifiers > 1:
variable_in_calculation_multi = 'submulti'
variable_in_calculation_multi = "submulti"
return local_variable_multi, variable_in_calculation_multi

View file

@ -0,0 +1,22 @@
{
"rougail.leadership.leader": {
"owner": "default",
"value": [
"value_1",
"value_2",
"value_3"
]
},
"rougail.leadership.follower": {
"owner": [
"default",
"default",
"default"
],
"value": [
null,
null,
null
]
}
}

View file

@ -0,0 +1,16 @@
{
"rougail.leadership.leader": [
{
"rougail.leadership.leader": "value_1",
"rougail.leadership.follower": null
},
{
"rougail.leadership.leader": "value_2",
"rougail.leadership.follower": null
},
{
"rougail.leadership.leader": "value_3",
"rougail.leadership.follower": null
}
]
}

View file

@ -0,0 +1,22 @@
{
"rougail.leadership.leader": {
"owner": "default",
"value": [
"value_1",
"value_2",
"value_3"
]
},
"rougail.leadership.follower": {
"owner": [
"default",
"default",
"default"
],
"value": [
null,
null,
null
]
}
}

View file

@ -0,0 +1 @@
["rougail.leadership.follower", "rougail.leadership.follower", "rougail.leadership.follower"]

View file

@ -0,0 +1,16 @@
{
"rougail.leadership.leader": [
{
"rougail.leadership.leader": "value_1",
"rougail.leadership.follower": null
},
{
"rougail.leadership.leader": "value_2",
"rougail.leadership.follower": null
},
{
"rougail.leadership.leader": "value_3",
"rougail.leadership.follower": null
}
]
}

View file

@ -0,0 +1,17 @@
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('../rougail-tests/funcs/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="leader", doc="a leader", multi=True, default=["value_1", "value_2", "value_3"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string', 'test': ('val1', 'val2')})
option_4 = StrOption(name="follower", doc="a follower", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string'})
optiondescription_2 = Leadership(name="leadership", doc="a leadership", children=[option_3, option_4], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml']})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2], properties=frozenset({"basic"}), informations={'ymlfiles': ['']})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -0,0 +1,12 @@
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('../rougail-tests/funcs/test.py')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="leader", doc="a leader", multi=True, default=["value_1", "value_2", "value_3"], properties=frozenset({"mandatory", "standard"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string', 'test': ('val1', 'val2')})
option_3 = StrOption(name="follower", doc="a follower", multi=True, properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml'], 'type': 'string'})
optiondescription_1 = Leadership(name="leadership", doc="a leadership", children=[option_2, option_3], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/40_0leadership_reduce/rougail/00-base.yml']})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -12,7 +12,7 @@
"default"
],
"value": [
"cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"cannot access to option \"a follower\" at index \"0\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"b"
]
}

View file

@ -12,7 +12,7 @@
"default"
],
"value": [
"cannot access to option \"a follower\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"cannot access to option \"a follower\" at index \"0\" because has property \"disabled\" (the value of \"leader\" is \"a\")",
"b"
]
}

View file

@ -31,7 +31,7 @@ excludes = set([])
# excludes = set(['60_5family_dynamic_variable_outside_sub_suffix'])
test_ok -= excludes
# test_ok = ['04_5validators_multi3']
test_ok = ['44_9calculated_default_leadership_leader']
test_ok = list(test_ok)