Compare commits

..

No commits in common. "e351da20691ca611298870dde01f410756214017" and "379630fc387691ed51cc6ea1265d868f30359b98" have entirely different histories.

32 changed files with 3226 additions and 3456 deletions

View file

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Tiramisu\n" "Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-19 22:03+0200\n" "POT-Creation-Date: 2025-05-12 09:04+0200\n"
"PO-Revision-Date: \n" "PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n" "Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n" "Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -11,46 +11,46 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 3.7\n" "X-Generator: Poedit 3.5\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
#: tiramisu/api.py:86 #: tiramisu/api.py:79
msgid "Settings:" msgid "Settings:"
msgstr "Paramètres :" msgstr "Paramètres :"
#: tiramisu/api.py:90 #: tiramisu/api.py:83
msgid "Access to option without verifying permissive properties" msgid "Access to option without verifying permissive properties"
msgstr "Accès à une option sans vérifié les propriétés permises" msgstr "Accès à une option sans vérifié les propriétés permises"
#: tiramisu/api.py:95 #: tiramisu/api.py:88
msgid "Access to option without property restriction" msgid "Access to option without property restriction"
msgstr "Accès à une option sans restriction de propriété" msgstr "Accès à une option sans restriction de propriété"
#: tiramisu/api.py:100 #: tiramisu/api.py:93
msgid "Do not warnings during validation" msgid "Do not warnings during validation"
msgstr "Ne peut avoir de warnings durant une validation" msgstr "Ne peut avoir de warnings durant une validation"
#: tiramisu/api.py:104 #: tiramisu/api.py:97
msgid "Commands:" msgid "Commands:"
msgstr "Commandes :" msgstr "Commandes :"
#: tiramisu/api.py:118 tiramisu/api.py:1955 #: tiramisu/api.py:111 tiramisu/api.py:1857
msgid "please specify a valid sub function ({0}.{1})" msgid "please specify a valid sub function ({0}.{1})"
msgstr "veuillez spécifier une sous fonction valide ({0}.{1})" msgstr "veuillez spécifier une sous fonction valide ({0}.{1})"
#: tiramisu/api.py:206 #: tiramisu/api.py:196
msgid "please do not specify index ({0}.{1})" msgid "please do not specify index ({0}.{1})"
msgstr "veuillez ne pas spécifier d'index ({0}.{1})" msgstr "veuillez ne pas spécifier d'index ({0}.{1})"
#: tiramisu/api.py:211 tiramisu/api.py:940 #: tiramisu/api.py:201 tiramisu/api.py:856
msgid "please specify index with a follower option ({0}.{1})" msgid "please specify index with a follower option ({0}.{1})"
msgstr "veuillez spécifier un index avec une option suiveuse ({0}.{1})" msgstr "veuillez spécifier un index avec une option suiveuse ({0}.{1})"
#: tiramisu/api.py:234 #: tiramisu/api.py:222
msgid "please specify a valid sub function ({0}.{1}): {2}" msgid "please specify a valid sub function ({0}.{1}): {2}"
msgstr "veuillez spécifier une sous fonction valide ({0}.{1}): {2}" msgstr "veuillez spécifier une sous fonction valide ({0}.{1}): {2}"
#: tiramisu/api.py:525 #: tiramisu/api.py:446
msgid "" msgid ""
"the option {0} is not a dynamic option, cannot get identifiers with " "the option {0} is not a dynamic option, cannot get identifiers with "
"only_self parameter to True" "only_self parameter to True"
@ -58,15 +58,15 @@ msgstr ""
"l'option {0} n'est pas une option dynamique, ne peut retrouver l'identifiant " "l'option {0} n'est pas une option dynamique, ne peut retrouver l'identifiant "
"avec le paramètre only_self à True" "avec le paramètre only_self à True"
#: tiramisu/api.py:613 #: tiramisu/api.py:532
msgid "cannot get option from a follower symlink without index" msgid "cannot get option from a follower symlink without index"
msgstr "ne peut avoir d'option pour une symlink suiveuse sans index" msgstr "ne peut avoir d'option pour une symlink suiveuse sans index"
#: tiramisu/api.py:691 #: tiramisu/api.py:607
msgid "cannot add this property: \"{0}\"" msgid "cannot add this property: \"{0}\""
msgstr "ne peut pas ajouter cette propriété : \"{0}\"" msgstr "ne peut pas ajouter cette propriété : \"{0}\""
#: tiramisu/api.py:718 #: tiramisu/api.py:634
msgid "" msgid ""
"cannot remove option's property \"{0}\", use permissive instead in option " "cannot remove option's property \"{0}\", use permissive instead in option "
"\"{1}\"" "\"{1}\""
@ -74,11 +74,11 @@ msgstr ""
"ne supprimer la propriété \"{0}\" de l'option, utiliser plutôt permissive " "ne supprimer la propriété \"{0}\" de l'option, utiliser plutôt permissive "
"dans l'option \"{1}\"" "dans l'option \"{1}\""
#: tiramisu/api.py:722 #: tiramisu/api.py:638
msgid "cannot find \"{0}\" in option \"{1}\"" msgid "cannot find \"{0}\" in option \"{1}\""
msgstr "ne peut trouver \"{0}\" dans l'option \"{1}\"" msgstr "ne peut trouver \"{0}\" dans l'option \"{1}\""
#: tiramisu/api.py:727 #: tiramisu/api.py:643
msgid "" msgid ""
"cannot remove option's property \"{0}\", use permissive instead in option " "cannot remove option's property \"{0}\", use permissive instead in option "
"\"{1}\" at index \"{2}\"" "\"{1}\" at index \"{2}\""
@ -86,35 +86,35 @@ msgstr ""
"ne peut supprimer la propriété \"{0}\" de l'option, utilisez plutôt " "ne peut supprimer la propriété \"{0}\" de l'option, utilisez plutôt "
"permissive dans l'option \"{1}\" a l'index \"{2}\"" "permissive dans l'option \"{1}\" a l'index \"{2}\""
#: tiramisu/api.py:731 #: tiramisu/api.py:647
msgid "cannot find \"{0}\" in option \"{1}\" at index \"{2}\"" msgid "cannot find \"{0}\" in option \"{1}\" at index \"{2}\""
msgstr "ne peut trouver \"{0}\" dans l'option \"{1}\" à l'index \"{2}\"" msgstr "ne peut trouver \"{0}\" dans l'option \"{1}\" à l'index \"{2}\""
#: tiramisu/api.py:775 #: tiramisu/api.py:691
msgid "cannot find \"{0}\"" msgid "cannot find \"{0}\""
msgstr "ne peut trouver \"{0}\"" msgstr "ne peut trouver \"{0}\""
#: tiramisu/api.py:957 #: tiramisu/api.py:873
msgid "only multi value has defaultmulti" msgid "only multi value has defaultmulti"
msgstr "seule les valeurs multiple a l'attribut defaultmulti" msgstr "seule les valeurs multiple a l'attribut defaultmulti"
#: tiramisu/api.py:1121 #: tiramisu/api.py:1037
msgid "please specify a valid sub function ({0}.{1}) for {2}" msgid "please specify a valid sub function ({0}.{1}) for {2}"
msgstr "veuillez spécifier une sous fonction valide ({0}.{1}) pour {2}" msgstr "veuillez spécifier une sous fonction valide ({0}.{1}) pour {2}"
#: tiramisu/api.py:1520 #: tiramisu/api.py:1424
msgid "properties must be a frozenset" msgid "properties must be a frozenset"
msgstr "une propriété doit être de type frozenset" msgstr "une propriété doit être de type frozenset"
#: tiramisu/api.py:1524 tiramisu/api.py:1551 #: tiramisu/api.py:1428 tiramisu/api.py:1455
msgid "unknown when {} (must be in append or remove)" msgid "unknown when {} (must be in append or remove)"
msgstr "value {} inconsistent (doit être append ou remove)" msgstr "value {} inconsistent (doit être append ou remove)"
#: tiramisu/api.py:1537 tiramisu/api.py:1561 tiramisu/config.py:1691 #: tiramisu/api.py:1441 tiramisu/api.py:1465 tiramisu/config.py:1676
msgid "unknown type {}" msgid "unknown type {}"
msgstr "type inconnu {}" msgstr "type inconnu {}"
#: tiramisu/api.py:1927 #: tiramisu/api.py:1829
msgid "do not use unrestraint, nowarnings or forcepermissive together" msgid "do not use unrestraint, nowarnings or forcepermissive together"
msgstr "" msgstr ""
"il ne faut pas utiliser unrestraint, nowarnings ou forcepermissive ensemble" "il ne faut pas utiliser unrestraint, nowarnings ou forcepermissive ensemble"
@ -183,29 +183,29 @@ msgstr "le premier argument ({0}) doit être une fonction"
msgid "help_function ({0}) must be a function" msgid "help_function ({0}) must be a function"
msgstr "help_function ({0}) doit être une fonction" msgstr "help_function ({0}) doit être une fonction"
#: tiramisu/autolib.py:469 tiramisu/autolib.py:525 #: tiramisu/autolib.py:469 tiramisu/autolib.py:524
msgid "the option {0} is used in a calculation but is invalid ({1})" msgid "the option {0} is used in a calculation but is invalid ({1})"
msgstr "l'option {0} est utilisé dans un calcul mais est invalide ({1})" msgstr "l'option {0} est utilisé dans un calcul mais est invalide ({1})"
#: tiramisu/autolib.py:482 tiramisu/autolib.py:539 tiramisu/autolib.py:589 #: tiramisu/autolib.py:482 tiramisu/autolib.py:538 tiramisu/autolib.py:588
msgid "unable to get value for calculating {0}, {1}" msgid "unable to get value for calculating {0}, {1}"
msgstr "impossible de trouver la valeur pour calculer {0}, {1}" msgstr "impossible de trouver la valeur pour calculer {0}, {1}"
#: tiramisu/autolib.py:518 #: tiramisu/autolib.py:517
msgid "unable to carry out a calculation for {0}, {1}" msgid "unable to carry out a calculation for {0}, {1}"
msgstr "impossible d'effectuer le calcul pour {0}, {1}" msgstr "impossible d'effectuer le calcul pour {0}, {1}"
#: tiramisu/autolib.py:564 #: tiramisu/autolib.py:563
msgid "cannot find information for {0}, {1} is a dynamic option" msgid "cannot find information for {0}, {1} is a dynamic option"
msgstr "ne peut trouver l'information pour {0}, {1} est une option dynamique" msgstr "ne peut trouver l'information pour {0}, {1} est une option dynamique"
#: tiramisu/autolib.py:604 #: tiramisu/autolib.py:603
msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription" msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription"
msgstr "" msgstr ""
"l'option {0} n'est pas une dynoptiondescription ou n'est pas dans une " "l'option {0} n'est pas une dynoptiondescription ou n'est pas dans une "
"dynoptiondescription" "dynoptiondescription"
#: tiramisu/autolib.py:697 #: tiramisu/autolib.py:696
msgid "" msgid ""
"cannot calculate arguments for {0}, {1} with identifier \"{2}\", there is no " "cannot calculate arguments for {0}, {1} with identifier \"{2}\", there is no "
"identifiers" "identifiers"
@ -213,7 +213,7 @@ msgstr ""
"impossible de calculer les arguments de {0}, {1} avec l'identifiant \"{2}\", " "impossible de calculer les arguments de {0}, {1} avec l'identifiant \"{2}\", "
"il n'y a pas d'identifiants" "il n'y a pas d'identifiants"
#: tiramisu/autolib.py:709 #: tiramisu/autolib.py:708
msgid "" msgid ""
"cannot calculate arguments for {0}, {1} with identifier \"{2}\", list of " "cannot calculate arguments for {0}, {1} with identifier \"{2}\", list of "
"valid identifiers: {3}" "valid identifiers: {3}"
@ -221,12 +221,12 @@ msgstr ""
"impossible de calculer les arguments de {0}, {1} avec l'identifiant \"{2}\", " "impossible de calculer les arguments de {0}, {1} avec l'identifiant \"{2}\", "
"voici la liste des identifiants valables : {3}" "voici la liste des identifiants valables : {3}"
#: tiramisu/autolib.py:820 #: tiramisu/autolib.py:819
msgid "the follower {0} must have index in carry_out_calculation!" msgid "the follower {0} must have index in carry_out_calculation!"
msgstr "" msgstr ""
"la variable suiveuse {0} doit avoir un index dans carry_out_calculation!" "la variable suiveuse {0} doit avoir un index dans carry_out_calculation!"
#: tiramisu/autolib.py:932 #: tiramisu/autolib.py:931
msgid "" msgid ""
"unexpected error \"{1}\" in function \"{2}\" with arguments \"{3}\" and " "unexpected error \"{1}\" in function \"{2}\" with arguments \"{3}\" and "
"\"{4}\" for option {0}" "\"{4}\" for option {0}"
@ -234,54 +234,50 @@ msgstr ""
"erreur inattendue \"{1}\" dans la fonction \"{2}\" avec les arguments " "erreur inattendue \"{1}\" dans la fonction \"{2}\" avec les arguments "
"\"{3}\" et \"{4}\" pour l'option {0}" "\"{3}\" et \"{4}\" pour l'option {0}"
#: tiramisu/autolib.py:942 #: tiramisu/autolib.py:941
msgid "unexpected error \"{1}\" in function \"{2}\" for option {0}" msgid "unexpected error \"{1}\" in function \"{2}\" for option {0}"
msgstr "erreur inattendue \"{1}\" dans la fonction \"{2}\" pour l'option {0}" msgstr "erreur inattendue \"{1}\" dans la fonction \"{2}\" pour l'option {0}"
#: tiramisu/config.py:391 tiramisu/config.py:413 #: tiramisu/config.py:574
msgid "option name {0} is not unique in {1}"
msgstr "le nom de l'option {0} n'est pas unique dans {1}"
#: tiramisu/config.py:638
msgid "there is no option description for this config (may be GroupConfig)" msgid "there is no option description for this config (may be GroupConfig)"
msgstr "" msgstr ""
"il n'y a pas d'option description trouvé pour cette config (peut être un " "il n'y a pas d'option description trouvé pour cette config (peut être un "
"GroupConfig)" "GroupConfig)"
#: tiramisu/config.py:989 tiramisu/option/optiondescription.py:74 #: tiramisu/config.py:663
msgid "no option found in config with these criteria"
msgstr "aucune option trouvée dans la config avec ces critères"
#: tiramisu/config.py:978 tiramisu/option/optiondescription.py:74
msgid "option description seems to be part of an other config" msgid "option description seems to be part of an other config"
msgstr "l'option description semble faire parti d'une autre config" msgstr "l'option description semble faire parti d'une autre config"
#: tiramisu/config.py:1151 #: tiramisu/config.py:1140
msgid "parent of {0} not already exists" msgid "parent of {0} not already exists"
msgstr "le parent de {0} n'existe plus" msgstr "le parent de {0} n'existe plus"
#: tiramisu/config.py:1198 #: tiramisu/config.py:1187
msgid "cannot set leadership object has root optiondescription" msgid "cannot set leadership object has root optiondescription"
msgstr "ne peut assigner un objet leadership comme optiondescription racine" msgstr "ne peut assigner un objet leadership comme optiondescription racine"
#: tiramisu/config.py:1201 #: tiramisu/config.py:1190
msgid "cannot set dynoptiondescription object has root optiondescription" msgid "cannot set dynoptiondescription object has root optiondescription"
msgstr "" msgstr ""
"ne peut assigner un objet dynoptiondescription comme optiondescription racine" "ne peut assigner un objet dynoptiondescription comme optiondescription racine"
#: tiramisu/config.py:1248 #: tiramisu/config.py:1242
msgid "child must be a Config, GroupConfig, MixConfig or MetaConfig"
msgstr "l'enfant doit être une Config, GroupConfig, MixConfig ou MetaConfig"
#: tiramisu/config.py:1257
msgid "config name must be uniq in groupconfig for \"{0}\"" msgid "config name must be uniq in groupconfig for \"{0}\""
msgstr "le nom d'un config doit être unique dans un groupconfig pour \"{0}\"" msgstr "le nom d'un config doit être unique dans un groupconfig pour \"{0}\""
#: tiramisu/config.py:1466 #: tiramisu/config.py:1453
msgid "unknown config \"{}\"" msgid "unknown config \"{}\""
msgstr "config \"{}\" inconnue" msgstr "config \"{}\" inconnue"
#: tiramisu/config.py:1491 #: tiramisu/config.py:1478
msgid "child must be a Config, MixConfig or MetaConfig" msgid "child must be a Config, MixConfig or MetaConfig"
msgstr "l'enfant doit être une Config, MixConfig ou MetaConfig" msgstr "l'enfant doit être une Config, MixConfig ou MetaConfig"
#: tiramisu/config.py:1526 #: tiramisu/config.py:1513
msgid "" msgid ""
"force_default, force_default_if_same or force_dont_change_value cannot be " "force_default, force_default_if_same or force_dont_change_value cannot be "
"set with only_config" "set with only_config"
@ -289,43 +285,43 @@ msgstr ""
"force_default, force_default_if_same ou force_dont_change_value ne peuvent " "force_default, force_default_if_same ou force_dont_change_value ne peuvent "
"pas être spécifié avec only_config" "pas être spécifié avec only_config"
#: tiramisu/config.py:1536 #: tiramisu/config.py:1523
msgid "force_default and force_dont_change_value cannot be set together" msgid "force_default and force_dont_change_value cannot be set together"
msgstr "" msgstr ""
"force_default et force_dont_change_value ne peuvent pas être mis ensemble" "force_default et force_dont_change_value ne peuvent pas être mis ensemble"
#: tiramisu/config.py:1687 #: tiramisu/config.py:1672
msgid "config name must be uniq in groupconfig for {0}" msgid "config name must be uniq in groupconfig for {0}"
msgstr "le nom de la config doit être unique dans un groupconfig pour {0}" msgstr "le nom de la config doit être unique dans un groupconfig pour {0}"
#: tiramisu/config.py:1732 #: tiramisu/config.py:1717
msgid "config added has no name, the name is mandatory" msgid "config added has no name, the name is mandatory"
msgstr "la config ajoutée n'a pas de nom, le nom est obligatoire" msgstr "la config ajoutée n'a pas de nom, le nom est obligatoire"
#: tiramisu/config.py:1737 #: tiramisu/config.py:1722
msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\"" msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\""
msgstr "" msgstr ""
"le nom d'un config \"{0}\" n'est pas unique dans le groupconfig \"{1}\"" "le nom d'un config \"{0}\" n'est pas unique dans le groupconfig \"{1}\""
#: tiramisu/config.py:1755 tiramisu/config.py:1761 #: tiramisu/config.py:1740 tiramisu/config.py:1746
msgid "cannot find the config {0}" msgid "cannot find the config {0}"
msgstr "ne peut pas trouver la config {0}" msgstr "ne peut pas trouver la config {0}"
#: tiramisu/config.py:1787 #: tiramisu/config.py:1772
msgid "MetaConfig with optiondescription must have string has child, not {}" msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr "" msgstr ""
"MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}" "MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}"
#: tiramisu/config.py:1799 #: tiramisu/config.py:1784
msgid "child must be a Config or MetaConfig" msgid "child must be a Config or MetaConfig"
msgstr "enfant doit être une une Config ou une MetaConfig" msgstr "enfant doit être une une Config ou une MetaConfig"
#: tiramisu/config.py:1804 #: tiramisu/config.py:1789
msgid "all config in metaconfig must have the same optiondescription" msgid "all config in metaconfig must have the same optiondescription"
msgstr "" msgstr ""
"toutes les configs d'une metaconfig doivent avoir la même optiondescription" "toutes les configs d'une metaconfig doivent avoir la même optiondescription"
#: tiramisu/config.py:1821 #: tiramisu/config.py:1806
msgid "metaconfig must have the same optiondescription" msgid "metaconfig must have the same optiondescription"
msgstr "metaconfig doivent avoir la même optiondescription" msgstr "metaconfig doivent avoir la même optiondescription"
@ -358,6 +354,8 @@ msgid "cannot modify the {0} {1} because is frozen"
msgstr "ne peut modifier {0} {1} parce qu'est frozen" msgstr "ne peut modifier {0} {1} parce qu'est frozen"
#: tiramisu/error.py:160 #: tiramisu/error.py:160
#, fuzzy
#| msgid "cannot access to {0} {1} at index \"{2}\" because {2} hasn't value"
msgid "cannot access to {0} {1} at index \"{2}\" because {3} hasn't value" msgid "cannot access to {0} {1} at index \"{2}\" because {3} hasn't value"
msgstr "" msgstr ""
"ne peut accéder à {0} {1} à l'index \"{2}\" parce que {3} n'a pas de valeur" "ne peut accéder à {0} {1} à l'index \"{2}\" parce que {3} n'a pas de valeur"
@ -457,24 +455,24 @@ msgstr ""
"la fonction \"{0}\" ne doit pas retourner une liste (\"{1}\") pour l'option " "la fonction \"{0}\" ne doit pas retourner une liste (\"{1}\") pour l'option "
"suiveuse {2}" "suiveuse {2}"
#: tiramisu/error.py:333 #: tiramisu/error.py:331
msgid "invalid value" msgid "invalid value"
msgstr "valeur invalide" msgstr "valeur invalide"
#: tiramisu/error.py:343 #: tiramisu/error.py:341
msgid "attention, \"{0}\" could be an invalid {1} for {2}" msgid "attention, \"{0}\" could be an invalid {1} for {2}"
msgstr "attention, \"{0}\" peut être un {1} invalide pour {2}" msgstr "attention, \"{0}\" peut être un {1} invalide pour {2}"
#: tiramisu/error.py:347 #: tiramisu/error.py:345
msgid "attention, \"{0}\" could be an invalid {1} for {2} at index \"{3}\"" msgid "attention, \"{0}\" could be an invalid {1} for {2} at index \"{3}\""
msgstr "" msgstr ""
"attention, \"{0}\" peut être un {1} invalide pour {2} à l'index \"{3}\"" "attention, \"{0}\" peut être un {1} invalide pour {2} à l'index \"{3}\""
#: tiramisu/error.py:368 tiramisu/error.py:379 #: tiramisu/error.py:366 tiramisu/error.py:377
msgid "\"{0}\" is an invalid {1} for {2}" msgid "\"{0}\" is an invalid {1} for {2}"
msgstr "\"{0}\" est une valeur invalide pour l'option {2} de type {1}" msgstr "\"{0}\" est une valeur invalide pour l'option {2} de type {1}"
#: tiramisu/error.py:370 #: tiramisu/error.py:368
msgid "\"{0}\" is an invalid {1} for {2} at index \"{3}\"" msgid "\"{0}\" is an invalid {1} for {2} at index \"{3}\""
msgstr "\"{0}\" est un {1} invalide pour {2} à l'index \"{3}\"" msgstr "\"{0}\" est un {1} invalide pour {2} à l'index \"{3}\""
@ -549,33 +547,33 @@ msgstr "la valeur de \"{0}\" est {1}"
msgid "the value of \"{0}\" is not {1}" msgid "the value of \"{0}\" is not {1}"
msgstr "la valeur de \"{0}\" n'est pas {1}" msgstr "la valeur de \"{0}\" n'est pas {1}"
#: tiramisu/option/baseoption.py:76 tiramisu/option/symlinkoption.py:44 #: tiramisu/option/baseoption.py:75 tiramisu/option/symlinkoption.py:44
msgid "\"{0}\" is an invalid name for an option" msgid "\"{0}\" is an invalid name for an option"
msgstr "\"{0}\" est un nom invalide pour une option" msgstr "\"{0}\" est un nom invalide pour une option"
#: tiramisu/option/baseoption.py:89 #: tiramisu/option/baseoption.py:88
msgid "invalid properties type {0} for {1}, must be a frozenset" msgid "invalid properties type {0} for {1}, must be a frozenset"
msgstr "type {0} invalide pour des propriétés pour {1}, doit être un frozenset" msgstr "type {0} invalide pour des propriétés pour {1}, doit être un frozenset"
#: tiramisu/option/baseoption.py:102 #: tiramisu/option/baseoption.py:100
msgid "invalid property type {0} for {1}, must be a string or a Calculation" msgid "invalid property type {0} for {1}, must be a string or a Calculation"
msgstr "" msgstr ""
"type {0} invalide pour des propriétés pour {1}, doit être des caractères ou " "type {0} invalide pour des propriétés pour {1}, doit être des caractères ou "
"un objet Calculation" "un objet Calculation"
#: tiramisu/option/baseoption.py:253 #: tiramisu/option/baseoption.py:251
msgid "information's item for {0} not found: \"{1}\"" msgid "information's item for {0} not found: \"{1}\""
msgstr "item pour {0} dans les informations non trouvée: \"{1}\"" msgstr "item pour {0} dans les informations non trouvée: \"{1}\""
#: tiramisu/option/baseoption.py:271 #: tiramisu/option/baseoption.py:269
msgid "'{0}' ({1}) object attribute '{2}' is read-only" msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule" msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
#: tiramisu/option/baseoption.py:312 #: tiramisu/option/baseoption.py:310
msgid "\"{}\" ({}) object attribute \"{}\" is read-only" msgid "\"{}\" ({}) object attribute \"{}\" is read-only"
msgstr "\"{}\" ({}) l'attribut de l'objet \"{}\" est en lecture seule" msgstr "\"{}\" ({}) l'attribut de l'objet \"{}\" est en lecture seule"
#: tiramisu/option/baseoption.py:324 #: tiramisu/option/baseoption.py:322
msgid "{0} not part of any Config" msgid "{0} not part of any Config"
msgstr "{0} ne fait pas parti d'une Config" msgstr "{0} ne fait pas parti d'une Config"
@ -583,19 +581,19 @@ msgstr "{0} ne fait pas parti d'une Config"
msgid "invalid string" msgid "invalid string"
msgstr "invalide caractère" msgstr "invalide caractère"
#: tiramisu/option/choiceoption.py:52 #: tiramisu/option/choiceoption.py:47
msgid "values must be a tuple or a calculation for {0}" msgid "values must be a tuple or a calculation for {0}"
msgstr "les valeurs doivent être un tuple ou une fonction pour {0}" msgstr "les valeurs doivent être un tuple ou une fonction pour {0}"
#: tiramisu/option/choiceoption.py:75 #: tiramisu/option/choiceoption.py:70
msgid "the calculated values \"{0}\" for \"{1}\" is not a list" msgid "the calculated values \"{0}\" for \"{1}\" is not a list"
msgstr "les valeurs calculées \"{0}\" pour \"{1}\" n'est pas une liste" msgstr "les valeurs calculées \"{0}\" pour \"{1}\" n'est pas une liste"
#: tiramisu/option/choiceoption.py:106 #: tiramisu/option/choiceoption.py:101
msgid "only \"{0}\" is allowed" msgid "only \"{0}\" is allowed"
msgstr "seul \"{0}\" est autorisé" msgstr "seul \"{0}\" est autorisé"
#: tiramisu/option/choiceoption.py:108 #: tiramisu/option/choiceoption.py:103
msgid "only {0} are allowed" msgid "only {0} are allowed"
msgstr "seul {0} sont autorisées" msgstr "seul {0} sont autorisées"
@ -698,7 +696,7 @@ msgstr ""
msgid "invalid identifier \"{}\" for option {}" msgid "invalid identifier \"{}\" for option {}"
msgstr "identifiant \"{}\" invalide pour l'option \"{}\"" msgstr "identifiant \"{}\" invalide pour l'option \"{}\""
#: tiramisu/option/dynoptiondescription.py:154 #: tiramisu/option/dynoptiondescription.py:150
msgid "" msgid ""
"DynOptionDescription \"{0}\" identifiers return a list with same values " "DynOptionDescription \"{0}\" identifiers return a list with same values "
"\"{1}\"" "\"{1}\""
@ -849,47 +847,44 @@ msgstr ""
#: tiramisu/option/option.py:294 #: tiramisu/option/option.py:294
msgid "the value \"{}\" is not unique" msgid "the value \"{}\" is not unique"
msgstr "la valeur \"{}\" n'est pas unique" msgstr "la valeur de \"{}\" n'est pas unique"
#: tiramisu/option/option.py:357 #: tiramisu/option/option.py:356
msgid "which must not be a list" msgid "which must not be a list"
msgstr "qui ne doit pas être une liste" msgstr "qui ne doit pas être une liste"
#: tiramisu/option/option.py:412 tiramisu/option/option.py:450 #: tiramisu/option/option.py:408 tiramisu/option/option.py:434
msgid "which must be a list" msgid "which must be a list"
msgstr "qui doit être une liste" msgstr "qui doit être une liste"
#: tiramisu/option/option.py:440 #: tiramisu/option/option.py:428
msgid "which \"{}\" must be a list of list" msgid "which \"{}\" must be a list of list"
msgstr "lequel \"{}\" doit être une liste de liste" msgstr "lequel \"{}\" doit être une liste de liste"
#: tiramisu/option/optiondescription.py:111 #: tiramisu/option/optiondescription.py:109
#: tiramisu/option/optiondescription.py:117 msgid "duplicate option: {0}"
msgid "\"{0}\" option description" msgstr "option dupliquée : {0}"
msgstr "l'option description \"{0}\""
#: tiramisu/option/optiondescription.py:115 #: tiramisu/option/optiondescription.py:336
#: tiramisu/option/optiondescription.py:121
msgid "root option description"
msgstr "l'option description racine"
#: tiramisu/option/optiondescription.py:123
msgid "option \"{0}\" is include in {1} but is also in {2}"
msgstr "l'option \"{0}\" est incluse dans {1} mais est aussi dans {2}"
#: tiramisu/option/optiondescription.py:328
msgid "children in optiondescription \"{}\" must be a list" msgid "children in optiondescription \"{}\" must be a list"
msgstr "les enfants d'une optiondescription \"{}\" doivent être une liste" msgstr "les enfants d'une optiondescription \"{}\" doivent être une liste"
#: tiramisu/option/optiondescription.py:357 #: tiramisu/option/optiondescription.py:364
msgid "the option name \"{0}\" is duplicate in \"{1}\"" msgid "duplicate option name: \"{0}\""
msgstr "le nom de l'option \"{0}\" est dupliqué dans \"{1}\"" msgstr "nom de l'option dupliqué : \"{0}\""
#: tiramisu/option/optiondescription.py:411 #: tiramisu/option/optiondescription.py:370
msgid ""
"the option's name \"{0}\" start as the dynoptiondescription's name \"{1}\""
msgstr ""
"le nom de l'option \"{0}\" commence comme le nom du dynoptiondescription "
"\"{1}\""
#: tiramisu/option/optiondescription.py:413
msgid "cannot change group_type if already set (old {0}, new {1})" msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1})" msgstr "ne peut changer group_type si déjà spécifié (ancien {0}, nouveau {1})"
#: tiramisu/option/optiondescription.py:416 #: tiramisu/option/optiondescription.py:418
msgid "group_type: {0} not allowed" msgid "group_type: {0} not allowed"
msgstr "group_type : {0} non autorisé" msgstr "group_type : {0} non autorisé"
@ -930,27 +925,27 @@ msgstr "{0} a plus de droit que {1}"
msgid "too weak" msgid "too weak"
msgstr "trop simple" msgstr "trop simple"
#: tiramisu/option/portoption.py:77 #: tiramisu/option/portoption.py:80
msgid "inconsistency in allowed range" msgid "inconsistency in allowed range"
msgstr "inconsistence dans la plage autorisée" msgstr "inconsistence dans la plage autorisée"
#: tiramisu/option/portoption.py:82 #: tiramisu/option/portoption.py:85
msgid "max value is empty" msgid "max value is empty"
msgstr "la valeur maximum est vide" msgstr "la valeur maximum est vide"
#: tiramisu/option/portoption.py:95 #: tiramisu/option/portoption.py:98
msgid "range must have two values only" msgid "range must have two values only"
msgstr "un rang doit avoir deux valeurs seulement" msgstr "un rang doit avoir deux valeurs seulement"
#: tiramisu/option/portoption.py:98 #: tiramisu/option/portoption.py:101
msgid "first port in range must be smaller than the second one" msgid "first port in range must be smaller than the second one"
msgstr "le premier port d'un rang doit être plus petit que le second" msgstr "le premier port d'un rang doit être plus petit que le second"
#: tiramisu/option/portoption.py:124 #: tiramisu/option/portoption.py:127
msgid "should be between {0} and {1}" msgid "should be between {0} and {1}"
msgstr "devrait être une nombre entre {0} et {1}" msgstr "devrait être une nombre entre {0} et {1}"
#: tiramisu/option/portoption.py:126 #: tiramisu/option/portoption.py:129
msgid "must be between {0} and {1}" msgid "must be between {0} and {1}"
msgstr "doit être une nombre entre {0} et {1}" msgstr "doit être une nombre entre {0} et {1}"
@ -994,8 +989,8 @@ msgid ""
"invalid property type {type(new_prop)} for {subconfig.option.impl_getname()} " "invalid property type {type(new_prop)} for {subconfig.option.impl_getname()} "
"with {prop.function.__name__} function" "with {prop.function.__name__} function"
msgstr "" msgstr ""
"type {type(new_prop)} de la propriété invalide pour la fonction " "type {type(new_prop)} de la propriété invalide pour la fonction {subconfig."
"{subconfig.option.impl_getname()} with {prop.function.__name__}" "option.impl_getname()} with {prop.function.__name__}"
#: tiramisu/setting.py:606 #: tiramisu/setting.py:606
msgid "permissive must be a frozenset" msgid "permissive must be a frozenset"
@ -1039,42 +1034,28 @@ msgstr ""
msgid "unknown action {}" msgid "unknown action {}"
msgstr "action inconnue {}" msgstr "action inconnue {}"
#: tiramisu/value.py:557 tiramisu/value.py:859 #: tiramisu/value.py:570 tiramisu/value.py:872
msgid "set owner \"{0}\" is forbidden" msgid "set owner \"{0}\" is forbidden"
msgstr "assigner l'utilisateur \"{0}\" est interdit" msgstr "assigner l'utilisateur \"{0}\" est interdit"
#: tiramisu/value.py:564 #: tiramisu/value.py:577
msgid "\"{0}\" is a default value, so we cannot change owner to \"{1}\"" msgid "\"{0}\" is a default value, so we cannot change owner to \"{1}\""
msgstr "" msgstr ""
"\"{0}\" est une valeur par défaut, donc ne peut changer d'utilisateur à " "\"{0}\" est une valeur par défaut, donc ne peut changer d'utilisateur à "
"\"{1}\"" "\"{1}\""
#: tiramisu/value.py:845 #: tiramisu/value.py:751
msgid ""
"index {index} is greater than the length {length} for option {subconfig."
"option.impl_get_display_name(with_quote=True)}"
msgstr ""
"l'index {index} est supérieur à la longueur \"{length}\" pour l'option "
"\"{subconfig.option.impl_get_display_name(with_quote=True)}\""
#: tiramisu/value.py:858
msgid "information's item not found \"{}\"" msgid "information's item not found \"{}\""
msgstr "l'information de l'objet ne sont pas trouvé \"{}\"" msgstr "l'information de l'objet ne sont pas trouvé \"{}\""
#~ msgid "no option found in config with these criteria"
#~ msgstr "aucune option trouvée dans la config avec ces critères"
#~ msgid ""
#~ "the option's name \"{0}\" start as the dynoptiondescription's name \"{1}\""
#~ msgstr ""
#~ "le nom de l'option \"{0}\" commence comme le nom du dynoptiondescription "
#~ "\"{1}\""
#~ msgid "duplicate option name: \"{0}\""
#~ msgstr "nom de l'option dupliqué : \"{0}\""
#~ msgid "duplicate option: {0}"
#~ msgstr "option dupliquée : {0}"
#~ msgid ""
#~ "index {index} is greater than the length {length} for option "
#~ "{subconfig.option.impl_get_display_name(with_quote=True)}"
#~ msgstr ""
#~ "l'index {index} est supérieur à la longueur \"{length}\" pour l'option "
#~ "\"{subconfig.option.impl_get_display_name(with_quote=True)}\""
#~ msgid "cannot find \"{0}\" in \"{1}\"" #~ msgid "cannot find \"{0}\" in \"{1}\""
#~ msgstr "ne peut pas trouver \"{0}\" dans \"{1}\"" #~ msgstr "ne peut pas trouver \"{0}\" dans \"{1}\""
@ -1096,6 +1077,9 @@ msgstr "l'information de l'objet ne sont pas trouvé \"{}\""
#~ msgid "unknown option \"{0}\" in root optiondescription" #~ msgid "unknown option \"{0}\" in root optiondescription"
#~ msgstr "option \"{0}\" inconnue dans l'optiondescription racine" #~ msgstr "option \"{0}\" inconnue dans l'optiondescription racine"
#~ msgid "unknown option \"{0}\" in optiondescription {1}"
#~ msgstr "option \"{0}\" inconnue dans l'optiondescription {1}"
#~ msgid "" #~ msgid ""
#~ "IP \"{ip[\"value\"]}\" ({ip[\"name\"]}) with this netmask is in fact a " #~ "IP \"{ip[\"value\"]}\" ({ip[\"name\"]}) with this netmask is in fact a "
#~ "broacast address" #~ "broacast address"
@ -1106,6 +1090,9 @@ msgstr "l'information de l'objet ne sont pas trouvé \"{}\""
#~ msgid "Call: {}" #~ msgid "Call: {}"
#~ msgstr "Appel : {}" #~ msgstr "Appel : {}"
#~ msgid "option must not be an optiondescription"
#~ msgstr "option ne doit pas être une optiondescription"
#~ msgid "index must be set with the follower option \"{}\"" #~ msgid "index must be set with the follower option \"{}\""
#~ msgstr "l'index est obligatoire pour l'option suiveuse \"{}\"" #~ msgstr "l'index est obligatoire pour l'option suiveuse \"{}\""
@ -1127,6 +1114,9 @@ msgstr "l'information de l'objet ne sont pas trouvé \"{}\""
#~ msgid "cannot set session_id and config together" #~ msgid "cannot set session_id and config together"
#~ msgstr "session_id et config ne peut être mis ensemble" #~ msgstr "session_id et config ne peut être mis ensemble"
#~ msgid "\"{0}\" must be an optiondescription, not an {1}"
#~ msgstr "\"{0}\" doit être une optiondescription, et non {1}"
#~ msgid "unknown option {}" #~ msgid "unknown option {}"
#~ msgstr "option {} inconnue" #~ msgstr "option {} inconnue"

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: 2025-09-19 22:05+0200\n" "POT-Creation-Date: 2025-05-12 09:05+0200\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,95 +15,95 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
#: tiramisu/api.py:86 #: tiramisu/api.py:79
msgid "Settings:" msgid "Settings:"
msgstr "" msgstr ""
#: tiramisu/api.py:90 #: tiramisu/api.py:83
msgid "Access to option without verifying permissive properties" msgid "Access to option without verifying permissive properties"
msgstr "" msgstr ""
#: tiramisu/api.py:95 #: tiramisu/api.py:88
msgid "Access to option without property restriction" msgid "Access to option without property restriction"
msgstr "" msgstr ""
#: tiramisu/api.py:100 #: tiramisu/api.py:93
msgid "Do not warnings during validation" msgid "Do not warnings during validation"
msgstr "" msgstr ""
#: tiramisu/api.py:104 #: tiramisu/api.py:97
msgid "Commands:" msgid "Commands:"
msgstr "" msgstr ""
#: tiramisu/api.py:118 tiramisu/api.py:1955 #: tiramisu/api.py:111 tiramisu/api.py:1857
msgid "please specify a valid sub function ({0}.{1})" msgid "please specify a valid sub function ({0}.{1})"
msgstr "" msgstr ""
#: tiramisu/api.py:206 #: tiramisu/api.py:196
msgid "please do not specify index ({0}.{1})" msgid "please do not specify index ({0}.{1})"
msgstr "" msgstr ""
#: tiramisu/api.py:211 tiramisu/api.py:940 #: tiramisu/api.py:201 tiramisu/api.py:856
msgid "please specify index with a follower option ({0}.{1})" msgid "please specify index with a follower option ({0}.{1})"
msgstr "" msgstr ""
#: tiramisu/api.py:234 #: tiramisu/api.py:222
msgid "please specify a valid sub function ({0}.{1}): {2}" msgid "please specify a valid sub function ({0}.{1}): {2}"
msgstr "" msgstr ""
#: tiramisu/api.py:525 #: tiramisu/api.py:446
msgid "the option {0} is not a dynamic option, cannot get identifiers with only_self parameter to True" msgid "the option {0} is not a dynamic option, cannot get identifiers with only_self parameter to True"
msgstr "" msgstr ""
#: tiramisu/api.py:613 #: tiramisu/api.py:532
msgid "cannot get option from a follower symlink without index" msgid "cannot get option from a follower symlink without index"
msgstr "" msgstr ""
#: tiramisu/api.py:691 #: tiramisu/api.py:607
msgid "cannot add this property: \"{0}\"" msgid "cannot add this property: \"{0}\""
msgstr "" msgstr ""
#: tiramisu/api.py:718 #: tiramisu/api.py:634
msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\"" msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\""
msgstr "" msgstr ""
#: tiramisu/api.py:722 #: tiramisu/api.py:638
msgid "cannot find \"{0}\" in option \"{1}\"" msgid "cannot find \"{0}\" in option \"{1}\""
msgstr "" msgstr ""
#: tiramisu/api.py:727 #: tiramisu/api.py:643
msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\" at index \"{2}\"" msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\" at index \"{2}\""
msgstr "" msgstr ""
#: tiramisu/api.py:731 #: tiramisu/api.py:647
msgid "cannot find \"{0}\" in option \"{1}\" at index \"{2}\"" msgid "cannot find \"{0}\" in option \"{1}\" at index \"{2}\""
msgstr "" msgstr ""
#: tiramisu/api.py:775 #: tiramisu/api.py:691
msgid "cannot find \"{0}\"" msgid "cannot find \"{0}\""
msgstr "" msgstr ""
#: tiramisu/api.py:957 #: tiramisu/api.py:873
msgid "only multi value has defaultmulti" msgid "only multi value has defaultmulti"
msgstr "" msgstr ""
#: tiramisu/api.py:1121 #: tiramisu/api.py:1037
msgid "please specify a valid sub function ({0}.{1}) for {2}" msgid "please specify a valid sub function ({0}.{1}) for {2}"
msgstr "" msgstr ""
#: tiramisu/api.py:1520 #: tiramisu/api.py:1424
msgid "properties must be a frozenset" msgid "properties must be a frozenset"
msgstr "" msgstr ""
#: tiramisu/api.py:1524 tiramisu/api.py:1551 #: tiramisu/api.py:1428 tiramisu/api.py:1455
msgid "unknown when {} (must be in append or remove)" msgid "unknown when {} (must be in append or remove)"
msgstr "" msgstr ""
#: tiramisu/api.py:1537 tiramisu/api.py:1561 tiramisu/config.py:1691 #: tiramisu/api.py:1441 tiramisu/api.py:1465 tiramisu/config.py:1676
msgid "unknown type {}" msgid "unknown type {}"
msgstr "" msgstr ""
#: tiramisu/api.py:1927 #: tiramisu/api.py:1829
msgid "do not use unrestraint, nowarnings or forcepermissive together" msgid "do not use unrestraint, nowarnings or forcepermissive together"
msgstr "" msgstr ""
@ -167,123 +167,119 @@ msgstr ""
msgid "help_function ({0}) must be a function" msgid "help_function ({0}) must be a function"
msgstr "" msgstr ""
#: tiramisu/autolib.py:469 tiramisu/autolib.py:525 #: tiramisu/autolib.py:469 tiramisu/autolib.py:524
msgid "the option {0} is used in a calculation but is invalid ({1})" msgid "the option {0} is used in a calculation but is invalid ({1})"
msgstr "" msgstr ""
#: tiramisu/autolib.py:482 tiramisu/autolib.py:539 tiramisu/autolib.py:589 #: tiramisu/autolib.py:482 tiramisu/autolib.py:538 tiramisu/autolib.py:588
msgid "unable to get value for calculating {0}, {1}" msgid "unable to get value for calculating {0}, {1}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:518 #: tiramisu/autolib.py:517
msgid "unable to carry out a calculation for {0}, {1}" msgid "unable to carry out a calculation for {0}, {1}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:564 #: tiramisu/autolib.py:563
msgid "cannot find information for {0}, {1} is a dynamic option" msgid "cannot find information for {0}, {1} is a dynamic option"
msgstr "" msgstr ""
#: tiramisu/autolib.py:604 #: tiramisu/autolib.py:603
msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription" msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription"
msgstr "" msgstr ""
#: tiramisu/autolib.py:697 #: tiramisu/autolib.py:696
msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", there is no identifiers" msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", there is no identifiers"
msgstr "" msgstr ""
#: tiramisu/autolib.py:709 #: tiramisu/autolib.py:708
msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", list of valid identifiers: {3}" msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", list of valid identifiers: {3}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:820 #: tiramisu/autolib.py:819
msgid "the follower {0} must have index in carry_out_calculation!" msgid "the follower {0} must have index in carry_out_calculation!"
msgstr "" msgstr ""
#: tiramisu/autolib.py:932 #: tiramisu/autolib.py:931
msgid "unexpected error \"{1}\" in function \"{2}\" with arguments \"{3}\" and \"{4}\" for option {0}" msgid "unexpected error \"{1}\" in function \"{2}\" with arguments \"{3}\" and \"{4}\" for option {0}"
msgstr "" msgstr ""
#: tiramisu/autolib.py:942 #: tiramisu/autolib.py:941
msgid "unexpected error \"{1}\" in function \"{2}\" for option {0}" msgid "unexpected error \"{1}\" in function \"{2}\" for option {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:391 tiramisu/config.py:413 #: tiramisu/config.py:574
msgid "option name {0} is not unique in {1}"
msgstr ""
#: tiramisu/config.py:638
msgid "there is no option description for this config (may be GroupConfig)" msgid "there is no option description for this config (may be GroupConfig)"
msgstr "" msgstr ""
#: tiramisu/config.py:989 tiramisu/option/optiondescription.py:74 #: tiramisu/config.py:663
msgid "no option found in config with these criteria"
msgstr ""
#: tiramisu/config.py:978 tiramisu/option/optiondescription.py:74
msgid "option description seems to be part of an other config" msgid "option description seems to be part of an other config"
msgstr "" msgstr ""
#: tiramisu/config.py:1151 #: tiramisu/config.py:1140
msgid "parent of {0} not already exists" msgid "parent of {0} not already exists"
msgstr "" msgstr ""
#: tiramisu/config.py:1198 #: tiramisu/config.py:1187
msgid "cannot set leadership object has root optiondescription" msgid "cannot set leadership object has root optiondescription"
msgstr "" msgstr ""
#: tiramisu/config.py:1201 #: tiramisu/config.py:1190
msgid "cannot set dynoptiondescription object has root optiondescription" msgid "cannot set dynoptiondescription object has root optiondescription"
msgstr "" msgstr ""
#: tiramisu/config.py:1248 #: tiramisu/config.py:1242
msgid "child must be a Config, GroupConfig, MixConfig or MetaConfig"
msgstr ""
#: tiramisu/config.py:1257
msgid "config name must be uniq in groupconfig for \"{0}\"" msgid "config name must be uniq in groupconfig for \"{0}\""
msgstr "" msgstr ""
#: tiramisu/config.py:1466 #: tiramisu/config.py:1453
msgid "unknown config \"{}\"" msgid "unknown config \"{}\""
msgstr "" msgstr ""
#: tiramisu/config.py:1491 #: tiramisu/config.py:1478
msgid "child must be a Config, MixConfig or MetaConfig" msgid "child must be a Config, MixConfig or MetaConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:1526 #: tiramisu/config.py:1513
msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config" msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config"
msgstr "" msgstr ""
#: tiramisu/config.py:1536 #: tiramisu/config.py:1523
msgid "force_default and force_dont_change_value cannot be set together" msgid "force_default and force_dont_change_value cannot be set together"
msgstr "" msgstr ""
#: tiramisu/config.py:1687 #: tiramisu/config.py:1672
msgid "config name must be uniq in groupconfig for {0}" msgid "config name must be uniq in groupconfig for {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:1732 #: tiramisu/config.py:1717
msgid "config added has no name, the name is mandatory" msgid "config added has no name, the name is mandatory"
msgstr "" msgstr ""
#: tiramisu/config.py:1737 #: tiramisu/config.py:1722
msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\"" msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\""
msgstr "" msgstr ""
#: tiramisu/config.py:1755 tiramisu/config.py:1761 #: tiramisu/config.py:1740 tiramisu/config.py:1746
msgid "cannot find the config {0}" msgid "cannot find the config {0}"
msgstr "" msgstr ""
#: tiramisu/config.py:1787 #: tiramisu/config.py:1772
msgid "MetaConfig with optiondescription must have string has child, not {}" msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr "" msgstr ""
#: tiramisu/config.py:1799 #: tiramisu/config.py:1784
msgid "child must be a Config or MetaConfig" msgid "child must be a Config or MetaConfig"
msgstr "" msgstr ""
#: tiramisu/config.py:1804 #: tiramisu/config.py:1789
msgid "all config in metaconfig must have the same optiondescription" msgid "all config in metaconfig must have the same optiondescription"
msgstr "" msgstr ""
#: tiramisu/config.py:1821 #: tiramisu/config.py:1806
msgid "metaconfig must have the same optiondescription" msgid "metaconfig must have the same optiondescription"
msgstr "" msgstr ""
@ -395,23 +391,23 @@ msgstr ""
msgid "the \"{0}\" function must not return a list (\"{1}\") for the follower option {2}" msgid "the \"{0}\" function must not return a list (\"{1}\") for the follower option {2}"
msgstr "" msgstr ""
#: tiramisu/error.py:333 #: tiramisu/error.py:331
msgid "invalid value" msgid "invalid value"
msgstr "" msgstr ""
#: tiramisu/error.py:343 #: tiramisu/error.py:341
msgid "attention, \"{0}\" could be an invalid {1} for {2}" msgid "attention, \"{0}\" could be an invalid {1} for {2}"
msgstr "" msgstr ""
#: tiramisu/error.py:347 #: tiramisu/error.py:345
msgid "attention, \"{0}\" could be an invalid {1} for {2} at index \"{3}\"" msgid "attention, \"{0}\" could be an invalid {1} for {2} at index \"{3}\""
msgstr "" msgstr ""
#: tiramisu/error.py:368 tiramisu/error.py:379 #: tiramisu/error.py:366 tiramisu/error.py:377
msgid "\"{0}\" is an invalid {1} for {2}" msgid "\"{0}\" is an invalid {1} for {2}"
msgstr "" msgstr ""
#: tiramisu/error.py:370 #: tiramisu/error.py:368
msgid "\"{0}\" is an invalid {1} for {2} at index \"{3}\"" msgid "\"{0}\" is an invalid {1} for {2} at index \"{3}\""
msgstr "" msgstr ""
@ -471,31 +467,31 @@ msgstr ""
msgid "the value of \"{0}\" is not {1}" msgid "the value of \"{0}\" is not {1}"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:76 tiramisu/option/symlinkoption.py:44 #: tiramisu/option/baseoption.py:75 tiramisu/option/symlinkoption.py:44
msgid "\"{0}\" is an invalid name for an option" msgid "\"{0}\" is an invalid name for an option"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:89 #: tiramisu/option/baseoption.py:88
msgid "invalid properties type {0} for {1}, must be a frozenset" msgid "invalid properties type {0} for {1}, must be a frozenset"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:102 #: tiramisu/option/baseoption.py:100
msgid "invalid property type {0} for {1}, must be a string or a Calculation" msgid "invalid property type {0} for {1}, must be a string or a Calculation"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:253 #: tiramisu/option/baseoption.py:251
msgid "information's item for {0} not found: \"{1}\"" msgid "information's item for {0} not found: \"{1}\""
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:271 #: tiramisu/option/baseoption.py:269
msgid "'{0}' ({1}) object attribute '{2}' is read-only" msgid "'{0}' ({1}) object attribute '{2}' is read-only"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:312 #: tiramisu/option/baseoption.py:310
msgid "\"{}\" ({}) object attribute \"{}\" is read-only" msgid "\"{}\" ({}) object attribute \"{}\" is read-only"
msgstr "" msgstr ""
#: tiramisu/option/baseoption.py:324 #: tiramisu/option/baseoption.py:322
msgid "{0} not part of any Config" msgid "{0} not part of any Config"
msgstr "" msgstr ""
@ -503,19 +499,19 @@ msgstr ""
msgid "invalid string" msgid "invalid string"
msgstr "" msgstr ""
#: tiramisu/option/choiceoption.py:52 #: tiramisu/option/choiceoption.py:47
msgid "values must be a tuple or a calculation for {0}" msgid "values must be a tuple or a calculation for {0}"
msgstr "" msgstr ""
#: tiramisu/option/choiceoption.py:75 #: tiramisu/option/choiceoption.py:70
msgid "the calculated values \"{0}\" for \"{1}\" is not a list" msgid "the calculated values \"{0}\" for \"{1}\" is not a list"
msgstr "" msgstr ""
#: tiramisu/option/choiceoption.py:106 #: tiramisu/option/choiceoption.py:101
msgid "only \"{0}\" is allowed" msgid "only \"{0}\" is allowed"
msgstr "" msgstr ""
#: tiramisu/option/choiceoption.py:108 #: tiramisu/option/choiceoption.py:103
msgid "only {0} are allowed" msgid "only {0} are allowed"
msgstr "" msgstr ""
@ -600,7 +596,7 @@ msgstr ""
msgid "invalid identifier \"{}\" for option {}" msgid "invalid identifier \"{}\" for option {}"
msgstr "" msgstr ""
#: tiramisu/option/dynoptiondescription.py:154 #: tiramisu/option/dynoptiondescription.py:150
msgid "DynOptionDescription \"{0}\" identifiers return a list with same values \"{1}\"" msgid "DynOptionDescription \"{0}\" identifiers return a list with same values \"{1}\""
msgstr "" msgstr ""
@ -736,45 +732,39 @@ msgstr ""
msgid "the value \"{}\" is not unique" msgid "the value \"{}\" is not unique"
msgstr "" msgstr ""
#: tiramisu/option/option.py:357 #: tiramisu/option/option.py:356
msgid "which must not be a list" msgid "which must not be a list"
msgstr "" msgstr ""
#: tiramisu/option/option.py:412 tiramisu/option/option.py:450 #: tiramisu/option/option.py:408 tiramisu/option/option.py:434
msgid "which must be a list" msgid "which must be a list"
msgstr "" msgstr ""
#: tiramisu/option/option.py:440 #: tiramisu/option/option.py:428
msgid "which \"{}\" must be a list of list" msgid "which \"{}\" must be a list of list"
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:111 #: tiramisu/option/optiondescription.py:109
#: tiramisu/option/optiondescription.py:117 msgid "duplicate option: {0}"
msgid "\"{0}\" option description"
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:115 #: tiramisu/option/optiondescription.py:336
#: tiramisu/option/optiondescription.py:121
msgid "root option description"
msgstr ""
#: tiramisu/option/optiondescription.py:123
msgid "option \"{0}\" is include in {1} but is also in {2}"
msgstr ""
#: tiramisu/option/optiondescription.py:328
msgid "children in optiondescription \"{}\" must be a list" msgid "children in optiondescription \"{}\" must be a list"
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:357 #: tiramisu/option/optiondescription.py:364
msgid "the option name \"{0}\" is duplicate in \"{1}\"" msgid "duplicate option name: \"{0}\""
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:411 #: tiramisu/option/optiondescription.py:370
msgid "the option's name \"{0}\" start as the dynoptiondescription's name \"{1}\""
msgstr ""
#: tiramisu/option/optiondescription.py:413
msgid "cannot change group_type if already set (old {0}, new {1})" msgid "cannot change group_type if already set (old {0}, new {1})"
msgstr "" msgstr ""
#: tiramisu/option/optiondescription.py:416 #: tiramisu/option/optiondescription.py:418
msgid "group_type: {0} not allowed" msgid "group_type: {0} not allowed"
msgstr "" msgstr ""
@ -815,27 +805,27 @@ msgstr ""
msgid "too weak" msgid "too weak"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:77 #: tiramisu/option/portoption.py:80
msgid "inconsistency in allowed range" msgid "inconsistency in allowed range"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:82 #: tiramisu/option/portoption.py:85
msgid "max value is empty" msgid "max value is empty"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:95 #: tiramisu/option/portoption.py:98
msgid "range must have two values only" msgid "range must have two values only"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:98 #: tiramisu/option/portoption.py:101
msgid "first port in range must be smaller than the second one" msgid "first port in range must be smaller than the second one"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:124 #: tiramisu/option/portoption.py:127
msgid "should be between {0} and {1}" msgid "should be between {0} and {1}"
msgstr "" msgstr ""
#: tiramisu/option/portoption.py:126 #: tiramisu/option/portoption.py:129
msgid "must be between {0} and {1}" msgid "must be between {0} and {1}"
msgstr "" msgstr ""
@ -915,15 +905,19 @@ msgstr ""
msgid "unknown action {}" msgid "unknown action {}"
msgstr "" msgstr ""
#: tiramisu/value.py:557 tiramisu/value.py:859 #: tiramisu/value.py:570 tiramisu/value.py:872
msgid "set owner \"{0}\" is forbidden" msgid "set owner \"{0}\" is forbidden"
msgstr "" msgstr ""
#: tiramisu/value.py:564 #: tiramisu/value.py:577
msgid "\"{0}\" is a default value, so we cannot change owner to \"{1}\"" msgid "\"{0}\" is a default value, so we cannot change owner to \"{1}\""
msgstr "" msgstr ""
#: tiramisu/value.py:845 #: tiramisu/value.py:751
msgid "index {index} is greater than the length {length} for option {subconfig.option.impl_get_display_name(with_quote=True)}"
msgstr ""
#: tiramisu/value.py:858
msgid "information's item not found \"{}\"" msgid "information's item not found \"{}\""
msgstr "" msgstr ""

View file

@ -1,4 +1,5 @@
# from json import dumps, loads # from json import dumps, loads
import asyncio
from os import environ from os import environ
try: try:
from tiramisu_api import Config from tiramisu_api import Config
@ -62,14 +63,3 @@ def parse_od_get(dico):
else: else:
ret[k.path()] = v ret[k.path()] = v
return ret return ret
def get_dependencies(option):
ret = []
for a in option.dependencies():
if a.isoptiondescription():
ret.append((a.path(), None))
else:
ret.append((a.path(), a.index()))
ret.sort()
return ret

View file

@ -162,10 +162,6 @@ def test_choiceoption_calc_opt_function(config_type):
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
assert cfg.option('choice').owner.isdefault() assert cfg.option('choice').owner.isdefault()
# #
dep = cfg.option('str').dependencies()
assert len(dep) == 1
assert dep[0].path() == 'choice'
#
cfg.option('choice').value.set('val1') cfg.option('choice').value.set('val1')
assert cfg.option('choice').owner.get() == owner assert cfg.option('choice').owner.get() == owner
# #
@ -191,6 +187,7 @@ def test_choiceoption_calc_opt_function_propertyerror():
# assert not list_sessions() # assert not list_sessions()
#def test_choiceoption_calc_opt_multi_function(config_type):
def test_choiceoption_calc_opt_multi_function(): def test_choiceoption_calc_opt_multi_function():
# FIXME # FIXME
config_type = 'tiramisu' config_type = 'tiramisu'

View file

@ -332,7 +332,7 @@ def test_duplicated_option():
g1 g1
#in same OptionDescription #in same OptionDescription
with pytest.raises(ConflictError): with pytest.raises(ConflictError):
OptionDescription('od', '', [g1, g1]) d1 = OptionDescription('od', '', [g1, g1])
# assert not list_sessions() # assert not list_sessions()
@ -346,28 +346,6 @@ def test_duplicated_option_diff_od():
Config(d2) Config(d2)
def test_duplicated_option_diff_od_2():
g1 = IntOption('g1', '', 1)
d1 = OptionDescription('od1', '', [g1])
#in different OptionDescription
d2 = OptionDescription('od2', '', [d1, g1])
d2
with pytest.raises(ConflictError):
Config(d2)
def test_duplicated_option_diff_od_3():
g1 = IntOption('g1', '', 1)
d1 = OptionDescription('od1', '', [g1])
d3 = OptionDescription('od3', '', [g1])
#in different OptionDescription
d2 = OptionDescription('od2', '', [d1, d3])
d4 = OptionDescription('od4', '', [d2])
d4
with pytest.raises(ConflictError):
Config(d4)
def test_cannot_assign_value_to_option_description(): def test_cannot_assign_value_to_option_description():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)

View file

@ -13,6 +13,12 @@ from tiramisu.error import PropertiesOptionError, ValueWarning, ConfigError
import warnings import warnings
#def teardown_function(function):
# # test_od_not_list emit a warnings because of doesn't create a Config
# with warnings.catch_warnings(record=True) as w:
# assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
@ -346,8 +352,6 @@ def test_invalid_option():
PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False) PortOption('a', '', allow_zero=False, allow_wellknown=False, allow_registred=False, allow_private=False)
with raises(ValueError): with raises(ValueError):
PortOption('a', '', 'tcp:80') PortOption('a', '', 'tcp:80')
with raises(ValueError):
PortOption('a', '', '')
NetworkOption('a', '') NetworkOption('a', '')
with raises(ValueError): with raises(ValueError):
NetworkOption('a', '', 'string') NetworkOption('a', '', 'string')

View file

@ -80,15 +80,15 @@ def test_copy_force_store_value():
assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}} assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}}
assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}} assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
# assert not list_sessions() # assert not list_sessions()
#
#
def test_copy_force_store_value_metaconfig(): #def test_copy_force_store_value_metaconfig():
od1 = make_description() # od1 = make_description()
meta = MetaConfig([], optiondescription=od1) # meta = MetaConfig([], optiondescription=od1)
conf = meta.config.new() # conf = meta.config.new()
assert meta.property.get() == conf.property.get() # assert meta.property.get() == conf.property.get()
assert meta.permissive.get() == conf.permissive.get() # assert meta.permissive.get() == conf.permissive.get()
conf.property.read_write() # conf.property.read_write()
assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}} # assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
assert meta.value.exportation() == {} # assert meta.value.exportation() == {}
# assert not list_sessions() ## assert not list_sessions()

View file

@ -1,7 +1,7 @@
# coding: utf-8 # coding: utf-8
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from .config import parse_od_get, get_dependencies from .config import parse_od_get
import pytest import pytest
from tiramisu.setting import groups, owners from tiramisu.setting import groups, owners
@ -336,7 +336,6 @@ def test_prop_dyndescription_force_store_value_calculation_prefix():
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
cfg = Config(od2) cfg = Config(od2)
cfg.property.read_write() cfg.property.read_write()
assert get_dependencies(cfg.option('od.lst')) == [('od.dodval1', None), ('od.dodval2', None)]
assert cfg.option('od.dodval1.st').owner.isdefault() == False assert cfg.option('od.dodval1.st').owner.isdefault() == False
assert cfg.option('od.dodval2.st').owner.isdefault() == False assert cfg.option('od.dodval2.st').owner.isdefault() == False
assert parse_od_get(cfg.value.get()) == {'od.lst': ['val1', 'val2'], 'od.dodval1.st': 'val1', 'od.dodval2.st': 'val2'} assert parse_od_get(cfg.value.get()) == {'od.lst': ['val1', 'val2'], 'od.dodval1.st': 'val1', 'od.dodval2.st': 'val2'}
@ -395,8 +394,6 @@ def test_callback_dyndescription_outside1():
od = OptionDescription('od', '', [dod, out]) od = OptionDescription('od', '', [dod, out])
od2 = OptionDescription('od', '', [od, lst]) od2 = OptionDescription('od', '', [od, lst])
cfg = Config(od2) cfg = Config(od2)
#
assert get_dependencies(cfg.option('od.dodval1.st')) == [('od.out', None)]
assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': 'val', 'od.dodval2.st': 'val', 'od.out': 'val', 'lst': ['val1', 'val2']} assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': 'val', 'od.dodval2.st': 'val', 'od.out': 'val', 'lst': ['val1', 'val2']}
cfg.option('od.dodval1.st').value.set('val1') cfg.option('od.dodval1.st').value.set('val1')
cfg.option('od.dodval2.st').value.set('val2') cfg.option('od.dodval2.st').value.set('val2')
@ -420,8 +417,6 @@ def test_callback_dyndescription_outside2():
assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': None, 'od.dodval2.st': None, 'od.out': None, 'lst': ['val1', 'val2']} assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': None, 'od.dodval2.st': None, 'od.out': None, 'lst': ['val1', 'val2']}
cfg.option('od.out').value.set('val1') cfg.option('od.out').value.set('val1')
assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': 'val1', 'od.dodval2.st': 'val1', 'od.out': 'val1', 'lst': ['val1', 'val2']} assert parse_od_get(cfg.value.get()) == {'od.dodval1.st': 'val1', 'od.dodval2.st': 'val1', 'od.out': 'val1', 'lst': ['val1', 'val2']}
#
assert get_dependencies(cfg.option('od.out')) == [('od.dodval1.st', None), ('od.dodval2.st', None)]
# assert not list_sessions() # assert not list_sessions()
@ -1196,8 +1191,6 @@ def test_leadership_dyndescription():
cfg = Config(od1) cfg = Config(od1)
owner = cfg.owner.get() owner = cfg.owner.get()
# #
assert get_dependencies(cfg.option('od.stval1.st1.st2')) == [('od.stval1.st1', None)]
assert get_dependencies(cfg.option('od.stval2.st1.st2')) == [('od.stval2.st1', None)]
assert parse_od_get(cfg.value.get()) == {'od.stval2.st1.st1': [], 'od.stval1.st1.st1': []} assert parse_od_get(cfg.value.get()) == {'od.stval2.st1.st1': [], 'od.stval1.st1.st1': []}
assert cfg.option('od.stval1.st1.st1').value.get() == [] assert cfg.option('od.stval1.st1.st1').value.get() == []
assert cfg.option('od.stval2.st1.st1').value.get() == [] assert cfg.option('od.stval2.st1.st1').value.get() == []
@ -1257,9 +1250,6 @@ def test_leadership_dyndescription_force_store_value_leader():
od1 = OptionDescription('od', '', [od]) od1 = OptionDescription('od', '', [od])
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
#
assert get_dependencies(cfg.option('od.stval1.st1.st2')) == [('od.stval1.st1', None)]
assert get_dependencies(cfg.option('od.stval2.st1.st2')) == [('od.stval2.st1', None)]
assert cfg.option('od.stval1.st1.st1').owner.isdefault() == False assert cfg.option('od.stval1.st1.st1').owner.isdefault() == False
assert cfg.option('od.stval2.st1.st1').owner.isdefault() == False assert cfg.option('od.stval2.st1.st1').owner.isdefault() == False
assert cfg.option('od.stval1.st1.st2', 0).owner.isdefault() == True assert cfg.option('od.stval1.st1.st2', 0).owner.isdefault() == True
@ -1720,6 +1710,16 @@ def test_leadership_callback_samegroup_dyndescription():
# assert not list_sessions() # assert not list_sessions()
def test_invalid_conflict_dyndescription():
st = StrOption('st', '')
dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list))
dodinvalid = StrOption('dodinvalid', '')
dod, dodinvalid
with pytest.raises(ConflictError):
OptionDescription('od', '', [dod, dodinvalid])
# assert not list_sessions()
def test_leadership_default_multi_dyndescription4(): def test_leadership_default_multi_dyndescription4():
st1 = StrOption('st1', "", multi=True) st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, default_multi='no') st2 = StrOption('st2', "", multi=True, default_multi='no')
@ -2873,86 +2873,3 @@ def test_callback_list_dyndescription_information_not_list():
cfg.information.set('identifier', 'ival3') cfg.information.set('identifier', 'ival3')
assert cfg.option('od.dodival3.st').value.get() == ['ival3', 'val2'] assert cfg.option('od.dodival3.st').value.get() == ['ival3', 'val2']
# assert not list_sessions() # assert not list_sessions()
def test_dynoption_not_duplicate():
st = StrOption('st', '')
st2 = StrOption('st', '')
dod = DynOptionDescription('od_', '', [st], identifiers=["val1"])
dod2 = DynOptionDescription('od_', '', [st2], identifiers=["val2"])
od = OptionDescription('od', '', [dod, dod2])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
assert parse_od_get(cfg.value.get()) == {
'od.od_val1.st': None,
'od.od_val2.st': None,
}
def test_dynoption_duplicate_1():
st = StrOption('st', '', "val1")
od = OptionDescription('od_val', '', [st])
st2 = StrOption('st', '', "val2")
dod = DynOptionDescription('od_', '', [st2], identifiers=["val"])
od1 = OptionDescription('od', '', [od, dod])
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
with pytest.raises(ConflictError):
cfg.value.get()
with pytest.raises(ConflictError):
cfg.option('od.od_val').value.get()
def test_dynoption_duplicate_2():
st2 = StrOption('st', '', "val2")
dod = DynOptionDescription('od_', '', [st2], identifiers=["val"])
st = StrOption('st', '', "val1")
od = OptionDescription('od_val', '', [st])
od1 = OptionDescription('od', '', [dod, od])
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
with pytest.raises(ConflictError):
cfg.value.get()
with pytest.raises(ConflictError):
cfg.option('od.od_val').value.get()
def test_dynoption_duplicate_3():
st = StrOption('od_val', '')
st2 = StrOption('st', '', "val2")
dod = DynOptionDescription('od_', '', [st2], identifiers=["val"])
od1 = OptionDescription('od', '', [dod, st])
od2 = OptionDescription('od', '', [od1])
cfg = Config(od2)
with pytest.raises(ConflictError):
cfg.value.get()
with pytest.raises(ConflictError):
cfg.option('od.od_val').value.get()
def test_dynoption_duplicate_4():
st = StrOption('st', '')
st2 = StrOption('st', '')
dod = DynOptionDescription('od_', '', [st], identifiers=["val"])
dod2 = DynOptionDescription('od_', '', [st2], identifiers=["val"])
od = OptionDescription('od', '', [dod, dod2])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
with pytest.raises(ConflictError):
cfg.value.get()
with pytest.raises(ConflictError):
cfg.option('od.od_val').value.get()
def test_dynoption_duplicate_5():
st = StrOption('st', '')
st2 = StrOption('st', '')
dod = DynOptionDescription('od_', '', [st], identifiers=["val"])
dod2 = DynOptionDescription('od', '', [st2], identifiers=["_val"])
od = OptionDescription('od', '', [dod, dod2])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
with pytest.raises(ConflictError):
cfg.value.get()
with pytest.raises(ConflictError):
cfg.option('od.od_val').value.get()

View file

@ -1055,7 +1055,7 @@ def test_follower_force_store_value_reset():
# assert not list_sessions() # assert not list_sessions()
def test_follower_properties(): #def test_follower_properties():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('aproperty',)) netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('aproperty',))
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])

View file

@ -13,6 +13,8 @@ from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.setting import groups from tiramisu.setting import groups
#def teardown_function(function):
# assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def is_mandatory(variable): def is_mandatory(variable):
return True return True
@ -686,25 +688,25 @@ def return_list(val=None, identifier=None):
return ['val1', 'val2'] return ['val1', 'val2']
def test_mandatory_dyndescription(): #def test_mandatory_dyndescription():
st = StrOption('st', '', properties=('mandatory',)) # st = StrOption('st', '', properties=('mandatory',))
dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list)) # dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list))
od = OptionDescription('od', '', [dod]) # od = OptionDescription('od', '', [dod])
od2 = OptionDescription('od', '', [od]) # od2 = OptionDescription('od', '', [od])
cfg = Config(od2) # cfg = Config(od2)
cfg.property.read_only() # cfg.property.read_only()
compare(cfg.value.mandatory(), ['od.dodval1.st', 'od.dodval2.st']) # compare(cfg.value.mandatory(), ['od.dodval1.st', 'od.dodval2.st'])
#
#
def test_mandatory_dyndescription_context(): #def test_mandatory_dyndescription_context():
val1 = StrOption('val1', '', ['val1', 'val2'], multi=True) # val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
st = StrOption('st', '', properties=('mandatory',)) # st = StrOption('st', '', properties=('mandatory',))
dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list, Params(ParamOption(val1)))) # dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list, Params(ParamOption(val1))))
od = OptionDescription('od', '', [dod, val1]) # od = OptionDescription('od', '', [dod, val1])
od2 = OptionDescription('od', '', [od]) # od2 = OptionDescription('od', '', [od])
cfg = Config(od2) # cfg = Config(od2)
cfg.property.read_only() # cfg.property.read_only()
compare(cfg.value.mandatory(), ['od.dodval1.st', 'od.dodval2.st']) # compare(cfg.value.mandatory(), ['od.dodval1.st', 'od.dodval2.st'])
def test_mandatory_callback_leader_and_followers_leader(): def test_mandatory_callback_leader_and_followers_leader():

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -15,76 +15,76 @@ def make_metaconfig():
return MetaConfig([], optiondescription=od2, name='metacfg1') return MetaConfig([], optiondescription=od2, name='metacfg1')
def test_multi_parents_path(): #def test_multi_parents_path():
""" # """
metacfg1 (1) --- # metacfg1 (1) ---
| -- cfg1 # | -- cfg1
metacfg2 (2) --- # metacfg2 (2) ---
""" # """
metacfg1 = make_metaconfig() # metacfg1 = make_metaconfig()
cfg1 = metacfg1.config.new(type='config', name="cfg1") # cfg1 = metacfg1.config.new(type='config', name="cfg1")
metacfg2 = MetaConfig([cfg1], name='metacfg2') # metacfg2 = MetaConfig([cfg1], name='metacfg2')
# #
# assert metacfg1.config.path() == 'metacfg1'
# assert metacfg2.config.path() == 'metacfg2'
# assert cfg1.config.path() == 'metacfg2.metacfg1.cfg1'
# #
assert metacfg1.config.path() == 'metacfg1'
assert metacfg2.config.path() == 'metacfg2'
assert cfg1.config.path() == 'metacfg2.metacfg1.cfg1'
def test_multi_parents_path_same():
"""
--- metacfg2 (1) ---
metacfg1 --| | -- cfg1
--- metacfg3 (2) ---
"""
metacfg1 = make_metaconfig()
metacfg2 = metacfg1.config.new(type='metaconfig', name="metacfg2")
metacfg3 = metacfg1.config.new(type='metaconfig', name="metacfg3")
cfg1 = metacfg2.config.new(type='config', name="cfg1")
metacfg3.config.add(cfg1)
# #
assert metacfg2.config.path() == 'metacfg1.metacfg2' #def test_multi_parents_path_same():
assert metacfg3.config.path() == 'metacfg1.metacfg3' # """
assert cfg1.config.path() == 'metacfg1.metacfg3.metacfg1.metacfg2.cfg1' # --- metacfg2 (1) ---
metacfg1.option('od1.i1').value.set(1) # metacfg1 --| | -- cfg1
metacfg3.option('od1.i1').value.set(2) # --- metacfg3 (2) ---
assert cfg1.option('od1.i1').value.get() == 1 # """
orideep = cfg1.config.deepcopy(metaconfig_prefix="test_", name='test_cfg1') # metacfg1 = make_metaconfig()
deep = orideep # metacfg2 = metacfg1.config.new(type='metaconfig', name="metacfg2")
while True: # metacfg3 = metacfg1.config.new(type='metaconfig', name="metacfg3")
try: # cfg1 = metacfg2.config.new(type='config', name="cfg1")
children = list(deep.config.list()) # metacfg3.config.add(cfg1)
except: # #
break # assert metacfg2.config.path() == 'metacfg1.metacfg2'
assert len(children) < 2 # assert metacfg3.config.path() == 'metacfg1.metacfg3'
deep = children[0] # assert cfg1.config.path() == 'metacfg1.metacfg3.metacfg1.metacfg2.cfg1'
assert deep.config.path() == 'test_metacfg3.test_metacfg1.test_metacfg2.test_cfg1' # metacfg1.option('od1.i1').value.set(1)
assert cfg1.option('od1.i1').value.get() == 1 # metacfg3.option('od1.i1').value.set(2)
# assert cfg1.option('od1.i1').value.get() == 1
# orideep = cfg1.config.deepcopy(metaconfig_prefix="test_", name='test_cfg1')
# deep = orideep
def test_multi_parents_value(): # while True:
metacfg1 = make_metaconfig() # try:
cfg1 = metacfg1.config.new(type='config', name="cfg1") # children = list(deep.config.list())
metacfg2 = MetaConfig([cfg1], name='metacfg2') # except:
# break
# assert len(children) < 2
# deep = children[0]
# assert deep.config.path() == 'test_metacfg3.test_metacfg1.test_metacfg2.test_cfg1'
# assert cfg1.option('od1.i1').value.get() == 1
# #
assert cfg1.option('od1.i1').value.get() == None
assert cfg1.option('od1.i2').value.get() == 1
assert cfg1.option('od1.i3').value.get() == None
# #
assert metacfg1.option('od1.i1').value.get() == None
assert metacfg1.option('od1.i2').value.get() == 1
assert metacfg1.option('od1.i3').value.get() == None
# #
assert metacfg2.option('od1.i1').value.get() == None #def test_multi_parents_value():
assert metacfg2.option('od1.i2').value.get() == 1 # metacfg1 = make_metaconfig()
assert metacfg2.option('od1.i3').value.get() == None # cfg1 = metacfg1.config.new(type='config', name="cfg1")
# # metacfg2 = MetaConfig([cfg1], name='metacfg2')
metacfg1.option('od1.i3').value.set(3) # #
assert metacfg1.option('od1.i3').value.get() == 3 # assert cfg1.option('od1.i1').value.get() == None
assert cfg1.option('od1.i3').value.get() == 3 # assert cfg1.option('od1.i2').value.get() == 1
assert metacfg2.option('od1.i2').value.get() == 1 # assert cfg1.option('od1.i3').value.get() == None
# # #
metacfg2.option('od1.i2').value.set(4) # assert metacfg1.option('od1.i1').value.get() == None
assert metacfg2.option('od1.i2').value.get() == 4 # assert metacfg1.option('od1.i2').value.get() == 1
assert metacfg1.option('od1.i2').value.get() == 1 # assert metacfg1.option('od1.i3').value.get() == None
assert cfg1.option('od1.i2').value.get() == 4 # #
# assert metacfg2.option('od1.i1').value.get() == None
# assert metacfg2.option('od1.i2').value.get() == 1
# assert metacfg2.option('od1.i3').value.get() == None
# #
# metacfg1.option('od1.i3').value.set(3)
# assert metacfg1.option('od1.i3').value.get() == 3
# assert cfg1.option('od1.i3').value.get() == 3
# assert metacfg2.option('od1.i2').value.get() == 1
# #
# metacfg2.option('od1.i2').value.set(4)
# assert metacfg2.option('od1.i2').value.get() == 4
# assert metacfg1.option('od1.i2').value.get() == 1
# assert cfg1.option('od1.i2').value.get() == 4

View file

@ -13,7 +13,7 @@ from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
valid_ip_netmask, ParamSelfOption, ParamInformation, ParamSelfInformation valid_ip_netmask, ParamSelfOption, ParamInformation, ParamSelfInformation
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _ from tiramisu.i18n import _
from .config import config_type, get_config, parse_od_get, get_dependencies from .config import config_type, get_config, parse_od_get
def return_val(): def return_val():
@ -693,7 +693,6 @@ def test_callback_leader_and_followers_leader(config_type):
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
assert [(a.path(), a.index()) for a in cfg.option('val1').dependencies()] == [('val2.val2', None)]
assert cfg.option('val1').value.get() == ['val'] assert cfg.option('val1').value.get() == ['val']
assert cfg.option('val2.val2').value.get() == ['val'] assert cfg.option('val2.val2').value.get() == ['val']
# #
@ -784,29 +783,10 @@ def test_callback_leader_and_followers_leader2(config_type):
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
cfg = get_config(cfg, config_type) cfg = get_config(cfg, config_type)
assert get_dependencies(cfg.option('val1.val2')) == [('val1', None)]
assert get_dependencies(cfg.option('val1.val3')) == [('val1', None)] #, ('val2.val2', 0)]
assert get_dependencies(cfg.option('val1.val4')) == [('val1', None)] #, ('val2.val3', 0)]
#
cfg.option('val1.val1').value.set(['val']) cfg.option('val1.val1').value.set(['val'])
assert get_dependencies(cfg.option('val1.val2')) == [('val1', None), ('val1.val3', 0)]
assert get_dependencies(cfg.option('val1.val2', 0)) == [('val1', None), ('val1.val3', 0)]
assert get_dependencies(cfg.option('val1.val3')) == [('val1', None), ('val1.val4', 0)]
assert get_dependencies(cfg.option('val1.val3', 0)) == [('val1', None), ('val1.val4', 0)]
assert get_dependencies(cfg.option('val1.val4')) == [('val1', None)]
assert cfg.option('val1.val4', 0).value.get() == 'val2' assert cfg.option('val1.val4', 0).value.get() == 'val2'
assert cfg.option('val1.val3', 0).value.get() == 'val2' assert cfg.option('val1.val3', 0).value.get() == 'val2'
assert cfg.option('val1.val2', 0).value.get() == 'val2' assert cfg.option('val1.val2', 0).value.get() == 'val2'
#
cfg.option('val1.val1').value.set(['val1', 'val2'])
assert get_dependencies(cfg.option('val1.val2')) == [('val1', None), ('val1.val3', 0), ('val1.val3', 1)]
assert get_dependencies(cfg.option('val1.val2', 0)) == [('val1', None), ('val1.val3', 0)]
assert get_dependencies(cfg.option('val1.val2', 1)) == [('val1', None), ('val1.val3', 1)]
assert get_dependencies(cfg.option('val1.val3')) == [('val1', None), ('val1.val4', 0), ('val1.val4', 1)]
assert get_dependencies(cfg.option('val1.val3', 0)) == [('val1', None), ('val1.val4', 0)]
assert get_dependencies(cfg.option('val1.val3', 1)) == [('val1', None), ('val1.val4', 1)]
assert get_dependencies(cfg.option('val1.val4')) == [('val1', None)]
# assert not list_sessions() # assert not list_sessions()
@ -1519,7 +1499,6 @@ def test_leadership_callback_description(config_type):
cfg.option('od.st.st1.st2', 0).value.set('yes') cfg.option('od.st.st1.st2', 0).value.set('yes')
assert cfg.option('od.st.st1.st1').owner.get() == owner assert cfg.option('od.st.st1.st1').owner.get() == owner
assert cfg.option('od.st.st1.st2', 0).owner.get() == owner assert cfg.option('od.st.st1.st2', 0).owner.get() == owner
assert get_dependencies(cfg.option('od.st.st1.st2')) == [('od.st.st1', None)]
# assert not list_sessions() # assert not list_sessions()
@ -1536,8 +1515,6 @@ def test_leadership_callback_outside(config_type):
owner = cfg.owner.get() owner = cfg.owner.get()
cfg.option('od.st.st1.st1').value.set(['yes']) cfg.option('od.st.st1.st1').value.set(['yes'])
assert parse_od_get(cfg.value.get()) == {'od.st.st1.st1': [{'od.st.st1.st1': 'yes', 'od.st.st1.st2': 'val2'}], 'od.st.st3': ['val2']} assert parse_od_get(cfg.value.get()) == {'od.st.st1.st1': [{'od.st.st1.st1': 'yes', 'od.st.st1.st2': 'val2'}], 'od.st.st3': ['val2']}
assert get_dependencies(cfg.option('od.st.st1.st2')) == [('od.st.st1', None), ('od.st.st3', None,)]
## assert not list_sessions() ## assert not list_sessions()

View file

@ -154,8 +154,8 @@ def test_force_default_on_freeze_multi():
# with pytest.raises(ConfigError): # with pytest.raises(ConfigError):
# Config(od1) # Config(od1)
# assert not list_sessions() # assert not list_sessions()
#
#
#def test_force_metaconfig_on_freeze_leader(): #def test_force_metaconfig_on_freeze_leader():
# dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',)) # dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',))
# dummy2 = BoolOption('dummy2', 'Test string option', multi=True) # dummy2 = BoolOption('dummy2', 'Test string option', multi=True)

View file

@ -818,27 +818,27 @@ def test_reset_properties_force_store_value():
# assert not list_sessions() # assert not list_sessions()
def test_importation_force_store_value(): #def test_importation_force_store_value():
gcdummy = BoolOption('dummy', 'dummy', default=False, # gcdummy = BoolOption('dummy', 'dummy', default=False,
properties=('force_store_value',)) # properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy]) # gcgroup = OptionDescription('gc', '', [gcdummy])
od1 = OptionDescription('tiramisu', '', [gcgroup]) # od1 = OptionDescription('tiramisu', '', [gcgroup])
config1 = Config(od1) # config1 = Config(od1)
assert config1.value.exportation() == {} # assert config1.value.exportation() == {}
config1.property.add('frozen') # config1.property.add('frozen')
assert config1.value.exportation() == {} # assert config1.value.exportation() == {}
config1.property.add('force_store_value') # config1.property.add('force_store_value')
assert config1.value.exportation() == {'gc.dummy': {None: [False, 'forced']}} # assert config1.value.exportation() == {'gc.dummy': {None: [False, 'forced']}}
exportation = config1.property.exportation() # exportation = config1.property.exportation()
config2 = Config(od1) # config2 = Config(od1)
assert config2.value.exportation() == {} # assert config2.value.exportation() == {}
config2.property.importation(exportation) # config2.property.importation(exportation)
assert config2.value.exportation() == {'gc.dummy': {None: [False, 'forced']}} # assert config2.value.exportation() == {'gc.dummy': {None: [False, 'forced']}}
config2.property.importation(exportation) # config2.property.importation(exportation)
assert config2.value.exportation() == {'gc.dummy': {None: [False, 'forced']}} # assert config2.value.exportation() == {'gc.dummy': {None: [False, 'forced']}}
# assert not list_sessions() ## assert not list_sessions()
#
#
def test_set_modified_value(): def test_set_modified_value():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',)) gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy]) gcgroup = OptionDescription('gc', '', [gcdummy])
@ -920,18 +920,18 @@ def test_set_modified_value():
# assert not list_sessions() # assert not list_sessions()
def test_none_is_not_modified(): #def test_none_is_not_modified():
gcdummy = StrOption('dummy', 'dummy', properties=('force_store_value',)) # gcdummy = StrOption('dummy', 'dummy', properties=('force_store_value',))
gcdummy1 = StrOption('dummy1', 'dummy1', default="str", properties=('force_store_value',)) # gcdummy1 = StrOption('dummy1', 'dummy1', default="str", properties=('force_store_value',))
gcgroup = OptionDescription('gc', '', [gcdummy, gcdummy1]) # gcgroup = OptionDescription('gc', '', [gcdummy, gcdummy1])
od1 = OptionDescription('tiramisu', '', [gcgroup]) # od1 = OptionDescription('tiramisu', '', [gcgroup])
cfg = Config(od1) # cfg = Config(od1)
assert cfg.value.exportation() == {} # assert cfg.value.exportation() == {}
cfg.property.read_write() # cfg.property.read_write()
assert cfg.value.exportation() == {'gc.dummy1': {None: ['str', 'forced']}} # assert cfg.value.exportation() == {'gc.dummy1': {None: ['str', 'forced']}}
# assert not list_sessions() ## assert not list_sessions()
#
#
def test_pprint(): def test_pprint():
msg_error = _("cannot access to {0} {1} because has {2} {3}") msg_error = _("cannot access to {0} {1} because has {2} {3}")
msg_is_not = _('the value of "{0}" is not {1}') msg_is_not = _('the value of "{0}" is not {1}')

View file

@ -34,7 +34,7 @@ def return_val(value, param=None):
def return_if_val(value): def return_if_val(value):
if value not in ['val', 'val_not_raise']: if value != 'val':
raise ValueError('test error') raise ValueError('test error')
@ -341,13 +341,6 @@ def test_validator_multi(config_type):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
cfg.option('opt1').value.set(['val', 'val1']) cfg.option('opt1').value.set(['val', 'val1'])
assert len(w) == 1 assert len(w) == 1
with warnings.catch_warnings(record=True) as w:
cfg.option('opt1').value.set(['val1', 'val2'])
assert len(w) == 2
with warnings.catch_warnings(record=True) as w:
# same value twice
cfg.option('opt1').value.set(['val', 'val', 'val_not_raise'])
assert len(w) == 2
# assert not list_sessions() # assert not list_sessions()

View file

@ -146,8 +146,8 @@ def test_slots_option_readonly():
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
q._requires = 'q' q._requires = 'q'
# assert not list_sessions() # assert not list_sessions()
#
#
#def test_slots_description(): #def test_slots_description():
# # __slots__ for OptionDescription should be complete for __getattr__ # # __slots__ for OptionDescription should be complete for __getattr__
# slots = set() # slots = set()

View file

@ -528,43 +528,43 @@ def test_submulti_unique():
# assert not list_sessions() # assert not list_sessions()
def test_multi_submulti_meta(): #def test_multi_submulti_meta():
multi = StrOption('multi', '', multi=submulti) # multi = StrOption('multi', '', multi=submulti)
od1 = OptionDescription('od', '', [multi]) # od1 = OptionDescription('od', '', [multi])
cfg = Config(od1, name='cfg') # cfg = Config(od1, name='cfg')
cfg.property.read_write() # cfg.property.read_write()
cfg2 = Config(od1) # cfg2 = Config(od1)
cfg2.property.read_write() # cfg2.property.read_write()
meta = MetaConfig([cfg, cfg2]) # meta = MetaConfig([cfg, cfg2])
meta.property.read_write() # meta.property.read_write()
meta.option('multi').value.set([['val']]) # meta.option('multi').value.set([['val']])
assert meta.option('multi').value.get() == [['val']] # assert meta.option('multi').value.get() == [['val']]
newcfg = meta.config('cfg') # newcfg = meta.config('cfg')
newcfg.option('multi').value.set([['val', None]]) # newcfg.option('multi').value.set([['val', None]])
assert cfg.option('multi').value.get() == [['val', None]] # assert cfg.option('multi').value.get() == [['val', None]]
newcfg = meta.config('cfg') # newcfg = meta.config('cfg')
assert newcfg.option('multi').value.get() == [['val', None]] # assert newcfg.option('multi').value.get() == [['val', None]]
assert meta.option('multi').value.get() == [['val']] # assert meta.option('multi').value.get() == [['val']]
# assert not list_sessions() ## assert not list_sessions()
#
#
def test_multi_submulti_meta_no_cache(): #def test_multi_submulti_meta_no_cache():
multi = StrOption('multi', '', multi=submulti) # multi = StrOption('multi', '', multi=submulti)
multi = StrOption('multi', '', multi=submulti) # multi = StrOption('multi', '', multi=submulti)
od1 = OptionDescription('od', '', [multi]) # od1 = OptionDescription('od', '', [multi])
cfg = Config(od1, name='cfg') # cfg = Config(od1, name='cfg')
cfg.property.read_write() # cfg.property.read_write()
cfg2 = Config(od1) # cfg2 = Config(od1)
cfg.property.read_write() # cfg.property.read_write()
meta = MetaConfig([cfg, cfg2]) # meta = MetaConfig([cfg, cfg2])
meta.property.read_write() # meta.property.read_write()
meta.property.remove('cache') # meta.property.remove('cache')
meta.option('multi').value.set([['val']]) # meta.option('multi').value.set([['val']])
assert meta.option('multi').value.get() == [['val']] # assert meta.option('multi').value.get() == [['val']]
newcfg = meta.config('cfg') # newcfg = meta.config('cfg')
newcfg.option('multi').value.set([['val', None]]) # newcfg.option('multi').value.set([['val', None]])
assert cfg.option('multi').value.get() == [['val', None]] # assert cfg.option('multi').value.get() == [['val', None]]
newcfg = meta.config('cfg') # newcfg = meta.config('cfg')
assert newcfg.option('multi').value.get() == [['val', None]] # assert newcfg.option('multi').value.get() == [['val', None]]
assert meta.option('multi').value.get() == [['val']] # assert meta.option('multi').value.get() == [['val']]
# assert not list_sessions() ## assert not list_sessions()

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2017-2025 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2017-2024 Team tiramisu (see AUTHORS for all contributors)
# #
# 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
@ -52,13 +52,6 @@ from .autolib import Calculation
TIRAMISU_VERSION = 5 TIRAMISU_VERSION = 5
class Fake_SubConfig:
def __init__(self, config_bag, path, index):
self.config_bag = config_bag
self.path = path
self.index = index
class TiramisuHelp: class TiramisuHelp:
_tmpl_help = " {0}\t{1}" _tmpl_help = " {0}\t{1}"
@ -127,7 +120,6 @@ class CommonTiramisu(TiramisuHelp):
def _set_subconfig(self) -> None: def _set_subconfig(self) -> None:
if not self._subconfig: if not self._subconfig:
try:
self._subconfig = self._config_bag.context.get_sub_config( self._subconfig = self._config_bag.context.get_sub_config(
self._config_bag, self._config_bag,
self._path, self._path,
@ -135,8 +127,6 @@ class CommonTiramisu(TiramisuHelp):
validate_properties=False, validate_properties=False,
allow_dynoption=self._allow_dynoption, allow_dynoption=self._allow_dynoption,
) )
except AssertionError as err:
raise ConfigError(str(err))
def option_type(typ): def option_type(typ):
@ -212,9 +202,7 @@ def option_type(typ):
"please specify index with a follower option ({0}.{1})" "please specify index with a follower option ({0}.{1})"
).format(self.__class__.__name__, func.__name__) ).format(self.__class__.__name__, func.__name__)
raise ConfigError(msg) raise ConfigError(msg)
if "validate_properties" in types or ( if self._validate_properties and "dont_validate_property" not in types:
self._validate_properties and "dont_validate_property" not in types
):
settings = self._config_bag.context.get_settings() settings = self._config_bag.context.get_settings()
parent = self._subconfig.parent parent = self._subconfig.parent
if parent and parent.transitive_properties: if parent and parent.transitive_properties:
@ -265,13 +253,10 @@ class _TiramisuOptionWalk:
validate_properties: bool, validate_properties: bool,
*, *,
uncalculated: bool = False, uncalculated: bool = False,
with_index: bool = True,
): ):
options = [] options = []
for sub_subconfig in subconfig.get_children( for sub_subconfig in subconfig.get_children(
validate_properties, validate_properties, uncalculated=uncalculated
uncalculated=uncalculated,
with_index=with_index,
): ):
options.append( options.append(
TiramisuOption( TiramisuOption(
@ -302,15 +287,7 @@ class _TiramisuOptionOptionDescription:
"""Get Tiramisu option""" """Get Tiramisu option"""
return self._subconfig.option return self._subconfig.option
@option_type( @option_type(["optiondescription", "option", "with_or_without_index", "symlink"])
[
"optiondescription",
"option",
"with_or_without_index",
"symlink",
"allow_dynoption",
]
)
def isoptiondescription(self): def isoptiondescription(self):
"""Test if option is an optiondescription""" """Test if option is an optiondescription"""
return self._subconfig.option.impl_is_optiondescription() return self._subconfig.option.impl_is_optiondescription()
@ -359,15 +336,6 @@ class _TiramisuOptionOptionDescription:
return self._subconfig.option.impl_getpath() return self._subconfig.option.impl_getpath()
return self._subconfig.true_path return self._subconfig.true_path
def parent(self):
parent = self._subconfig.parent
return TiramisuOption(
parent.path,
None,
self._config_bag,
subconfig=parent,
)
@option_type(["optiondescription", "option", "symlink", "with_or_without_index"]) @option_type(["optiondescription", "option", "symlink", "with_or_without_index"])
def has_dependency( def has_dependency(
self, self,
@ -377,63 +345,16 @@ class _TiramisuOptionOptionDescription:
return self._subconfig.option.impl_has_dependency(self_is_dep) return self._subconfig.option.impl_has_dependency(self_is_dep)
@option_type(["optiondescription", "option", "symlink", "with_or_without_index"]) @option_type(["optiondescription", "option", "symlink", "with_or_without_index"])
def dependencies( def dependencies(self):
self,
*,
uncalculated: bool = False,
):
"""Get dependencies from this option""" """Get dependencies from this option"""
options = [] options = []
context = self._config_bag.context for option in self._subconfig.option.get_dependencies(self._config_bag.context):
index = self._index
parent = self._subconfig.parent
parent_option = parent.option
for woption in self._subconfig.option.get_dependencies(
self._config_bag.context
):
option = woption()
if not uncalculated and option.issubdyn():
for subconfig in context.get_dynamic_from_dyn_option(
self._subconfig, option
):
options.append( options.append(
TiramisuOption( TiramisuOption(
subconfig.path, option().impl_getpath(),
None, None,
self._config_bag, self._config_bag,
) allow_dynoption=True,
)
elif not uncalculated and option.impl_is_dynoptiondescription():
for subconfig in context.get_dynamic_from_dyn_option(
self._subconfig, option
):
options.append(
TiramisuOption(
subconfig.path,
None,
self._config_bag,
)
)
else:
if (
not option.impl_is_optiondescription()
and option.impl_is_follower()
and parent_option.impl_is_leadership()
and parent_option.in_same_leadership(option)
):
if index is not None:
current_indexes = [index]
else:
current_indexes = range(parent.get_length_leadership())
else:
current_indexes = [None]
for current_index in current_indexes:
options.append(
TiramisuOption(
option.impl_getpath(),
current_index,
self._config_bag,
allow_dynoption=uncalculated,
) )
) )
return options return options
@ -535,27 +456,27 @@ class _TiramisuOptionOptionDescription:
class _TiramisuOptionOption(_TiramisuOptionOptionDescription): class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
"""Manage option""" """Manage option"""
@option_type(["option", "symlink", "with_or_without_index", "allow_dynoption"]) @option_type(["option", "symlink", "with_or_without_index"])
def ismulti(self): def ismulti(self):
"""Test if option could have multi value""" """Test if option could have multi value"""
return self._subconfig.option.impl_is_multi() return self._subconfig.option.impl_is_multi()
@option_type(["option", "symlink", "with_or_without_index", "allow_dynoption"]) @option_type(["option", "symlink", "with_or_without_index"])
def issubmulti(self): def issubmulti(self):
"""Test if option could have submulti value""" """Test if option could have submulti value"""
return self._subconfig.option.impl_is_submulti() return self._subconfig.option.impl_is_submulti()
@option_type(["option", "with_or_without_index", "symlink", "allow_dynoption"]) @option_type(["option", "with_or_without_index", "symlink"])
def isleader(self): def isleader(self):
"""Test if option is a leader""" """Test if option is a leader"""
return self._subconfig.option.impl_is_leader() return self._subconfig.option.impl_is_leader()
@option_type(["option", "with_or_without_index", "symlink", "allow_dynoption"]) @option_type(["option", "with_or_without_index", "symlink"])
def isfollower(self): def isfollower(self):
"""Test if option is a follower""" """Test if option is a follower"""
return self._subconfig.option.impl_is_follower() return self._subconfig.option.impl_is_follower()
@option_type(["option", "symlink", "with_or_without_index", "allow_dynoption"]) @option_type(["option", "symlink", "with_or_without_index"])
def issymlinkoption(self) -> bool: def issymlinkoption(self) -> bool:
"""Test if option is a symlink option""" """Test if option is a symlink option"""
return self._subconfig.option.impl_is_symlinkoption() return self._subconfig.option.impl_is_symlinkoption()
@ -577,11 +498,9 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
return r"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" return r"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
@option_type(["option", "with_or_without_index", "symlink"]) @option_type(["option", "with_or_without_index", "symlink"])
def index(self, index=None): def index(self):
"""Get index of option""" """Get index of option"""
if index is None:
return self._subconfig.index return self._subconfig.index
return TiramisuOption(self._path, index, self._config_bag)
@option_type(["symlink", "optiondescription"]) @option_type(["symlink", "optiondescription"])
def option(self, *args, **kwargs): def option(self, *args, **kwargs):
@ -627,11 +546,9 @@ class TiramisuOptionOwner(CommonTiramisuOption):
_validate_properties = True _validate_properties = True
@option_type(["symlink", "option", "with_index"]) @option_type(["symlink", "option", "with_index"])
def get(self, only_self=False): def get(self):
"""Get owner for a specified option""" """Get owner for a specified option"""
return self._config_bag.context.get_owner( return self._config_bag.context.get_owner(self._subconfig)
self._subconfig, validate_meta=not only_self
)
@option_type(["symlink", "option", "with_index"]) @option_type(["symlink", "option", "with_index"])
def isdefault(self): def isdefault(self):
@ -680,7 +597,6 @@ class TiramisuOptionProperty(CommonTiramisuOption):
self._subconfig, self._subconfig,
uncalculated=uncalculated, uncalculated=uncalculated,
apply_requires=apply_requires, apply_requires=apply_requires,
not_unrestraint=True,
) )
@option_type(["option", "optiondescription", "with_or_without_index"]) @option_type(["option", "optiondescription", "with_or_without_index"])
@ -1140,13 +1056,12 @@ class TiramisuOption(
self._set_subconfig() self._set_subconfig()
return self._subconfig.option.impl_get_group_type() return self._subconfig.option.impl_get_group_type()
@option_type(["optiondescription", "validate_properties"]) @option_type("optiondescription")
def list( def list(
self, self,
*, *,
validate_properties: bool = True, validate_properties: bool = True,
uncalculated: bool = False, uncalculated: bool = False,
with_index: bool = True,
): ):
"""List options inside an option description (by default list only option)""" """List options inside an option description (by default list only option)"""
self._set_subconfig() self._set_subconfig()
@ -1154,7 +1069,6 @@ class TiramisuOption(
self._subconfig, self._subconfig,
validate_properties, validate_properties,
uncalculated=uncalculated, uncalculated=uncalculated,
with_index=with_index,
) )
def _load_dict( def _load_dict(
@ -1275,8 +1189,6 @@ class TiramisuContextValue(TiramisuConfig, _TiramisuODGet):
self, self,
path: str, path: str,
value: Any, value: Any,
*,
index: Optional[int] = None,
only_config=undefined, only_config=undefined,
force_default=undefined, force_default=undefined,
force_default_if_same=undefined, force_default_if_same=undefined,
@ -1292,22 +1204,14 @@ class TiramisuContextValue(TiramisuConfig, _TiramisuODGet):
kwargs["force_default_if_same"] = force_default_if_same kwargs["force_default_if_same"] = force_default_if_same
if force_dont_change_value is not undefined: if force_dont_change_value is not undefined:
kwargs["force_dont_change_value"] = force_dont_change_value kwargs["force_dont_change_value"] = force_dont_change_value
context = self._config_bag.context option_bag = OptionBag(
if isinstance(context, KernelGroupConfig): None,
subconfig = Fake_SubConfig( None,
self._config_bag, self._config_bag,
path, path=path,
index,
)
else:
subconfig = context.get_sub_config(
self._config_bag,
path,
index,
validate_properties=False,
) )
return self._config_bag.context.set_value( return self._config_bag.context.set_value(
subconfig, option_bag,
value, value,
**kwargs, **kwargs,
) )
@ -1695,7 +1599,6 @@ class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
*, *,
validate_properties: bool = True, validate_properties: bool = True,
uncalculated: bool = False, uncalculated: bool = False,
with_index: bool = True,
): ):
"""List options (by default list only option)""" """List options (by default list only option)"""
root = self._config_bag.context.get_root(self._config_bag) root = self._config_bag.context.get_root(self._config_bag)
@ -1703,7 +1606,6 @@ class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
root, root,
validate_properties, validate_properties,
uncalculated=uncalculated, uncalculated=uncalculated,
with_index=with_index,
) )
def _load_dict(self, clearable="all", remotable="minimum"): def _load_dict(self, clearable="all", remotable="minimum"):
@ -2010,7 +1912,7 @@ class Config(TiramisuAPI, TiramisuContextOption):
return f"<Config path=None>" return f"<Config path=None>"
class MetaConfig(TiramisuAPI, TiramisuContextOption): class MetaConfig(TiramisuAPI):
"""MetaConfig object that enables us to handle the sub configuration's options """MetaConfig object that enables us to handle the sub configuration's options
with common root optiondescription with common root optiondescription
""" """
@ -2078,7 +1980,7 @@ class MixConfig(TiramisuAPI):
display_name=display_name, display_name=display_name,
) )
settings = config.get_settings() settings = config.get_settings()
properties = settings.get_context_properties() properties = settings.get_context_properties(config.properties_cache)
permissives = settings.get_context_permissives() permissives = settings.get_context_permissives()
config_bag = ConfigBag( config_bag = ConfigBag(
config, config,

View file

@ -507,7 +507,6 @@ def manager_callback(
index_, index_,
validate_properties=not self_calc, validate_properties=not self_calc,
properties=properties, properties=properties,
valid_conflict=False,
) )
except PropertiesOptionError as err: except PropertiesOptionError as err:
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation # raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation

View file

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2012-2025 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2024 Team tiramisu (see AUTHORS for all contributors)
# #
# 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,12 +91,12 @@ class CCache:
if option.issubdyn(): if option.issubdyn():
# it's an option in dynoptiondescription, remove cache for all generated option # it's an option in dynoptiondescription, remove cache for all generated option
self.reset_cache_dyn_option( self.reset_cache_dyn_option(
subconfig, config_bag,
option, option,
resetted_opts, resetted_opts,
) )
elif option.impl_is_dynoptiondescription(): elif option.impl_is_dynoptiondescription():
self.reset_cache_dyn_optiondescription( self._reset_cache_dyn_optiondescription(
option, option,
config_bag, config_bag,
resetted_opts, resetted_opts,
@ -120,7 +120,13 @@ class CCache:
resetted_opts, resetted_opts,
) )
def get_dynamic_from_dyn_optiondescription(self, config_bag, option): def _reset_cache_dyn_optiondescription(
self,
option,
config_bag,
resetted_opts,
):
# reset cache for all chidren
path = option.impl_getpath() path = option.impl_getpath()
if "." in path: if "." in path:
parent_path = path.rsplit(".", 1)[0] parent_path = path.rsplit(".", 1)[0]
@ -133,21 +139,9 @@ class CCache:
) )
else: else:
parent_subconfig = self.get_root(config_bag) parent_subconfig = self.get_root(config_bag)
return parent_subconfig.dyn_to_subconfig( for subconfig in parent_subconfig.dyn_to_subconfig(
option, option,
False, False,
)
def reset_cache_dyn_optiondescription(
self,
option,
config_bag,
resetted_opts,
):
# reset cache for all chidren
for subconfig in self.get_dynamic_from_dyn_optiondescription(
config_bag,
option,
): ):
self.reset_one_option_cache( self.reset_one_option_cache(
subconfig, subconfig,
@ -163,20 +157,15 @@ class CCache:
resetted_opts, resetted_opts,
) )
def get_dynamic_from_dyn_option(self, subconfig, option): def reset_cache_dyn_option(
config_bag = subconfig.config_bag self,
sub_paths = option.impl_getpath() config_bag,
current_paths = subconfig.path.split(".") option,
current_paths_max_index = len(current_paths) - 1 resetted_opts,
current_subconfigs = [] ):
parent = subconfig
while True:
current_subconfigs.insert(0, parent)
parent = parent.parent
if parent.path is None:
break
currents = [self.get_root(config_bag)] currents = [self.get_root(config_bag)]
for idx, sub_path in enumerate(sub_paths.split(".")): sub_paths = option.impl_getpath()
for sub_path in sub_paths.split("."):
new_currents = [] new_currents = []
for current in currents: for current in currents:
sub_option = current.option.get_child( sub_option = current.option.get_child(
@ -186,12 +175,6 @@ class CCache:
allow_dynoption=True, allow_dynoption=True,
) )
if sub_option.impl_is_dynoptiondescription(): if sub_option.impl_is_dynoptiondescription():
if (
idx <= current_paths_max_index
and sub_option == current_subconfigs[idx].option
):
new_currents.append(current_subconfigs[idx])
else:
new_currents.extend( new_currents.extend(
list( list(
current.dyn_to_subconfig( current.dyn_to_subconfig(
@ -200,6 +183,7 @@ class CCache:
) )
) )
) )
else: else:
new_currents.append( new_currents.append(
current.get_child( current.get_child(
@ -210,15 +194,7 @@ class CCache:
), ),
) )
currents = new_currents currents = new_currents
return currents for dyn_option_subconfig in currents:
def reset_cache_dyn_option(
self,
subconfig,
option,
resetted_opts,
):
for dyn_option_subconfig in self.get_dynamic_from_dyn_option(subconfig, option):
self.reset_one_option_cache( self.reset_one_option_cache(
dyn_option_subconfig, dyn_option_subconfig,
resetted_opts, resetted_opts,
@ -372,31 +348,16 @@ class SubConfig:
validate_properties, validate_properties,
*, *,
uncalculated: bool = False, uncalculated: bool = False,
with_index: bool = True,
): ):
if self.option.impl_is_leadership() and not uncalculated and with_index: if self.option.impl_is_leadership() and not uncalculated:
yield from self.get_leadership_children(validate_properties) yield from self.get_leadership_children(validate_properties)
else: else:
children_name = []
for child in self.option.get_children(): for child in self.option.get_children():
if child.impl_is_dynoptiondescription() and not uncalculated: if child.impl_is_dynoptiondescription() and not uncalculated:
for dyn_child in self.dyn_to_subconfig( yield from self.dyn_to_subconfig(
child, child,
validate_properties, validate_properties,
):
yield dyn_child
if child.could_conflict:
name = dyn_child.path
if name in children_name:
raise ConflictError(
_("option name \"{0}\" is not unique in {1}").format(
name,
self.option.impl_get_display_name(
self, with_quote=True
),
) )
)
children_name.append(name)
else: else:
try: try:
yield self.get_child( yield self.get_child(
@ -407,18 +368,6 @@ class SubConfig:
except PropertiesOptionError as err: except PropertiesOptionError as err:
if err.proptype in (["mandatory"], ["empty"]): if err.proptype in (["mandatory"], ["empty"]):
raise err raise err
if child.could_conflict:
name = child.impl_getpath()
if name in children_name:
raise ConflictError(
_("option name \"{0}\" is not unique in {1}").format(
name,
self.option.impl_get_display_name(
self, with_quote=True
),
)
)
children_name.append(name)
def get_child( def get_child(
self, self,
@ -587,20 +536,6 @@ class SubConfig:
return subconfigs return subconfigs
return subconfigs[0] return subconfigs[0]
def change_context(self, context) -> "SubConfig":
config_bag = self.config_bag.copy()
config_bag.context = context
return SubConfig(
self.option,
self.index,
self.path,
config_bag,
self.parent,
self.identifiers,
true_path=self.true_path,
validate_properties=False,
)
class _Config(CCache): class _Config(CCache):
"""Sub configuration management entry. """Sub configuration management entry.
@ -653,8 +588,80 @@ class _Config(CCache):
"""get cache for values""" """get cache for values"""
return self._impl_values_cache # pylint: disable=no-member return self._impl_values_cache # pylint: disable=no-member
# # ============================================================================= # =============================================================================
# # WALK # WALK
def find(
self,
option_bag,
bytype,
byname,
byvalue,
raise_if_not_found=True,
only_path=undefined,
only_option=undefined,
with_option=False,
):
"""
convenience method for finding an option that lives only in the subtree
:param first: return only one option if True, a list otherwise
:return: find list or an exception if nothing has been found
"""
# pylint: disable=too-many-arguments,too-many-locals
def _filter_by_value(soption_bag):
value = self.get_value(soption_bag)
if isinstance(value, list):
return byvalue in value
return value == byvalue
found = False
if only_path is not undefined:
def _fake_iter():
yield only_option
options = _fake_iter()
else:
options = option_bag.option.get_children_recursively(
bytype,
byname,
option_bag.config_bag,
)
for option in options:
path = option.impl_getpath()
soption_bag = OptionBag(
option,
None,
option_bag.config_bag,
)
if byvalue is not undefined and not _filter_by_value(soption_bag):
continue
if option_bag.config_bag.properties:
# remove option with propertyerror, ...
try:
self.get_sub_config(
option_bag.config_bag, # pylint: disable=no-member
path,
None,
validate_properties=True,
)
except PropertiesOptionError:
continue
found = True
if not with_option:
yield path
else:
yield path, option
self._find_return_results(
found,
raise_if_not_found,
)
def _find_return_results(self, found, raise_if_not_found):
if not found and raise_if_not_found:
raise AttributeError(_("no option found in config" " with these criteria"))
def walk_valid_value( def walk_valid_value(
self, self,
subconfig, subconfig,
@ -699,7 +706,6 @@ class _Config(CCache):
properties=undefined, properties=undefined,
true_path: Optional[str] = None, true_path: Optional[str] = None,
allow_dynoption: bool = False, allow_dynoption: bool = False,
valid_conflict: bool = True,
): ):
subconfig = self.get_root(config_bag) subconfig = self.get_root(config_bag)
if path is None: if path is None:
@ -732,32 +738,6 @@ class _Config(CCache):
identifier, option = option identifier, option = option
else: else:
identifier = None identifier = None
if valid_conflict and option.could_conflict:
for ref in option.could_conflict:
child = ref()
if child.impl_is_dynoptiondescription():
for dyn_child in subconfig.dyn_to_subconfig(
child,
validate_properties,
):
if path == dyn_child.path:
raise ConflictError(
_("option name \"{0}\" is not unique in {1}").format(
name,
option.impl_get_display_name(
subconfig, with_quote=True
),
)
)
elif child.impl_getname() == name:
raise ConflictError(
_("option name \"{0}\" is not unique in {1}").format(
name,
self.option.impl_get_display_name(
self, with_quote=True
),
)
)
subconfig = subconfig.get_child( subconfig = subconfig.get_child(
option, option,
index_, index_,
@ -836,15 +816,6 @@ class _Config(CCache):
# ============================================================================= # =============================================================================
# Manage value # Manage value
def set_value(
self,
subconfig,
value: Any,
) -> Any:
"""set value"""
self.get_settings().validate_properties(subconfig)
return self.get_values().set_value(subconfig, value)
def get_value( def get_value(
self, self,
subconfig, subconfig,
@ -964,8 +935,6 @@ class _Config(CCache):
def get_owner( def get_owner(
self, self,
subconfig: "SubConfig", subconfig: "SubConfig",
*,
validate_meta=True,
): ):
"""get owner""" """get owner"""
subconfigs = self._get( subconfigs = self._get(
@ -976,14 +945,13 @@ class _Config(CCache):
for sc in subconfigs: for sc in subconfigs:
owner = self.get_owner( owner = self.get_owner(
sc, sc,
validate_meta=validate_meta,
) )
if owner != owners.default: if owner != owners.default:
break break
else: else:
owner = owners.default owner = owners.default
else: else:
owner = self.get_values().getowner(subconfigs, validate_meta=validate_meta) owner = self.get_values().getowner(subconfigs)
return owner return owner
@ -1264,10 +1232,6 @@ class KernelGroupConfig(_CommonConfig):
# pylint: disable=super-init-not-called # pylint: disable=super-init-not-called
names = [] names = []
for child in children: for child in children:
if not isinstance(child, (KernelConfig, KernelGroupConfig)):
raise TypeError(
_("child must be a Config, GroupConfig, MixConfig or MetaConfig")
)
name_ = child._impl_name name_ = child._impl_name
names.append(name_) names.append(name_)
if len(names) != len(set(names)): if len(names) != len(set(names)):
@ -1295,58 +1259,61 @@ class KernelGroupConfig(_CommonConfig):
def reset_cache( def reset_cache(
self, self,
subconfig, option_bag,
resetted_opts=None, resetted_opts=None,
): ):
if resetted_opts is None: if resetted_opts is None:
resetted_opts = [] resetted_opts = []
if isinstance(self, KernelMixConfig): if isinstance(self, KernelMixConfig):
super().reset_cache( super().reset_cache(
subconfig, option_bag,
resetted_opts=copy(resetted_opts), resetted_opts=copy(resetted_opts),
) )
for child in self._impl_children: for child in self._impl_children:
if subconfig is not None: if option_bag is not None:
parent_subconfig = subconfig.change_context(child) coption_bag = option_bag.copy()
cconfig_bag = coption_bag.config_bag.copy()
cconfig_bag.context = child
coption_bag.config_bag = cconfig_bag
else: else:
parent_subconfig = None coption_bag = None
child.reset_cache( child.reset_cache(
parent_subconfig, coption_bag,
resetted_opts=copy(resetted_opts), resetted_opts=copy(resetted_opts),
) )
def set_value( def set_value(
self, self,
subconfig, option_bag,
value, value,
only_config=False, only_config=False,
): ):
"""Setattr not in current KernelGroupConfig, but in each children""" """Setattr not in current KernelGroupConfig, but in each children"""
ret = [] ret = []
for child in self._impl_children: for child in self._impl_children:
cconfig_bag = subconfig.config_bag.copy() cconfig_bag = option_bag.config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
if isinstance(child, KernelGroupConfig): if isinstance(child, KernelGroupConfig):
ret.extend( ret.extend(
child.set_value( child.set_value(
subconfig, option_bag,
value, value,
only_config=only_config, only_config=only_config,
) )
) )
else: else:
settings = child.get_settings() settings = child.get_settings()
properties = settings.get_context_properties() properties = settings.get_context_properties(child.properties_cache)
permissives = settings.get_context_permissives() permissives = settings.get_context_permissives()
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
try: try:
# GROUP # GROUP
coption_bag = child.get_sub_config( coption_bag = child.get_sub_option_bag(
cconfig_bag, cconfig_bag,
subconfig.path, option_bag.path,
subconfig.index, option_bag.index,
validate_properties=False, False,
) )
child.set_value( child.set_value(
coption_bag, coption_bag,
@ -1356,7 +1323,7 @@ class KernelGroupConfig(_CommonConfig):
# pylint: disable=protected-access # pylint: disable=protected-access
ret.append( ret.append(
PropertiesOptionError( PropertiesOptionError(
err._subconfig, err._option_bag,
err.proptype, err.proptype,
err._settings, err._settings,
err._opt_type, err._opt_type,
@ -1419,7 +1386,7 @@ class KernelGroupConfig(_CommonConfig):
cconfig_bag.context = child cconfig_bag.context = child
if cconfig_bag.properties is None: if cconfig_bag.properties is None:
settings = child.get_settings() settings = child.get_settings()
properties = settings.get_context_properties() properties = settings.get_context_properties(child.properties_cache)
permissives = settings.get_context_permissives() permissives = settings.get_context_permissives()
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
@ -1453,7 +1420,6 @@ class KernelGroupConfig(_CommonConfig):
def reset( def reset(
self, self,
path: str, path: str,
only_children: bool,
config_bag: ConfigBag, config_bag: ConfigBag,
) -> None: ) -> None:
"""reset value for specified path""" """reset value for specified path"""
@ -1462,19 +1428,19 @@ class KernelGroupConfig(_CommonConfig):
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
settings = child.get_settings() settings = child.get_settings()
properties = settings.get_context_properties() properties = settings.get_context_properties(child.properties_cache)
permissives = settings.get_context_permissives() permissives = settings.get_context_permissives()
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = permissives cconfig_bag.permissives = permissives
cconfig_bag.remove_validation() cconfig_bag.remove_validation()
# GROUP # GROUP
subconfig = child.get_sub_config( option_bag = child.get_sub_option_bag(
cconfig_bag, cconfig_bag,
path, path,
None, None,
validate_properties=False, False,
) )[-1]
child.get_values().reset(subconfig) child.get_values().reset(option_bag)
def getconfig( def getconfig(
self, self,
@ -1529,7 +1495,7 @@ class KernelMixConfig(KernelGroupConfig):
def set_value( def set_value(
self, self,
subconfig, option_bag,
value, value,
only_config=False, only_config=False,
force_default=False, force_default=False,
@ -1560,10 +1526,10 @@ class KernelMixConfig(KernelGroupConfig):
) )
) )
for child in self._impl_children: for child in self._impl_children:
cconfig_bag = subconfig.config_bag.copy() cconfig_bag = option_bag.config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
settings = child.get_settings() settings = child.get_settings()
properties = settings.get_context_properties() properties = settings.get_context_properties(child.properties_cache)
cconfig_bag.properties = properties cconfig_bag.properties = properties
cconfig_bag.permissives = settings.get_context_permissives() cconfig_bag.permissives = settings.get_context_permissives()
try: try:
@ -1575,16 +1541,14 @@ class KernelMixConfig(KernelGroupConfig):
not force_default and not force_default_if_same not force_default and not force_default_if_same
) )
# MIX # MIX
moption_bag = obj.get_sub_config( moption_bag = obj.get_sub_option_bag(
cconfig_bag, cconfig_bag,
subconfig.path, option_bag.path,
subconfig.index, option_bag.index,
validate_properties=validate_properties, validate_properties,
) )[-1]
if force_default_if_same: if force_default_if_same:
if not child.get_values().hasvalue( if not child.get_values().hasvalue(option_bag.path):
subconfig.path, index=subconfig.index
):
child_value = undefined child_value = undefined
else: else:
child_value = child.get_value(moption_bag) child_value = child.get_value(moption_bag)
@ -1604,7 +1568,7 @@ class KernelMixConfig(KernelGroupConfig):
# pylint: disable=protected-access # pylint: disable=protected-access
ret.append( ret.append(
PropertiesOptionError( PropertiesOptionError(
err._subconfig, err._option_bag,
err.proptype, err.proptype,
err._settings, err._settings,
err._opt_type, err._opt_type,
@ -1617,12 +1581,12 @@ class KernelMixConfig(KernelGroupConfig):
try: try:
# MIX # MIX
moption_bag = self.get_sub_config( moption_bag = self.get_sub_option_bag(
subconfig.config_bag, option_bag.config_bag,
subconfig.path, option_bag.path,
subconfig.index, option_bag.index,
validate_properties=not only_config, not only_config,
) )[-1]
if only_config: if only_config:
ret = super().set_value( ret = super().set_value(
moption_bag, moption_bag,
@ -1651,37 +1615,37 @@ class KernelMixConfig(KernelGroupConfig):
rconfig_bag.remove_validation() rconfig_bag.remove_validation()
if self.impl_type == "meta": if self.impl_type == "meta":
# MIX # MIX
subconfig = self.get_sub_config( option_bag = self.get_sub_option_bag(
config_bag, config_bag,
path, path,
None, None,
validate_properties=True, True,
) )[-1]
elif not only_children: elif not only_children:
try: try:
# MIX # MIX
subconfig = self.get_sub_config( option_bag = self.get_sub_option_bag(
rconfig_bag, rconfig_bag,
path, path,
None, None,
validate_properties=True, True,
) )[-1]
except AttributeError: except AttributeError:
only_children = True only_children = True
for child in self._impl_children: for child in self._impl_children:
rconfig_bag.context = child rconfig_bag.context = child
try: try:
if self.impl_type == "meta": if self.impl_type == "meta":
moption_bag = subconfig moption_bag = option_bag
moption_bag.config_bag = rconfig_bag moption_bag.config_bag = rconfig_bag
else: else:
# MIX # MIX
moption_bag = child.get_sub_config( moption_bag = child.get_sub_option_bag(
rconfig_bag, rconfig_bag,
path, path,
None, None,
validate_properties=True, True,
) )[-1]
child.get_values().reset(moption_bag) child.get_values().reset(moption_bag)
except AttributeError: except AttributeError:
pass pass
@ -1692,8 +1656,8 @@ class KernelMixConfig(KernelGroupConfig):
rconfig_bag, rconfig_bag,
) )
if not only_children: if not only_children:
subconfig.config_bag = config_bag option_bag.config_bag = config_bag
self.get_values().reset(subconfig) self.get_values().reset(option_bag)
def new_config( def new_config(
self, self,

View file

@ -249,19 +249,19 @@ class LeadershipError(Exception):
option = subconfig.option option = subconfig.option
self.display_name = option.impl_get_display_name(subconfig, with_quote=True) self.display_name = option.impl_get_display_name(subconfig, with_quote=True)
self.code = code self.code = code
if prop is not None: if prop:
self.prop = prop self.prop = prop
if index is not None: if index:
self.index = index self.index = index
if length is not None: if length:
self.length = length self.length = length
if callback is not None: if callback:
self.callback = callback self.callback = callback
if args is not None: if args:
self.args = args self.args = args
if kwargs is not None: if kwargs:
self.kwargs = kwargs self.kwargs = kwargs
if ret is not None: if ret:
self.ret = ret self.ret = ret
def __str__(self): def __str__(self):
@ -310,8 +310,6 @@ class _CommonError:
self.display_type = display_type self.display_type = display_type
self.opt = weakref.ref(opt) self.opt = weakref.ref(opt)
self.name = opt.impl_get_display_name(subconfig, with_quote=True) self.name = opt.impl_get_display_name(subconfig, with_quote=True)
if subconfig:
self.path = subconfig.path
self.err_msg = err_msg self.err_msg = err_msg
self.index = index self.index = index
super().__init__(self.err_msg) super().__init__(self.err_msg)
@ -396,12 +394,6 @@ class CancelParam(Exception):
return False return False
class ValueErrorIndexes(ValueError):
def __init__(self, msg, indexes):
super().__init__(msg)
self.indexes = indexes
class Errors: class Errors:
@staticmethod @staticmethod
def raise_carry_out_calculation_error( def raise_carry_out_calculation_error(

View file

@ -59,7 +59,6 @@ class Base:
"_dependencies", "_dependencies",
"_dependencies_information", "_dependencies_information",
"_identifiers_dependencies", "_identifiers_dependencies",
"could_conflict",
"__weakref__", "__weakref__",
) )
@ -94,7 +93,6 @@ class Base:
_setattr = object.__setattr__ _setattr = object.__setattr__
_setattr(self, "_name", name) _setattr(self, "_name", name)
_setattr(self, "_informations", {"doc": doc}) _setattr(self, "_informations", {"doc": doc})
_setattr(self, "could_conflict", [])
for prop in properties: for prop in properties:
if not isinstance(prop, str): if not isinstance(prop, str):
if not isinstance(prop, Calculation): if not isinstance(prop, Calculation):
@ -190,7 +188,6 @@ class Base:
else: else:
dico = tuple([keys, tuple(dico.values())]) dico = tuple([keys, tuple(dico.values())])
_setattr(self, "_informations", dico) _setattr(self, "_informations", dico)
_setattr(self, "could_conflict", tuple(self.could_conflict))
extra = getattr(self, "_extra", None) extra = getattr(self, "_extra", None)
if extra is not None: if extra is not None:
_setattr( _setattr(

View file

@ -21,12 +21,11 @@
"""ChoiceOption """ChoiceOption
""" """
from typing import Any from typing import Any
from itertools import chain
from ..setting import undefined from ..setting import undefined
from ..i18n import _ from ..i18n import _
from .option import Option from .option import Option
from ..autolib import Calculation, get_calculated_value, ParamOption from ..autolib import Calculation, get_calculated_value
from ..error import ConfigError, display_list from ..error import ConfigError, display_list
@ -43,11 +42,7 @@ class ChoiceOption(Option):
""" """
:param values: is a list of values the option can possibly take :param values: is a list of values the option can possibly take
""" """
if isinstance(values, Calculation): if not isinstance(values, (Calculation, tuple)):
for param in chain(values.params.args, values.params.kwargs.values()):
if isinstance(param, ParamOption):
param.option._add_dependency(self)
elif not isinstance(values, tuple):
raise TypeError( raise TypeError(
_("values must be a tuple or a calculation for {0}").format(name) _("values must be a tuple or a calculation for {0}").format(name)
) )

View file

@ -82,9 +82,6 @@ class DynOptionDescription(OptionDescription):
identifier = identifier.replace(".", "_") identifier = identifier.replace(".", "_")
return identifier return identifier
def name_could_conflict(self, dynchild, child):
return child.impl_getname().startswith(dynchild.impl_getname())
def impl_is_dynoptiondescription(self) -> bool: def impl_is_dynoptiondescription(self) -> bool:
return True return True
@ -148,11 +145,7 @@ class DynOptionDescription(OptionDescription):
) )
else: else:
values_.append(val) values_.append(val)
if ( if __debug__ and len(values_) > len(set(values_)):
__debug__
and "demoting_error_warning" not in subconfig.config_bag.properties
and len(values_) > len(set(values_))
):
raise ValueError( raise ValueError(
_( _(
'DynOptionDescription "{0}" identifiers return a list with same values "{1}"' 'DynOptionDescription "{0}" identifiers return a list with same values "{1}"'

View file

@ -281,18 +281,17 @@ class Option(BaseOption):
force_index = None force_index = None
is_warnings_only = getattr(self, "_warnings_only", False) is_warnings_only = getattr(self, "_warnings_only", False)
def _is_not_unique(current_value, values): def _is_not_unique(value):
if current_value is None: # if set(value) has not same length than value
return
if not subconfig or not check_error or "unique" not in subconfig.properties: if not subconfig or not check_error or "unique" not in subconfig.properties:
return return
indexes = [ lvalue = [val for val in value if val is not None]
index for index, value in enumerate(values) if value == current_value if len(set(lvalue)) == len(lvalue):
] return
if len(indexes) > 1: for idx, val in enumerate(value):
raise ValueError( if val not in value[idx + 1 :]:
_('the value "{}" is not unique' "").format(current_value) continue
) raise ValueError(_('the value "{}" is not unique' "").format(val))
def calculation_validator( def calculation_validator(
val, val,
@ -395,40 +394,29 @@ class Option(BaseOption):
_index, _index,
) )
val = value
err_index = force_index err_index = force_index
ret = True
if not self.impl_is_multi():
try: try:
if not self.impl_is_multi():
do_validation( do_validation(
value, val,
None, None,
) )
except ValueError as err:
self.validate_parse_error(value, err_index, err, subconfig)
ret = False
elif force_index is not None: elif force_index is not None:
if self.impl_is_submulti(): if self.impl_is_submulti():
if not isinstance(value, list): if not isinstance(value, list):
raise ValueError(_("which must be a list")) raise ValueError(_("which must be a list"))
for val in value: for val in value:
try:
do_validation( do_validation(
val, val,
force_index, force_index,
) )
_is_not_unique(val, value) _is_not_unique(value)
except ValueError as err:
self.validate_parse_error(val, err_index, err, subconfig)
ret = False
else: else:
try:
do_validation( do_validation(
value, val,
force_index, force_index,
) )
except ValueError as err:
self.validate_parse_error(value, err_index, err, subconfig)
ret = False
elif isinstance(value, Calculation) and not subconfig: elif isinstance(value, Calculation) and not subconfig:
pass pass
elif self.impl_is_submulti(): elif self.impl_is_submulti():
@ -440,30 +428,19 @@ class Option(BaseOption):
_('which "{}" must be a list of list' "").format(lval) _('which "{}" must be a list of list' "").format(lval)
) )
for val in lval: for val in lval:
try:
do_validation(val, err_index) do_validation(val, err_index)
_is_not_unique(val, lval) _is_not_unique(lval)
except ValueError as err:
self.validate_parse_error(val, err_index, err, subconfig)
ret = False
elif not isinstance(value, list): elif not isinstance(value, list):
raise ValueError(_("which must be a list")) raise ValueError(_("which must be a list"))
else: else:
# FIXME suboptimal, not several time for whole=True! # FIXME suboptimal, not several time for whole=True!
for err_index, val in enumerate(value): for err_index, val in enumerate(value):
try:
do_validation( do_validation(
val, val,
err_index, err_index,
) )
_is_not_unique(val, value) _is_not_unique(value)
except ValueError as err: except ValueError as err:
self.validate_parse_error(val, err_index, err, subconfig)
ret = False
# return False
return ret
def validate_parse_error(self, val, index, err, subconfig):
if ( if (
not subconfig not subconfig
or "demoting_error_warning" not in subconfig.config_bag.properties or "demoting_error_warning" not in subconfig.config_bag.properties
@ -474,7 +451,7 @@ class Option(BaseOption):
display_type=_(self.get_type()), display_type=_(self.get_type()),
opt=self, opt=self,
err_msg=str(err), err_msg=str(err),
index=index, index=err_index,
) from err ) from err
warnings.warn_explicit( warnings.warn_explicit(
ValueErrorWarning( ValueErrorWarning(
@ -483,12 +460,14 @@ class Option(BaseOption):
display_type=_(self.get_type()), display_type=_(self.get_type()),
opt=self, opt=self,
err_msg=str(err), err_msg=str(err),
index=index, index=err_index,
), ),
ValueErrorWarning, ValueErrorWarning,
self.__class__.__name__, self.__class__.__name__,
0, 0,
) )
return False
return True
def validate_with_option( def validate_with_option(
self, self,

View file

@ -106,24 +106,7 @@ class CacheOptionDescription(BaseOption):
if "force_store_value" in properties: if "force_store_value" in properties:
force_store_values.append(option) force_store_values.append(option)
if option.impl_is_readonly(): if option.impl_is_readonly():
previous_path = option.impl_getpath() raise ConflictError(_("duplicate option: {0}").format(option))
if "." in previous_path:
previous_path = _('"{0}" option description').format(
previous_path.rsplit(".", 1)[0]
)
else:
previous_path = _("root option description")
if currpath:
current_path = _('"{0}" option description').format(
".".join(currpath)
)
else:
current_path = _("root option description")
raise ConflictError(
_('option "{0}" is include in {1} but is also in {2}').format(
option.impl_get_display_name(None), current_path, previous_path
)
)
if not self.impl_is_readonly() and display_name: if not self.impl_is_readonly() and display_name:
option._display_name_function = ( option._display_name_function = (
display_name # pylint: disable=protected-access display_name # pylint: disable=protected-access
@ -303,6 +286,31 @@ class OptionDescriptionWalk(CacheOptionDescription):
"""get children""" """get children"""
return self._children[1] return self._children[1]
def get_children_recursively(
self,
bytype: Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt: BaseOption = None,
*,
option_identifiers: Optional[list] = None,
) -> Iterator[Union[BaseOption]]:
"""get children recursively"""
if self_opt is None:
self_opt = self
for option in self_opt.get_children():
if option.impl_is_optiondescription():
for subopt in option.get_children_recursively(
bytype,
byname,
config_bag,
):
yield subopt
elif (byname is None or option.impl_getname() == byname) and (
bytype is None or isinstance(option, bytype)
):
yield option
class OptionDescription(OptionDescriptionWalk): class OptionDescription(OptionDescriptionWalk):
"""Config's schema (organisation, group) and container of Options """Config's schema (organisation, group) and container of Options
@ -335,38 +343,35 @@ class OptionDescription(OptionDescriptionWalk):
properties=properties, properties=properties,
) )
child_names = [] child_names = []
fix_child_names = [] if __debug__:
dynopts = [] dynopt_names = []
for child in children: for child in children:
name = child.impl_getname() name = child.impl_getname()
child_names.append(name) child_names.append(name)
if child.impl_is_dynoptiondescription(): if __debug__ and child.impl_is_dynoptiondescription():
dynopts.append(child) dynopt_names.append(name)
else:
fix_child_names.append(name)
# before sorting # before sorting
children_ = (tuple(child_names), tuple(children)) children_ = (tuple(child_names), tuple(children))
if __debug__:
# better performance like this # better performance like this
fix_child_names.sort() child_names.sort()
old = None old = None
for child_name in fix_child_names: for child in child_names:
if child_name == old: if child == old:
raise ConflictError( raise ConflictError(
_('the option name "{0}" is duplicate in "{1}"').format( _("duplicate option name: " '"{0}"').format(child)
child_name, self.impl_get_display_name(None)
) )
if dynopt_names:
for dynopt in dynopt_names:
if child != dynopt and child.startswith(dynopt):
raise ConflictError(
_(
'the option\'s name "{0}" start as the dynoptiondescription\'s name "{1}"'
).format(child, dynopt)
) )
old = child_name old = child
for dynopt in dynopts:
if dynopt.could_conflict:
continue
for child in children:
if child != dynopt and dynopt.name_could_conflict(dynopt, child):
dynopt.could_conflict.append(weakref.ref(child))
child.could_conflict.append(weakref.ref(dynopt))
break
self._children = children_ self._children = children_
# the group_type is useful for filtering OptionDescriptions in a config # the group_type is useful for filtering OptionDescriptions in a config
self._group_type = None self._group_type = None

View file

@ -20,6 +20,8 @@
# ____________________________________________________________ # ____________________________________________________________
"""PortOption """PortOption
""" """
import re
from ..i18n import _ from ..i18n import _
from .stroption import StrOption from .stroption import StrOption
@ -36,6 +38,7 @@ class PortOption(StrOption):
""" """
__slots__ = tuple() __slots__ = tuple()
port_re = re.compile(r"^[0-9]*$")
_type = "port" _type = "port"
def __init__( def __init__(
@ -101,7 +104,7 @@ class PortOption(StrOption):
value = [value] value = [value]
for val in value: for val in value:
if not val.isdecimal(): if not self.port_re.search(val):
raise ValueError() raise ValueError()
def second_level_validation(self, value: str, warnings_only: bool) -> None: def second_level_validation(self, value: str, warnings_only: bool) -> None:

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"sets the options of the configuration objects Config object itself" "sets the options of the configuration objects Config object itself"
# Copyright (C) 2012-2025 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2012-2024 Team tiramisu (see AUTHORS for all contributors)
# #
# 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,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"takes care of the option's values and multi values" "takes care of the option's values and multi values"
# Copyright (C) 2013-2025 Team tiramisu (see AUTHORS for all contributors) # Copyright (C) 2013-2024 Team tiramisu (see AUTHORS for all contributors)
# #
# 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
@ -189,9 +189,10 @@ class Values:
if subconfig.config_bag.context.impl_type == "config": if subconfig.config_bag.context.impl_type == "config":
return True return True
# it's a not a config, force to metaconfig only in *explicitly* set # it's a not a config, force to metaconfig only in *explicitly* set
return "force_metaconfig_on_freeze" in settings.get_personalize_properties( return "force_metaconfig_on_freeze" in settings.get_stored_properties(
subconfig.path, subconfig.path,
subconfig.index, subconfig.index,
frozenset(),
) )
return False return False
@ -433,28 +434,36 @@ class Values:
If not found, return None If not found, return None
For follower option, return the Config where leader is modified For follower option, return the Config where leader is modified
""" """
def build_option_bag(subconfig, parent):
doption_bag = subconfig.copy()
config_bag = subconfig.config_bag.copy()
config_bag.context = parent
config_bag.unrestraint()
doption_bag.config_bag = config_bag
return doption_bag
for parent in subconfig.config_bag.context.get_parents(): for parent in subconfig.config_bag.context.get_parents():
parent_subconfig = subconfig.change_context(parent) doption_bag = build_option_bag(subconfig, parent)
parent_subconfig.config_bag.unrestraint()
parent_subconfig.properties = subconfig.properties
if "force_metaconfig_on_freeze" in subconfig.properties: if "force_metaconfig_on_freeze" in subconfig.properties:
# remove force_metaconfig_on_freeze only if option in metaconfig # remove force_metaconfig_on_freeze only if option in metaconfig
# hasn't force_metaconfig_on_freeze properties # hasn't force_metaconfig_on_freeze properties
ori_properties = parent_subconfig.properties ori_properties = doption_bag.properties
settings = parent_subconfig.config_bag.context.get_settings() settings = doption_bag.config_bag.context.get_settings()
parent_subconfig.properties = settings.getproperties(parent_subconfig) doption_bag.properties = settings.getproperties(doption_bag)
if not self.check_force_to_metaconfig(parent_subconfig): if not self.check_force_to_metaconfig(doption_bag):
parent_subconfig.properties = ori_properties - { doption_bag.properties = ori_properties - {
"force_metaconfig_on_freeze" "force_metaconfig_on_freeze"
} }
else: else:
parent_subconfig.properties = ori_properties doption_bag.properties = ori_properties
parent_owner = parent.get_values().getowner( parent_owner = parent.get_values().getowner(
parent_subconfig, doption_bag,
parent,
only_default=True, only_default=True,
) )
if parent_owner != owners.default: if parent_owner != owners.default:
return parent_subconfig return doption_bag
return None return None
@ -508,6 +517,9 @@ class Values:
was present was present
:returns: a `setting.owners.Owner` object :returns: a `setting.owners.Owner` object
""" """
# context = subconfig.config_bag.context
# settings = context.get_settings()
# settings.validate_properties(subconfig)
if ( if (
"frozen" in subconfig.properties "frozen" in subconfig.properties
and "force_default_on_freeze" in subconfig.properties and "force_default_on_freeze" in subconfig.properties
@ -536,10 +548,11 @@ class Values:
values = msubconfig.config_bag.context.get_values() values = msubconfig.config_bag.context.get_values()
owner = values.getowner( owner = values.getowner(
msubconfig, msubconfig,
parent,
only_default=only_default, only_default=only_default,
) )
elif "force_metaconfig_on_freeze" in subconfig.properties: elif "force_metaconfig_on_freeze" in subconfig.properties:
owner = owners.default return owners.default
return owner return owner
def set_owner( def set_owner(
@ -736,8 +749,8 @@ class Values:
if index >= length: if index >= length:
raise IndexError( raise IndexError(
_( _(
f"index {index} is greater than the length {length} " "index {index} is greater than the length {length} "
f"for option {subconfig.option.impl_get_display_name(subconfig, with_quote=True)}" "for option {subconfig.option.impl_get_display_name(with_quote=True)}"
) )
) )
current_value.pop(index) current_value.pop(index)