Compare commits
No commits in common. "5.2.0a9" and "main" have entirely different histories.
37 changed files with 889 additions and 1504 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2025-05-12 09:05+0200\n"
|
||||
"POT-Creation-Date: 2024-11-05 08:52+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -35,380 +35,288 @@ msgstr ""
|
|||
msgid "Commands:"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:111 tiramisu/api.py:1857
|
||||
#: tiramisu/api.py:111 tiramisu/api.py:1840
|
||||
msgid "please specify a valid sub function ({0}.{1})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:196
|
||||
#: tiramisu/api.py:194
|
||||
msgid "please do not specify index ({0}.{1})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:201 tiramisu/api.py:856
|
||||
#: tiramisu/api.py:199 tiramisu/api.py:844
|
||||
msgid "please specify index with a follower option ({0}.{1})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:222
|
||||
#: tiramisu/api.py:220
|
||||
msgid "please specify a valid sub function ({0}.{1}): {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:446
|
||||
#: tiramisu/api.py:431
|
||||
msgid "the option {0} is not a dynamic option, cannot get identifiers with only_self parameter to True"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:532
|
||||
#: tiramisu/api.py:517
|
||||
msgid "cannot get option from a follower symlink without index"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:607
|
||||
#: tiramisu/api.py:592
|
||||
msgid "cannot add this property: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:634
|
||||
#: tiramisu/api.py:619
|
||||
msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:638
|
||||
#: tiramisu/api.py:623
|
||||
msgid "cannot find \"{0}\" in option \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:643
|
||||
#: tiramisu/api.py:628
|
||||
msgid "cannot remove option's property \"{0}\", use permissive instead in option \"{1}\" at index \"{2}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:647
|
||||
#: tiramisu/api.py:632
|
||||
msgid "cannot find \"{0}\" in option \"{1}\" at index \"{2}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:691
|
||||
#: tiramisu/api.py:676
|
||||
msgid "cannot find \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:873
|
||||
#: tiramisu/api.py:808
|
||||
msgid "cannot reduce length of the leader {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:861
|
||||
msgid "only multi value has defaultmulti"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:1037
|
||||
#: tiramisu/api.py:1020
|
||||
msgid "please specify a valid sub function ({0}.{1}) for {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:1424
|
||||
#: tiramisu/api.py:1407
|
||||
msgid "properties must be a frozenset"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:1428 tiramisu/api.py:1455
|
||||
#: tiramisu/api.py:1411 tiramisu/api.py:1438
|
||||
msgid "unknown when {} (must be in append or remove)"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:1441 tiramisu/api.py:1465 tiramisu/config.py:1676
|
||||
#: tiramisu/api.py:1424 tiramisu/api.py:1448 tiramisu/config.py:1680
|
||||
msgid "unknown type {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/api.py:1829
|
||||
#: tiramisu/api.py:1812
|
||||
msgid "do not use unrestraint, nowarnings or forcepermissive together"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:89
|
||||
#: tiramisu/autolib.py:80
|
||||
msgid "args in params must be a tuple"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:92 tiramisu/autolib.py:97
|
||||
#: tiramisu/autolib.py:83 tiramisu/autolib.py:88
|
||||
msgid "arg in params must be a Param"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:94
|
||||
#: tiramisu/autolib.py:85
|
||||
msgid "kwargs in params must be a dict"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:122
|
||||
#: tiramisu/autolib.py:113
|
||||
msgid "paramoption needs an option not {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:128
|
||||
#: tiramisu/autolib.py:119
|
||||
msgid "param must have a boolean not a {} for notraisepropertyerror"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:131
|
||||
#: tiramisu/autolib.py:122
|
||||
msgid "param must have a boolean not a {} for raisepropertyerror"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:160
|
||||
msgid "identifiers in ParamDynOption must be a list, not {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:166
|
||||
msgid "optional in ParamDynOption must be a boolean, not {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:220
|
||||
msgid "cannot add option in information after creating config"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:223
|
||||
msgid "cannot redefine option in information"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:227
|
||||
#: tiramisu/autolib.py:212
|
||||
msgid "option in ParamInformation cannot be a symlinkoption"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:230
|
||||
#: tiramisu/autolib.py:215
|
||||
msgid "option in ParamInformation cannot be a follower"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:233
|
||||
#: tiramisu/autolib.py:218
|
||||
msgid "option in ParamInformation cannot be a dynamic option"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:294
|
||||
#: tiramisu/autolib.py:279
|
||||
msgid "first argument ({0}) must be a function"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:298
|
||||
#: tiramisu/autolib.py:283
|
||||
msgid "help_function ({0}) must be a function"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:469 tiramisu/autolib.py:524
|
||||
#: tiramisu/autolib.py:452 tiramisu/autolib.py:514
|
||||
msgid "unable to carry out a calculation for {}, {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:461 tiramisu/autolib.py:521
|
||||
msgid "the option {0} is used in a calculation but is invalid ({1})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:482 tiramisu/autolib.py:538 tiramisu/autolib.py:588
|
||||
#: tiramisu/autolib.py:477 tiramisu/autolib.py:535 tiramisu/autolib.py:584
|
||||
msgid "unable to get value for calculating {0}, {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:517
|
||||
msgid "unable to carry out a calculation for {0}, {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:563
|
||||
msgid "cannot find information for {0}, {1} is a dynamic option"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:603
|
||||
#: tiramisu/autolib.py:601
|
||||
msgid "option {0} is not a dynoptiondescription or in a dynoptiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:696
|
||||
msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", there is no identifiers"
|
||||
#: tiramisu/autolib.py:848
|
||||
msgid "the \"{}\" function with positional arguments \"{}\" and keyword arguments \"{}\" must not return a list (\"{}\") for the follower option {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:708
|
||||
msgid "cannot calculate arguments for {0}, {1} with identifier \"{2}\", list of valid identifiers: {3}"
|
||||
#: tiramisu/autolib.py:863
|
||||
msgid "the \"{}\" function must not return a list (\"{}\") for the follower option {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:819
|
||||
msgid "the follower {0} must have index in carry_out_calculation!"
|
||||
#: tiramisu/autolib.py:904
|
||||
msgid "unexpected error \"{0}\" in function \"{1}\" with arguments \"{3}\" and \"{4}\" for option {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:931
|
||||
msgid "unexpected error \"{1}\" in function \"{2}\" with arguments \"{3}\" and \"{4}\" for option {0}"
|
||||
#: tiramisu/autolib.py:915
|
||||
msgid "unexpected error \"{0}\" in function \"{1}\" for option {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/autolib.py:941
|
||||
msgid "unexpected error \"{1}\" in function \"{2}\" for option {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:574
|
||||
msgid "there is no option description for this config (may be GroupConfig)"
|
||||
msgstr ""
|
||||
|
||||
#: 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"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1140
|
||||
msgid "parent of {0} not already exists"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1187
|
||||
msgid "cannot set leadership object has root optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1190
|
||||
msgid "cannot set dynoptiondescription object has root optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1242
|
||||
msgid "config name must be uniq in groupconfig for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1453
|
||||
msgid "unknown config \"{}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1478
|
||||
msgid "child must be a Config, MixConfig or MetaConfig"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1513
|
||||
msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1523
|
||||
msgid "force_default and force_dont_change_value cannot be set together"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1672
|
||||
msgid "config name must be uniq in groupconfig for {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1717
|
||||
msgid "config added has no name, the name is mandatory"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1722
|
||||
msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1740 tiramisu/config.py:1746
|
||||
msgid "cannot find the config {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1772
|
||||
msgid "MetaConfig with optiondescription must have string has child, not {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1784
|
||||
msgid "child must be a Config or MetaConfig"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1789
|
||||
msgid "all config in metaconfig must have the same optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1806
|
||||
msgid "metaconfig must have the same optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:48
|
||||
msgid "and"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:50
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:72
|
||||
msgid " {} "
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:145
|
||||
msgid "cannot modify the {0} {1} at index \"{2}\" because {3} is frozen"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:149
|
||||
msgid "cannot modify the {0} {1} at index \"{2}\" because is frozen"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:154
|
||||
msgid "cannot modify the {0} {1} because {2} is frozen"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:156
|
||||
msgid "cannot modify the {0} {1} because is frozen"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:160
|
||||
msgid "cannot access to {0} {1} at index \"{2}\" because {3} hasn't value"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:164
|
||||
msgid "{0} {1} at index \"{2}\" is mandatory but hasn't value"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:167
|
||||
msgid "cannot access to {0} {1} because {2} hasn't value"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:169
|
||||
msgid "{0} {1} is mandatory but hasn't value"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:173
|
||||
msgid "cannot access to {0} {1} at index \"{2}\" because {3} has {4} {5}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:177
|
||||
msgid "cannot access to {0} {1} at index \"{2}\" because has {3} {4}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:182
|
||||
msgid "cannot access to {0} {1} because {2} has {3} {4}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:184
|
||||
msgid "cannot access to {0} {1} because has {2} {3}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:187
|
||||
msgid "property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:189
|
||||
msgid "properties"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:204
|
||||
msgid "cannot access to \"{0}\" it's a dynamic option"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:205
|
||||
msgid "\"{0}\" is not an option"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:269
|
||||
msgid "cannot set \"group_type\" attribute for the Leadership {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:273
|
||||
msgid "the leader {0} cannot have \"{1}\" property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:277
|
||||
msgid "the leader {0} cannot have \"force_default_on_freeze\" or \"force_metaconfig_on_freeze\" property without \"frozen\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:281
|
||||
msgid "cannot reduce length of the leader {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:283
|
||||
#: tiramisu/config.py:419
|
||||
msgid "index \"{0}\" is greater than the leadership length \"{1}\" for option {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:287
|
||||
#: tiramisu/config.py:579
|
||||
msgid "there is no option description for this config (may be GroupConfig)"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:668
|
||||
msgid "no option found in config with these criteria"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:871
|
||||
msgid "the follower option {0} has greater length ({1}) than the leader length ({2})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:292
|
||||
msgid "the \"{0}\" function with positional arguments \"{1}\" and keyword arguments \"{2}\" must not return a list (\"{3}\") for the follower option {4}"
|
||||
#: tiramisu/config.py:982 tiramisu/option/optiondescription.py:74
|
||||
msgid "option description seems to be part of an other config"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:297
|
||||
msgid "the \"{0}\" function must not return a list (\"{1}\") for the follower option {2}"
|
||||
#: tiramisu/config.py:1144
|
||||
msgid "parent of {0} not already exists"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:331
|
||||
#: tiramisu/config.py:1191
|
||||
msgid "cannot set leadership object has root optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1194
|
||||
msgid "cannot set dynoptiondescription object has root optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1246
|
||||
msgid "config name must be uniq in groupconfig for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1457
|
||||
msgid "unknown config \"{}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1482
|
||||
msgid "child must be a Config, MixConfig or MetaConfig"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1517
|
||||
msgid "force_default, force_default_if_same or force_dont_change_value cannot be set with only_config"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1527
|
||||
msgid "force_default and force_dont_change_value cannot be set together"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1676
|
||||
msgid "config name must be uniq in groupconfig for {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1721
|
||||
msgid "config added has no name, the name is mandatory"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1726
|
||||
msgid "config name \"{0}\" is not uniq in groupconfig \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1744 tiramisu/config.py:1750
|
||||
msgid "cannot find the config {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1776
|
||||
msgid "MetaConfig with optiondescription must have string has child, not {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1788
|
||||
msgid "child must be a Config or MetaConfig"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1793
|
||||
msgid "all config in metaconfig must have the same optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/config.py:1810
|
||||
msgid "metaconfig must have the same optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:31
|
||||
msgid "and"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:33
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:55
|
||||
msgid " {} "
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:108
|
||||
msgid "property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:110
|
||||
msgid "properties"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:113
|
||||
msgid "cannot modify the {0} {1} because \"{2}\" has {3} {4}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:115
|
||||
msgid "cannot modify the {0} {1} because has {2} {3}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:118
|
||||
msgid "cannot access to {0} {1} because \"{2}\" has {3} {4}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:120
|
||||
msgid "cannot access to {0} {1} because has {2} {3}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:192
|
||||
msgid "invalid value"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:341
|
||||
msgid "attention, \"{0}\" could be an invalid {1} for {2}"
|
||||
#: tiramisu/error.py:201
|
||||
msgid "attention, \"{0}\" could be an invalid {1} for \"{2}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:345
|
||||
msgid "attention, \"{0}\" could be an invalid {1} for {2} at index \"{3}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:366 tiramisu/error.py:377
|
||||
msgid "\"{0}\" is an invalid {1} for {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/error.py:368
|
||||
msgid "\"{0}\" is an invalid {1} for {2} at index \"{3}\""
|
||||
#: tiramisu/error.py:219 tiramisu/error.py:228
|
||||
msgid "\"{0}\" is an invalid {1} for \"{2}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/function.py:65
|
||||
|
|
@ -475,23 +383,23 @@ msgstr ""
|
|||
msgid "invalid properties type {0} for {1}, must be a frozenset"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/baseoption.py:100
|
||||
#: tiramisu/option/baseoption.py:98
|
||||
msgid "invalid property type {0} for {1}, must be a string or a Calculation"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/baseoption.py:251
|
||||
#: tiramisu/option/baseoption.py:249
|
||||
msgid "information's item for {0} not found: \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/baseoption.py:269
|
||||
#: tiramisu/option/baseoption.py:267
|
||||
msgid "'{0}' ({1}) object attribute '{2}' is read-only"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/baseoption.py:310
|
||||
#: tiramisu/option/baseoption.py:308
|
||||
msgid "\"{}\" ({}) object attribute \"{}\" is read-only"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/baseoption.py:322
|
||||
#: tiramisu/option/baseoption.py:320
|
||||
msgid "{0} not part of any Config"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -515,80 +423,64 @@ msgstr ""
|
|||
msgid "only {0} are allowed"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:67
|
||||
#: tiramisu/option/domainnameoption.py:60
|
||||
msgid "unknown type {0} for hostname"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:70
|
||||
#: tiramisu/option/domainnameoption.py:63
|
||||
msgid "allow_ip must be a boolean"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:72
|
||||
#: tiramisu/option/domainnameoption.py:65
|
||||
msgid "allow_cidr_network must be a boolean"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:74
|
||||
#: tiramisu/option/domainnameoption.py:67
|
||||
msgid "allow_without_dot must be a boolean"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:76
|
||||
#: tiramisu/option/domainnameoption.py:69
|
||||
msgid "allow_startswith_dot must be a boolean"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:87
|
||||
#: tiramisu/option/domainnameoption.py:81
|
||||
msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are allowed"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:90
|
||||
#: tiramisu/option/domainnameoption.py:84
|
||||
msgid "must start with lowercase characters followed by lowercase characters, number, \"-\" and \".\" characters are recommanded"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:95
|
||||
msgid "must start with lowercase characters followed by lowercase characters, number and \"-\" characters are allowed"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:98
|
||||
msgid "must start with lowercase characters followed by lowercase characters, number and \"-\" characters are recommanded"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:102
|
||||
#: tiramisu/option/domainnameoption.py:103
|
||||
#: tiramisu/option/domainnameoption.py:88
|
||||
#: tiramisu/option/domainnameoption.py:89
|
||||
msgid "could be a IP, otherwise {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:148
|
||||
#: tiramisu/option/domainnameoption.py:134
|
||||
msgid "invalid length (min 1)"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:151
|
||||
#: tiramisu/option/domainnameoption.py:137
|
||||
msgid "invalid length (max {0})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:157
|
||||
#: tiramisu/option/domainnameoption.py:143
|
||||
msgid "must have dot"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:159
|
||||
#: tiramisu/option/domainnameoption.py:145
|
||||
msgid "invalid length (max 255)"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:179
|
||||
msgid "DNS resolution failed"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:182
|
||||
msgid "error resolving DNS: {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:189
|
||||
#: tiramisu/option/domainnameoption.py:163
|
||||
msgid "must not be an IP"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/domainnameoption.py:212
|
||||
#: tiramisu/option/domainnameoption.py:186
|
||||
msgid "some characters are uppercase"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/dynoptiondescription.py:130
|
||||
#: tiramisu/option/dynoptiondescription.py:131
|
||||
msgid "DynOptionDescription identifiers for option {0}, is not a list ({1})"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -609,19 +501,7 @@ msgid "must starts with \"/\""
|
|||
msgstr ""
|
||||
|
||||
#: tiramisu/option/filenameoption.py:78
|
||||
msgid "directory"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/filenameoption.py:78
|
||||
msgid "file"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/filenameoption.py:82
|
||||
msgid "cannot find this {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/intoption.py:46
|
||||
msgid "which is not an integer"
|
||||
msgid "cannot find {0} \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/intoption.py:52
|
||||
|
|
@ -668,23 +548,31 @@ msgstr ""
|
|||
msgid "must be private IP"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:65
|
||||
#: tiramisu/option/leadership.py:55
|
||||
msgid "cannot set \"group_type\" attribute for a Leadership"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:67
|
||||
msgid "a leader and a follower are mandatories in leadership \"{}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:97
|
||||
#: tiramisu/option/leadership.py:89
|
||||
msgid "leader cannot have \"{}\" property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:101
|
||||
msgid "leadership {0} shall not have a symlinkoption"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:104
|
||||
#: tiramisu/option/leadership.py:108
|
||||
msgid "leadership {0} shall not have a subgroup"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:110
|
||||
msgid "only multi option are allowed in leadership {0} but option {1} is not a multi"
|
||||
#: tiramisu/option/leadership.py:114
|
||||
msgid "only multi option allowed in leadership {0} but option {1} is not a multi"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/leadership.py:137
|
||||
#: tiramisu/option/leadership.py:141
|
||||
msgid "not allowed default value for follower option {0} in leadership {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -716,31 +604,31 @@ msgstr ""
|
|||
msgid "validators must be a Calculation for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:141
|
||||
#: tiramisu/option/option.py:146
|
||||
msgid "invalid default_multi value \"{0}\" for option {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:149
|
||||
#: tiramisu/option/option.py:154
|
||||
msgid "invalid default_multi value \"{0}\" for option {1}, {2}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:162
|
||||
#: tiramisu/option/option.py:167
|
||||
msgid "invalid default_multi value \"{0}\" for option {1}, must be a list for a submulti"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:294
|
||||
#: tiramisu/option/option.py:290
|
||||
msgid "the value \"{}\" is not unique"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:356
|
||||
#: tiramisu/option/option.py:352
|
||||
msgid "which must not be a list"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:408 tiramisu/option/option.py:434
|
||||
#: tiramisu/option/option.py:404 tiramisu/option/option.py:430
|
||||
msgid "which must be a list"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/option.py:428
|
||||
#: tiramisu/option/option.py:424
|
||||
msgid "which \"{}\" must be a list of list"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -748,23 +636,35 @@ msgstr ""
|
|||
msgid "duplicate option: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:336
|
||||
#: tiramisu/option/optiondescription.py:244
|
||||
msgid "unknown option \"{0}\" in root optiondescription (it's a dynamic option)"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:279
|
||||
msgid "unknown option \"{0}\" in root optiondescription"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:282
|
||||
msgid "unknown option \"{0}\" in optiondescription {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:338
|
||||
msgid "children in optiondescription \"{}\" must be a list"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:364
|
||||
#: tiramisu/option/optiondescription.py:366
|
||||
msgid "duplicate option name: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:370
|
||||
#: tiramisu/option/optiondescription.py:372
|
||||
msgid "the option's name \"{0}\" start as the dynoptiondescription's name \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:413
|
||||
#: tiramisu/option/optiondescription.py:415
|
||||
msgid "cannot change group_type if already set (old {0}, new {1})"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/optiondescription.py:418
|
||||
#: tiramisu/option/optiondescription.py:420
|
||||
msgid "group_type: {0} not allowed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -805,79 +705,79 @@ msgstr ""
|
|||
msgid "too weak"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:80
|
||||
#: tiramisu/option/portoption.py:74
|
||||
msgid "inconsistency in allowed range"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:85
|
||||
#: tiramisu/option/portoption.py:79
|
||||
msgid "max value is empty"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:98
|
||||
#: tiramisu/option/portoption.py:92
|
||||
msgid "range must have two values only"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:101
|
||||
#: tiramisu/option/portoption.py:95
|
||||
msgid "first port in range must be smaller than the second one"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:127
|
||||
#: tiramisu/option/portoption.py:121
|
||||
msgid "should be between {0} and {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/portoption.py:129
|
||||
#: tiramisu/option/portoption.py:123
|
||||
msgid "must be between {0} and {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/stroption.py:41
|
||||
msgid "which is not a string"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/symlinkoption.py:51
|
||||
msgid "malformed symlink second parameters must be an option for \"{0}\", not {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/urloption.py:92
|
||||
#: tiramisu/option/urloption.py:91
|
||||
msgid "must start with http:// or https://"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/urloption.py:117
|
||||
msgid "the port \"{0}\" is invalid: {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/urloption.py:124
|
||||
msgid "the domain \"{0}\" is invalid: {1}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/option/urloption.py:128
|
||||
#: tiramisu/option/urloption.py:119
|
||||
msgid "must ends with a valid resource name"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:258
|
||||
#: tiramisu/setting.py:255
|
||||
msgid "can't rebind {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:265
|
||||
#: tiramisu/setting.py:262
|
||||
msgid "can't unbind {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:467
|
||||
#: tiramisu/setting.py:464
|
||||
msgid "invalid property type {type(new_prop)} for {subconfig.option.impl_getname()} with {prop.function.__name__} function"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:606
|
||||
#: tiramisu/setting.py:476
|
||||
msgid "leader cannot have \"{new_prop}\" property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:564
|
||||
msgid "leader cannot have \"{0}\" property"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:573
|
||||
msgid "a leader ({0}) cannot have \"force_default_on_freeze\" or \"force_metaconfig_on_freeze\" property without \"frozen\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:607
|
||||
msgid "permissive must be a frozenset"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:616
|
||||
#: tiramisu/setting.py:617
|
||||
msgid "cannot add those permissives: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:653
|
||||
#: tiramisu/setting.py:654
|
||||
msgid "can't reset properties to the symlinkoption \"{}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/setting.py:666
|
||||
#: tiramisu/setting.py:667
|
||||
msgid "can't reset permissives to the symlinkoption \"{}\""
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -905,19 +805,19 @@ msgstr ""
|
|||
msgid "unknown action {}"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/value.py:570 tiramisu/value.py:872
|
||||
#: tiramisu/value.py:564 tiramisu/value.py:861
|
||||
msgid "set owner \"{0}\" is forbidden"
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/value.py:577
|
||||
#: tiramisu/value.py:571
|
||||
msgid "\"{0}\" is a default value, so we cannot change owner to \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: tiramisu/value.py:751
|
||||
#: tiramisu/value.py:740
|
||||
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
|
||||
#: tiramisu/value.py:847
|
||||
msgid "information's item not found \"{}\""
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
|
|||
|
||||
[project]
|
||||
name = "tiramisu"
|
||||
version = "5.2.0a9"
|
||||
version = "5.1.0"
|
||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||
readme = "README.md"
|
||||
description = "an options controller tool"
|
||||
|
|
@ -18,8 +18,6 @@ classifiers = [
|
|||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
"Natural Language :: English",
|
||||
|
|
@ -35,9 +33,5 @@ name = "cz_conventional_commits"
|
|||
tag_format = "$version"
|
||||
version_scheme = "pep440"
|
||||
version_provider = "pep621"
|
||||
version_files = [
|
||||
"tiramisu/__version__.py",
|
||||
"pyproject.toml:version"
|
||||
]
|
||||
#update_changelog_on_bump = true
|
||||
changelog_merge_prerelease = true
|
||||
|
|
|
|||
|
|
@ -69,11 +69,11 @@ def test_cache_importation_property():
|
|||
cfg = Config(od1)
|
||||
cfg.option('u2').property.add('prop')
|
||||
export = cfg.property.exportation()
|
||||
assert cfg.option('u2').property.get() == {'validator', 'prop'}
|
||||
assert cfg.option('u2').property.get() == {'prop'}
|
||||
cfg.option('u2').property.add('prop2')
|
||||
assert cfg.option('u2').property.get() == {'validator', 'prop', 'prop2'}
|
||||
assert cfg.option('u2').property.get() == {'prop', 'prop2'}
|
||||
cfg.property.importation(export)
|
||||
assert cfg.option('u2').property.get() == {'validator', 'prop'}
|
||||
assert cfg.option('u2').property.get() == {'prop'}
|
||||
cfg = Config(od1)
|
||||
# assert not list_sessions()
|
||||
|
||||
|
|
@ -366,8 +366,8 @@ def test_cache_leader_and_followers():
|
|||
cfg.value.get()
|
||||
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
|
||||
val1_props = []
|
||||
val1_val1_props = ['empty', 'unique', 'validator']
|
||||
val1_val2_props = ['validator']
|
||||
val1_val1_props = ['empty', 'unique']
|
||||
val1_val2_props = []
|
||||
global_props = frozenset(global_props)
|
||||
val1_props = frozenset(val1_props)
|
||||
val1_val1_props = frozenset(val1_val1_props)
|
||||
|
|
@ -384,7 +384,7 @@ def test_cache_leader_and_followers():
|
|||
#
|
||||
cfg.option('val1.val1').value.set([None])
|
||||
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'validator', 'empty', 'unique'}, None, True)}})
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'empty', 'unique'}, None, True)}})
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||
cfg.value.get()
|
||||
#has value
|
||||
|
|
@ -416,8 +416,8 @@ def test_cache_leader_callback():
|
|||
cfg.value.get()
|
||||
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
|
||||
val1_props = []
|
||||
val1_val1_props = ['empty', 'unique', 'validator']
|
||||
val1_val2_props = ['validator']
|
||||
val1_val1_props = ['empty', 'unique']
|
||||
val1_val2_props = []
|
||||
global_props = frozenset(global_props)
|
||||
val1_props = frozenset(val1_props)
|
||||
val1_val1_props = frozenset(val1_val1_props)
|
||||
|
|
@ -429,7 +429,7 @@ def test_cache_leader_callback():
|
|||
})
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
||||
cfg.option('val1.val1').value.set([None])
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty', 'validator'}, None, True)}})
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty'}, None, True)}})
|
||||
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||
cfg.value.get()
|
||||
|
|
@ -451,24 +451,24 @@ def test_cache_requires():
|
|||
settings = cfg._config_bag.context.properties_cache
|
||||
assert values.get_cached() == {}
|
||||
assert cfg.option('ip_address_service').value.get() == None
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({'validator'}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
cfg.option('ip_address_service').value.set('1.1.1.1')
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
|
|
@ -477,8 +477,8 @@ def test_cache_requires():
|
|||
|
||||
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({'disabled', "validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set(['disabled']), None)}})
|
||||
|
||||
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
||||
# assert not list_sessions()
|
||||
|
|
@ -499,19 +499,19 @@ def test_cache_global_properties():
|
|||
settings = cfg._config_bag.context.properties_cache
|
||||
assert values.get_cached() == {}
|
||||
assert cfg.option('ip_address_service').value.get() == None
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
cfg.property.remove('disabled')
|
||||
assert cfg.option('ip_address_service').value.get() == None
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
cfg.property.add('test')
|
||||
assert cfg.option('ip_address_service').value.get() == None
|
||||
compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
|
||||
'ip_address_service': {None: ({"validator"}, None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -380,12 +380,12 @@ def test_prefix_error():
|
|||
try:
|
||||
cfg.option('test1').value.set('yes')
|
||||
except Exception as err:
|
||||
assert str(err) == _('"{0}" is an invalid {1} for "{2}", which is not an integer').format('yes', _('integer'), 'test1')
|
||||
assert str(err) == _('"{0}" is an invalid {1} for "{2}"').format('yes', _('integer'), 'test1')
|
||||
try:
|
||||
cfg.option('test1').value.set('yes')
|
||||
except Exception as err:
|
||||
err.prefix = ''
|
||||
assert str(err) == _('which is not an integer')
|
||||
assert str(err) == _('invalid value')
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ def test_config_reset():
|
|||
cfg.owner.set('test')
|
||||
assert cfg.owner.get() == 'test'
|
||||
assert not cfg.option('gc.gc2.bool').value.get()
|
||||
assert cfg.option('boolop').property.get() == frozenset(["validator"])
|
||||
assert not cfg.option('boolop').property.get()
|
||||
assert not cfg.option('boolop').permissive.get()
|
||||
assert not cfg.option('wantref').information.get('info', None)
|
||||
#
|
||||
|
|
@ -440,7 +440,7 @@ def test_config_reset():
|
|||
cfg.config.reset()
|
||||
assert cfg.owner.get() == 'test'
|
||||
assert not cfg.option('gc.gc2.bool').value.get()
|
||||
assert cfg.option('boolop').property.get() == {"validator"}
|
||||
assert not cfg.option('boolop').property.get()
|
||||
assert not cfg.option('float').permissive.get()
|
||||
assert not cfg.option('wantref').information.get('info', None)
|
||||
# assert not list_sessions()
|
||||
|
|
|
|||
|
|
@ -275,9 +275,3 @@ def test_url(config_type):
|
|||
with pytest.raises(ValueError):
|
||||
cfg.option('u').value.set('https://FOO.COM:8443')
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_domainname_existence():
|
||||
DomainnameOption('d', '', 'google.fr', test_existence=True)
|
||||
with pytest.raises(ValueError):
|
||||
DomainnameOption('d', '', 'ljijouuuehyfr.com', test_existence=True)
|
||||
|
|
|
|||
|
|
@ -300,20 +300,20 @@ def test_prop_dyndescription():
|
|||
od = OptionDescription('od', '', [dod])
|
||||
od2 = OptionDescription('od', '', [od])
|
||||
cfg = Config(od2)
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == {'test', "validator"}
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == {'test', "validator"}
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test'])
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test'])
|
||||
cfg.option('od.dodval2.st').property.add('test2')
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == {'test', "validator"}
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == {'test', 'test2', "validator"}
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test'])
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2'])
|
||||
#
|
||||
assert set(cfg.option('od.dodval1').property.get()) == set()
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set()
|
||||
assert set(cfg.option('od.dodval1').property.get()) == set([])
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set([])
|
||||
cfg.option('od.dodval1').property.add('test1')
|
||||
assert set(cfg.option('od.dodval1').property.get()) == {'test1'}
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set()
|
||||
assert set(cfg.option('od.dodval1').property.get()) == set(['test1'])
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set([])
|
||||
cfg.option('od.dodval1').property.remove('test1')
|
||||
assert set(cfg.option('od.dodval1').property.get()) == set()
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set()
|
||||
assert set(cfg.option('od.dodval1').property.get()) == set([])
|
||||
assert set(cfg.option('od.dodval2').property.get()) == set([])
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
@ -432,20 +432,6 @@ def test_callback_dyndescription_outside3():
|
|||
assert parse_od_get(cfg.value.get()) == {'od.out': 'val1', 'lst': ['val1', 'val2']}
|
||||
|
||||
|
||||
def test_callback_dyndescription_outside_optional():
|
||||
lst = StrOption('lst', '', ['val'], multi=True)
|
||||
st = StrOption('st', '', 'val')
|
||||
dod = DynOptionDescription('dod', '', [st], identifiers=Calculation(return_list, Params(ParamOption(lst))))
|
||||
out = StrOption('out', '', Calculation(calc_value, Params(ParamDynOption(st, ['unknown_val'], optional=True))))
|
||||
od = OptionDescription('od', '', [dod, out])
|
||||
od2 = OptionDescription('od', '', [od, lst])
|
||||
cfg = Config(od2)
|
||||
assert parse_od_get(cfg.value.get()) == {'od.dodval.st': 'val', 'od.out': None, 'lst': ['val']}
|
||||
cfg.option('lst').value.set(['val', 'unknown_val'])
|
||||
assert parse_od_get(cfg.value.get()) == {'od.dodval.st': 'val', 'od.dodunknown_val.st': 'val', 'od.out': 'val', 'lst': ['val', 'unknown_val']}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_callback_dyndescription_subdyn():
|
||||
lst = StrOption('lst', '', ['val1', 'val2'], multi=True)
|
||||
st = StrOption('st', '', 'val1')
|
||||
|
|
@ -616,14 +602,14 @@ def test_prop_dyndescription_context():
|
|||
od = OptionDescription('od', '', [dod, val1])
|
||||
od2 = OptionDescription('od', '', [od])
|
||||
cfg = Config(od2)
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == {"validator", 'test'}
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test'}
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test'])
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test'])
|
||||
cfg.option('od.dodval2.st').property.add('test2')
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == {"validator", 'test'}
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test', 'test2'}
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test'])
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2'])
|
||||
cfg.option('od.dodval1.st').permissive.add('test')
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == {"validator"}
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test', 'test2'}
|
||||
assert set(cfg.option('od.dodval1.st').property.get()) == set([])
|
||||
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2'])
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pytest
|
|||
|
||||
from tiramisu.setting import groups, owners
|
||||
from tiramisu import ChoiceOption, BoolOption, IntOption, IPOption, NetworkOption, NetmaskOption, \
|
||||
StrOption, OptionDescription, Leadership, Config, Calculation, ParamValue, ParamOption, calc_value, Params, submulti
|
||||
StrOption, OptionDescription, Leadership, Config, Calculation, ParamValue, calc_value, Params
|
||||
from tiramisu.error import LeadershipError, PropertiesOptionError, ConfigError
|
||||
|
||||
|
||||
|
|
@ -788,19 +788,6 @@ def test_values_with_leader_and_followers_leader_pop():
|
|||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_values_with_leader_and_followers_leader_pop_default_value():
|
||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", default=["192.168.230.145", "192.168.230.146"], multi=True, properties=('notunique',))
|
||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", default_multi="255.255.255.0", multi=True)
|
||||
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
od1 = OptionDescription('toto', '', [interface1])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.pop(0)
|
||||
compare(cfg.value.exportation(), {'ip_admin_eth0.ip_admin_eth0': {None: [['192.168.230.146'], 'user']}})
|
||||
assert cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() == ["192.168.230.146"]
|
||||
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == '255.255.255.0'
|
||||
|
||||
|
||||
def test_follower_unique():
|
||||
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=('unique',))
|
||||
|
|
@ -809,7 +796,7 @@ def test_follower_unique():
|
|||
cfg = Config(od1)
|
||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.146"])
|
||||
# unique property is removed for a follower
|
||||
assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).property.get() == {"validator"}
|
||||
assert not cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).property.get()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
@ -1106,25 +1093,3 @@ def test_leader_forbidden_properties_callback(config_type):
|
|||
cfg = Config(od1)
|
||||
with pytest.raises(LeadershipError):
|
||||
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
|
||||
|
||||
|
||||
def test_follower_value_not_list():
|
||||
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
||||
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
||||
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
od1 = OptionDescription('od', '', [interface0])
|
||||
od2 = OptionDescription('root', '', [od1])
|
||||
cfg = Config(od2)
|
||||
cfg.property.read_write()
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('od.interface0.ip_admin_eth0').value.set(None)
|
||||
|
||||
|
||||
def test_default_calc():
|
||||
var1 = StrOption('var1', "", multi=True, default=['leader1', 'leader2'], properties=frozenset({"mandatory",}))
|
||||
var2 = StrOption('var2', "", default_multi=[Calculation(calc_value, Params((ParamOption(var1))))], multi=submulti, properties=frozenset({"mandatory",}))
|
||||
leader = Leadership('interface0', '', [var1, var2])
|
||||
od1 = OptionDescription('od', '', [leader])
|
||||
od2 = OptionDescription('root', '', [od1])
|
||||
cfg = Config(od2)
|
||||
assert parse_od_get(cfg.value.get()) == {'od.interface0.var1': [{'od.interface0.var1': 'leader1', 'od.interface0.var2': ['leader1']}, {'od.interface0.var1': 'leader2', 'od.interface0.var2': ['leader2']}]}
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ def test_consistency_leader_and_followers_leader_mandatory_transitive():
|
|||
try:
|
||||
cfg.option('val1.val2', 0).value.get()
|
||||
except PropertiesOptionError as error:
|
||||
assert str(error) == str(_('cannot access to {0} {1} at index "{2}" because has {3} {4}').format('option', '"val2"', 0, _('property'), '"disabled"'))
|
||||
assert str(error) == str(_('cannot access to {0} {1} because has {2} {3}').format('option', '"val2"', _('property'), '"disabled"'))
|
||||
else:
|
||||
raise Exception('must raises')
|
||||
assert list(cfg.value.mandatory()) == []
|
||||
|
|
|
|||
|
|
@ -202,10 +202,10 @@ def test_property_get_unique_empty():
|
|||
od1 = OptionDescription("options", "", [s, s2, s3, s4])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
assert cfg.option('string').property.get() == {"validator", 'empty', 'unique'}
|
||||
assert cfg.option('string2').property.get() == {"validator", 'empty', 'notunique'}
|
||||
assert cfg.option('string3').property.get() == {"validator", 'unique', 'notempty'}
|
||||
assert cfg.option('string4').property.get() == {"validator", 'notunique', 'notempty'}
|
||||
assert cfg.option('string').property.get() == {'empty', 'unique'}
|
||||
assert cfg.option('string2').property.get() == {'empty', 'notunique'}
|
||||
assert cfg.option('string3').property.get() == {'unique', 'notempty'}
|
||||
assert cfg.option('string4').property.get() == {'notunique', 'notempty'}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ def test_property_only_raises():
|
|||
od1 = OptionDescription("options", "", [s, intoption, stroption])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
assert cfg.option('str').property.get() == {'empty', 'unique', 'validator'}
|
||||
assert cfg.option('str').property.get() == {'empty', 'unique'}
|
||||
assert cfg.option('str').property.get(only_raises=True) == set()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
|
@ -569,23 +569,23 @@ def test_access_by_get_whith_hide():
|
|||
def test_append_properties():
|
||||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
assert cfg.option('gc.dummy').property.get() == {"validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == set()
|
||||
cfg.option('gc.dummy').property.add('test')
|
||||
assert cfg.option('gc.dummy').property.get() == {'test', "validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == {'test'}
|
||||
with pytest.raises(ConfigError):
|
||||
cfg.option('gc.dummy').property.add('force_store_value')
|
||||
assert cfg.option('gc.dummy').property.get() == {'test', "validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == {'test'}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_reset_properties():
|
||||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
assert cfg.option('gc.dummy').property.get() == {"validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == set()
|
||||
cfg.option('gc.dummy').property.add('frozen')
|
||||
assert cfg.option('gc.dummy').property.get() == {"validator", 'frozen'}
|
||||
assert cfg.option('gc.dummy').property.get() == {'frozen'}
|
||||
cfg.option('gc.dummy').property.reset()
|
||||
assert cfg.option('gc.dummy').property.get() == {"validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == set()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
@ -594,7 +594,7 @@ def test_properties_cached():
|
|||
od1 = OptionDescription("opt", "", [OptionDescription("sub", "", [b1])])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
assert cfg.option('sub.b1').property.get() == {'test', "validator"}
|
||||
assert cfg.option('sub.b1').property.get() == {'test'}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
@ -603,9 +603,9 @@ def test_append_properties_force_store_value():
|
|||
gcgroup = OptionDescription('gc', '', [gcdummy])
|
||||
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
||||
cfg = Config(od1)
|
||||
assert cfg.option('gc.dummy').property.get() == {'force_store_value', "validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == {'force_store_value'}
|
||||
cfg.option('gc.dummy').property.add('test')
|
||||
assert cfg.option('gc.dummy').property.get() == {'force_store_value', 'test', "validator"}
|
||||
assert cfg.option('gc.dummy').property.get() == {'force_store_value', 'test'}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,34 +121,6 @@ def test_validator(config_type):
|
|||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_validator_no_validation(config_type):
|
||||
opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption()))], default='val', properties=frozenset(['novalidator']))
|
||||
opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()))], properties=frozenset(['novalidator']))
|
||||
od1 = OptionDescription('root', '', [opt1, opt2])
|
||||
cfg_ori = Config(od1)
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
assert cfg.option('opt1').value.get() == 'val'
|
||||
assert cfg.option('opt2').value.valid() is True
|
||||
cfg.option('opt2').value.set('val')
|
||||
|
||||
|
||||
def test_validator_no_validation2(config_type):
|
||||
opt1 = StrOption('opt1', '', properties=frozenset(['novalidator']))
|
||||
od1 = OptionDescription('root', '', [opt1])
|
||||
cfg_ori = Config(od1)
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
cfg.option('opt1').value.set(1)
|
||||
assert cfg.option('opt1').value.get() == 1
|
||||
|
||||
|
||||
def test_validator_no_validation3(config_type):
|
||||
opt1 = StrOption('opt1', '', 1, properties=frozenset(['novalidator']))
|
||||
od1 = OptionDescription('root', '', [opt1])
|
||||
cfg_ori = Config(od1)
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
assert cfg.option('opt1').value.get() == 1
|
||||
|
||||
|
||||
def test_validator_not_valid(config_type):
|
||||
with pytest.raises(ValueError):
|
||||
StrOption('not_a_list', '', validators=Calculation(return_true, Params(ParamSelfOption())), default='val')
|
||||
|
|
|
|||
|
|
@ -426,9 +426,9 @@ def test_requires_transitive_unrestraint(config_type):
|
|||
#
|
||||
if config_type == 'tiramisu-api':
|
||||
cfg.send()
|
||||
assert cfg_ori.option('activate_service_web').property.get() == {'disabled', "validator"}
|
||||
assert cfg_ori.option('activate_service_web').property.get() == {'disabled'}
|
||||
# FIXME assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'}
|
||||
assert cfg_ori.option('ip_address_service_web').property.get() == {'disabled', "validator"}
|
||||
assert cfg_ori.option('ip_address_service_web').property.get() == {'disabled'}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ def test_symlink_option(config_type):
|
|||
assert cfg.option('c').issymlinkoption()
|
||||
assert cfg.option('s1.b').type() == 'boolean'
|
||||
assert cfg.option('c').type() == 'boolean'
|
||||
assert cfg.option('s1.b').type(only_self=True) == 'boolean'
|
||||
assert cfg.option('c').type(only_self=True) == 'symlink'
|
||||
assert cfg.option('s1.b').value.get() is False
|
||||
cfg.option("s1.b").value.set(True)
|
||||
cfg.option("s1.b").value.set(False)
|
||||
|
|
@ -159,7 +157,7 @@ def test_symlink_getproperties():
|
|||
od1 = OptionDescription('opt', '', [boolopt, linkopt])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test', "validator"}
|
||||
assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test'}
|
||||
# assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False
|
||||
# assert not list_sessions()
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ from .error import ConfigError
|
|||
from .api import Config, MetaConfig, GroupConfig, MixConfig
|
||||
from .option import __all__ as all_options
|
||||
from .setting import owners, groups, undefined
|
||||
from .__version__ import __version__
|
||||
|
||||
|
||||
allfuncs = [
|
||||
|
|
@ -77,3 +76,4 @@ allfuncs.extend(all_options)
|
|||
del all_options
|
||||
__all__ = tuple(allfuncs)
|
||||
del allfuncs
|
||||
__version__ = "4.1.0"
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
__version__ = "5.2.0a9"
|
||||
|
|
@ -139,8 +139,6 @@ def option_type(typ):
|
|||
@wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
self = args[0]
|
||||
if isinstance(typ, list) and "allow_dynoption" in typ:
|
||||
self._allow_dynoption = True
|
||||
config_bag = self._config_bag
|
||||
if self._config_bag.context.impl_type == "group" and "group" in types:
|
||||
options_bag = [
|
||||
|
|
@ -274,15 +272,7 @@ class _TiramisuOptionOptionDescription:
|
|||
|
||||
_validate_properties = False
|
||||
|
||||
@option_type(
|
||||
[
|
||||
"optiondescription",
|
||||
"option",
|
||||
"with_or_without_index",
|
||||
"symlink",
|
||||
"allow_dynoption",
|
||||
]
|
||||
)
|
||||
@option_type(["optiondescription", "option", "with_or_without_index", "symlink"])
|
||||
def get(self):
|
||||
"""Get Tiramisu option"""
|
||||
return self._subconfig.option
|
||||
|
|
@ -300,14 +290,11 @@ class _TiramisuOptionOptionDescription:
|
|||
@option_type(["optiondescription", "option", "with_or_without_index", "symlink"])
|
||||
def description(
|
||||
self,
|
||||
with_quote: bool = False,
|
||||
uncalculated: bool = False,
|
||||
):
|
||||
"""Get option description"""
|
||||
if not uncalculated:
|
||||
return self._subconfig.option.impl_get_display_name(
|
||||
self._subconfig, with_quote=with_quote
|
||||
)
|
||||
return self._subconfig.option.impl_get_display_name(self._subconfig)
|
||||
return self._subconfig.option._get_information(
|
||||
self._subconfig,
|
||||
"doc",
|
||||
|
|
@ -360,13 +347,11 @@ class _TiramisuOptionOptionDescription:
|
|||
return options
|
||||
|
||||
@option_type(["option", "optiondescription", "symlink", "with_or_without_index"])
|
||||
def type(self, only_self=False):
|
||||
def type(self):
|
||||
"""Get de option type"""
|
||||
option = self._subconfig.option
|
||||
if option.impl_is_optiondescription():
|
||||
return "optiondescription"
|
||||
if only_self and option.impl_is_symlinkoption():
|
||||
return "symlink"
|
||||
return option.get_type()
|
||||
|
||||
@option_type(["option", "symlink", "with_or_without_index"])
|
||||
|
|
@ -816,11 +801,14 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
option = self._subconfig.option
|
||||
if (
|
||||
not isinstance(value, Calculation)
|
||||
and isinstance(value, list)
|
||||
and option.impl_is_leader()
|
||||
and len(value) < self._subconfig.parent.get_length_leadership()
|
||||
):
|
||||
raise LeadershipError(self._subconfig, "leadership-reduce")
|
||||
raise LeadershipError(
|
||||
_("cannot reduce length of the leader {}" "").format(
|
||||
option.impl_get_display_name(self._subconfig, with_quote=True)
|
||||
)
|
||||
)
|
||||
values = self._config_bag.context.get_values()
|
||||
return values.set_value(self._subconfig, value)
|
||||
|
||||
|
|
@ -918,39 +906,34 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
def mandatory(self):
|
||||
"""Return path of options with mandatory property without any value"""
|
||||
subconfig = self._subconfig
|
||||
ori_config_bag = self._subconfig.config_bag
|
||||
config_bag = ori_config_bag.copy()
|
||||
config_bag.properties -= {"mandatory", "empty", "warnings"}
|
||||
config_bag.set_permissive()
|
||||
self._subconfig.config_bag = config_bag
|
||||
try:
|
||||
if subconfig.option.impl_is_optiondescription():
|
||||
options = []
|
||||
for subconfig in config_bag.context.walk(
|
||||
self._subconfig,
|
||||
only_mandatory=True,
|
||||
):
|
||||
options.append(
|
||||
TiramisuOption(
|
||||
subconfig.path,
|
||||
subconfig.index,
|
||||
ori_config_bag,
|
||||
subconfig=subconfig,
|
||||
)
|
||||
if subconfig.option.impl_is_optiondescription():
|
||||
ori_config_bag = self._subconfig.config_bag
|
||||
config_bag = ori_config_bag.copy()
|
||||
config_bag.properties -= {"mandatory", "empty", "warnings"}
|
||||
config_bag.set_permissive()
|
||||
self._subconfig.config_bag = config_bag
|
||||
options = []
|
||||
for subconfig in self._config_bag.context.walk(
|
||||
self._subconfig,
|
||||
only_mandatory=True,
|
||||
):
|
||||
options.append(
|
||||
TiramisuOption(
|
||||
subconfig.path,
|
||||
subconfig.index,
|
||||
ori_config_bag,
|
||||
subconfig=subconfig,
|
||||
)
|
||||
self._subconfig.config_bag = ori_config_bag
|
||||
return options
|
||||
try:
|
||||
self._config_bag.context.walk_valid_value(
|
||||
self._subconfig, only_mandatory=True
|
||||
)
|
||||
except PropertiesOptionError as err:
|
||||
return err.proptype == ["mandatory"] or err.proptype == ["empty"]
|
||||
self._subconfig.config_bag = ori_config_bag
|
||||
return False
|
||||
except Exception as err:
|
||||
self._subconfig.config_bag = ori_config_bag
|
||||
raise err from err
|
||||
return options
|
||||
try:
|
||||
self._config_bag.context.walk_valid_value(
|
||||
self._subconfig, only_mandatory=True
|
||||
)
|
||||
except PropertiesOptionError as err:
|
||||
return err.proptype == ["mandatory"] or err.proptype == ["empty"]
|
||||
return False
|
||||
|
||||
|
||||
def _registers(
|
||||
|
|
@ -1544,7 +1527,7 @@ class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
|
|||
|
||||
def get(self):
|
||||
"""Get Tiramisu option"""
|
||||
return self._config_bag.context.get_description()
|
||||
return None
|
||||
|
||||
def isleadership(self):
|
||||
"""Test if option is a leader or a follower"""
|
||||
|
|
|
|||
|
|
@ -22,15 +22,7 @@ from typing import Any, Optional, Union, Callable, Dict, List
|
|||
from itertools import chain
|
||||
import weakref
|
||||
|
||||
from .error import (
|
||||
PropertiesOptionError,
|
||||
ConfigError,
|
||||
LeadershipError,
|
||||
ValueWarning,
|
||||
CancelParam,
|
||||
display_list,
|
||||
errors,
|
||||
)
|
||||
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning
|
||||
from .i18n import _
|
||||
from .setting import undefined, ConfigBag
|
||||
from .function import FUNCTION_WAITING_FOR_DICT, FUNCTION_WAITING_FOR_ERROR
|
||||
|
|
@ -57,7 +49,6 @@ def get_calculated_value(
|
|||
has_calculation = True
|
||||
elif isinstance(value, list):
|
||||
# if value is a list, do subcalculation
|
||||
value = value.copy()
|
||||
for idx, val in enumerate(value):
|
||||
value[idx], _has_calculation = get_calculated_value(
|
||||
subconfig,
|
||||
|
|
@ -157,15 +148,11 @@ class ParamDynOption(ParamOption):
|
|||
)
|
||||
if not isinstance(identifiers, list):
|
||||
raise Exception(
|
||||
_("identifiers in ParamDynOption must be a list, not {0}").format(
|
||||
identifiers
|
||||
)
|
||||
f"identifiers in ParamDynOption must be a list, not {identifiers}"
|
||||
)
|
||||
if not isinstance(optional, bool):
|
||||
raise Exception(
|
||||
_("optional in ParamDynOption must be a boolean, not {0}").format(
|
||||
optional
|
||||
)
|
||||
f"optional in ParamDynOption must be a boolean, not {optional}"
|
||||
)
|
||||
self.identifiers = identifiers
|
||||
self.optional = optional
|
||||
|
|
@ -216,11 +203,9 @@ class ParamInformation(Param):
|
|||
|
||||
def set_option(self, option: "Option" = None) -> None:
|
||||
if not hasattr(self, "self_option"):
|
||||
raise ConfigError(
|
||||
_("cannot add option in information after creating config")
|
||||
)
|
||||
raise ConfigError("cannot add option in information after creating config")
|
||||
if self.option:
|
||||
raise ConfigError(_("cannot redefine option in information"))
|
||||
raise ConfigError("cannot redefine option in information")
|
||||
if not option.impl_is_optiondescription():
|
||||
if option.impl_is_symlinkoption():
|
||||
raise ValueError(
|
||||
|
|
@ -460,7 +445,14 @@ def manager_callback(
|
|||
or param.raisepropertyerror
|
||||
):
|
||||
raise err from err
|
||||
raise ConfigError(err)
|
||||
display_name = subconfig.option.impl_get_display_name(
|
||||
subconfig, with_quote=True
|
||||
)
|
||||
raise ConfigError(
|
||||
_("unable to carry out a calculation for {}, {}").format(
|
||||
display_name, err
|
||||
)
|
||||
) from err
|
||||
except ValueError as err:
|
||||
display_name = subconfig.option.impl_get_display_name(
|
||||
subconfig, with_quote=True
|
||||
|
|
@ -472,15 +464,20 @@ def manager_callback(
|
|||
) from err
|
||||
except AttributeError as err:
|
||||
if isinstance(param, ParamDynOption) and param.optional:
|
||||
# cannot access, simulate a propertyerror
|
||||
# cannot acces, simulate a propertyerror
|
||||
raise PropertiesOptionError(
|
||||
subconfig,
|
||||
["configerror"],
|
||||
config_bag.context.get_settings(),
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig, _("unable to get value for calculating {0}, {1}"), err
|
||||
display_name = subconfig.option.impl_get_display_name(
|
||||
subconfig, with_quote=True
|
||||
)
|
||||
raise ConfigError(
|
||||
_("unable to get value for calculating {0}, {1}").format(
|
||||
display_name, err
|
||||
)
|
||||
) from err
|
||||
return value
|
||||
|
||||
def get_option_bag(
|
||||
|
|
@ -512,12 +509,12 @@ def manager_callback(
|
|||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||
raise err from err
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to carry out a calculation for {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
raise ConfigError(
|
||||
_("unable to carry out a calculation for {}, {}").format(
|
||||
display_name, err
|
||||
)
|
||||
) from err
|
||||
except ValueError as err:
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
raise ValueError(
|
||||
|
|
@ -527,18 +524,18 @@ def manager_callback(
|
|||
) from err
|
||||
except AttributeError as err:
|
||||
if isinstance(param, ParamDynOption) and param.optional:
|
||||
# cannot access, simulate a propertyerror
|
||||
# cannot acces, simulate a propertyerror
|
||||
raise PropertiesOptionError(
|
||||
param,
|
||||
["configerror"],
|
||||
config_bag.context.get_settings(),
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to get value for calculating {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
raise ConfigError(
|
||||
_("unable to get value for calculating {0}, {1}").format(
|
||||
display_name, err
|
||||
)
|
||||
) from err
|
||||
return subsubconfig
|
||||
|
||||
if isinstance(param, ParamValue):
|
||||
|
|
@ -555,15 +552,14 @@ def manager_callback(
|
|||
true_path=subconfig.path,
|
||||
)
|
||||
if isinstance(isubconfig, list):
|
||||
display_name = option.impl_get_display_name(
|
||||
subconfig, with_quote=True
|
||||
)
|
||||
search_name = search_option.impl_get_display_name(
|
||||
None, with_quote=True
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("cannot find information for {0}, {1} is a dynamic option"),
|
||||
None,
|
||||
option=option,
|
||||
extra_keys=[search_name],
|
||||
raise ConfigError(
|
||||
f"cannot find information for {display_name}, {search_name} is a dynamic option"
|
||||
)
|
||||
else:
|
||||
isubconfig = get_option_bag(
|
||||
|
|
@ -583,12 +579,12 @@ def manager_callback(
|
|||
param.default_value,
|
||||
)
|
||||
except ValueError as err:
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("unable to get value for calculating {0}, {1}"),
|
||||
err,
|
||||
option=option,
|
||||
)
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
raise ConfigError(
|
||||
_("unable to get value for calculating {0}, {1}").format(
|
||||
display_name, err
|
||||
)
|
||||
) from err
|
||||
|
||||
if isinstance(param, ParamIndex):
|
||||
return index
|
||||
|
|
@ -598,17 +594,14 @@ def manager_callback(
|
|||
not option.impl_is_optiondescription()
|
||||
or not option.impl_is_dynoptiondescription()
|
||||
):
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
display_name = subconfig.option.impl_get_display_name(
|
||||
subconfig, with_quote=True
|
||||
)
|
||||
raise ConfigError(
|
||||
_(
|
||||
"option {0} is not a dynoptiondescription or in a dynoptiondescription"
|
||||
),
|
||||
None,
|
||||
option=option,
|
||||
).format(display_name)
|
||||
)
|
||||
if subconfig.identifiers is None:
|
||||
# if uncalculated
|
||||
return
|
||||
return subconfig.identifiers[param.identifier_index]
|
||||
|
||||
if isinstance(param, ParamSelfOption):
|
||||
|
|
@ -680,37 +673,7 @@ def manager_callback(
|
|||
parent,
|
||||
)
|
||||
except AttributeError as err:
|
||||
if parent.path:
|
||||
child_path = parent.path + "." + name
|
||||
else:
|
||||
child_path = name
|
||||
if param.optional:
|
||||
raise CancelParam(
|
||||
callbk_option.impl_getpath(), child_path
|
||||
)
|
||||
|
||||
identifiers = doption.get_identifiers(parent)
|
||||
if not identifiers:
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_(
|
||||
'cannot calculate arguments for {0}, {1} with identifier "{2}", there is no identifiers'
|
||||
),
|
||||
err,
|
||||
extra_keys=[identifier],
|
||||
)
|
||||
else:
|
||||
identifiers_list = display_list(
|
||||
identifiers, add_quote=True
|
||||
)
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_(
|
||||
'cannot calculate arguments for {0}, {1} with identifier "{2}", list of valid identifiers: {3}'
|
||||
),
|
||||
err,
|
||||
extra_keys=[identifier, identifiers_list],
|
||||
)
|
||||
raise ConfigError(err) from err
|
||||
new_parents.append(
|
||||
parent.get_child(
|
||||
doption,
|
||||
|
|
@ -814,11 +777,8 @@ def carry_out_calculation(
|
|||
and option.impl_is_follower()
|
||||
and index is None
|
||||
):
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig,
|
||||
_("the follower {0} must have index in carry_out_calculation!"),
|
||||
None,
|
||||
option=option,
|
||||
raise ConfigError(
|
||||
f"the follower {option.impl_get_display_name(subconfig, with_quote=True)} must have index in carry_out_calculation!"
|
||||
)
|
||||
|
||||
def fake_items(iterator):
|
||||
|
|
@ -868,12 +828,6 @@ def carry_out_calculation(
|
|||
args.append(err)
|
||||
else:
|
||||
kwargs[key] = err
|
||||
except CancelParam as err:
|
||||
if callback.__name__ in FUNCTION_WAITING_FOR_ERROR:
|
||||
if key is None:
|
||||
args.append(err)
|
||||
else:
|
||||
kwargs[key] = err
|
||||
ret = calculate(
|
||||
subconfig,
|
||||
callback,
|
||||
|
|
@ -889,14 +843,33 @@ def carry_out_calculation(
|
|||
and option.impl_is_follower()
|
||||
and not option.impl_is_submulti()
|
||||
):
|
||||
raise LeadershipError(
|
||||
subconfig,
|
||||
"leadership-follower-callback-list",
|
||||
callback=callback.__name__,
|
||||
args=args,
|
||||
kwargs=kwargs,
|
||||
ret=ret,
|
||||
)
|
||||
if args or kwargs:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'the "{}" function with positional arguments "{}" '
|
||||
'and keyword arguments "{}" must not return '
|
||||
'a list ("{}") for the follower option {}'
|
||||
""
|
||||
).format(
|
||||
callback.__name__,
|
||||
args,
|
||||
kwargs,
|
||||
ret,
|
||||
option.impl_get_display_name(subconfig, with_quote=True),
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'the "{}" function must not return a list ("{}") '
|
||||
"for the follower option {}"
|
||||
""
|
||||
).format(
|
||||
callback.__name__,
|
||||
ret,
|
||||
option.impl_get_display_name(subconfig, with_quote=True),
|
||||
)
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
|
|
@ -920,7 +893,7 @@ def calculate(
|
|||
except (ValueError, ValueWarning) as err:
|
||||
if allow_value_error:
|
||||
if force_value_warning:
|
||||
raise ValueWarning(msg=str(err))
|
||||
raise ValueWarning(str(err))
|
||||
raise err from err
|
||||
error = err
|
||||
except ConfigError as err:
|
||||
|
|
@ -929,17 +902,19 @@ def calculate(
|
|||
error = err
|
||||
if args or kwargs:
|
||||
msg = _(
|
||||
'unexpected error "{1}" in function "{2}" with arguments "{3}" and "{4}" '
|
||||
"for option {0}"
|
||||
)
|
||||
extra_keys = [
|
||||
'unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
||||
"for option {2}"
|
||||
).format(
|
||||
str(error),
|
||||
callback.__name__,
|
||||
subconfig.option.impl_get_display_name(subconfig, with_quote=True),
|
||||
args,
|
||||
kwargs,
|
||||
]
|
||||
)
|
||||
else:
|
||||
msg = _('unexpected error "{1}" in function "{2}" for option {0}')
|
||||
extra_keys = [callback.__name__]
|
||||
errors.raise_carry_out_calculation_error(
|
||||
subconfig, msg, error, extra_keys=extra_keys
|
||||
)
|
||||
msg = _('unexpected error "{0}" in function "{1}" for option {2}' "").format(
|
||||
str(error),
|
||||
callback.__name__,
|
||||
subconfig.option.impl_get_display_name(subconfig, with_quote=True),
|
||||
)
|
||||
raise ConfigError(msg) from error
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def get_common_path(path1, path2):
|
|||
return common_path
|
||||
if common_path.endswith("."):
|
||||
return common_path[:-1]
|
||||
elif "." in common_path:
|
||||
if "." in common_path:
|
||||
return common_path.rsplit(".", 1)[0]
|
||||
return None
|
||||
|
||||
|
|
@ -227,8 +227,7 @@ class SubConfig:
|
|||
identifiers: Optional[list[str]],
|
||||
*,
|
||||
true_path: Optional[str] = None,
|
||||
# for python 3.9 properties: Union[list[str], undefined] = undefined,
|
||||
properties=undefined,
|
||||
properties: Union[list[str], undefined] = undefined,
|
||||
validate_properties: bool = True,
|
||||
) -> None:
|
||||
self.index = index
|
||||
|
|
@ -417,7 +416,13 @@ class SubConfig:
|
|||
length = self.get_length_leadership()
|
||||
if index >= length:
|
||||
raise LeadershipError(
|
||||
subsubconfig, "leadership-greater", index=index, length=length
|
||||
_(
|
||||
'index "{0}" is greater than the leadership length "{1}" for option {2}'
|
||||
).format(
|
||||
index,
|
||||
length,
|
||||
option.impl_get_display_name(subsubconfig, with_quote=True),
|
||||
)
|
||||
)
|
||||
return subsubconfig
|
||||
|
||||
|
|
@ -863,10 +868,9 @@ class _Config(CCache):
|
|||
subconfig, with_quote=True
|
||||
)
|
||||
raise LeadershipError(
|
||||
subconfig,
|
||||
"leadership-follower-greater",
|
||||
index=follower_len,
|
||||
length=length,
|
||||
_(
|
||||
"the follower option {0} has greater length ({1}) than the leader length ({2})"
|
||||
).format(option_name, follower_len, length)
|
||||
)
|
||||
self.get_settings().validate_mandatory(
|
||||
subconfig,
|
||||
|
|
|
|||
|
|
@ -18,23 +18,6 @@
|
|||
import weakref
|
||||
from .i18n import _
|
||||
|
||||
from typing import Literal, Union
|
||||
|
||||
|
||||
TiramisuErrorCode = Literal[
|
||||
"option-dynamic",
|
||||
"option-not-found",
|
||||
"property-frozen",
|
||||
"property-error",
|
||||
"property-mandatory",
|
||||
"leadership-group_type",
|
||||
"leadership-wrong_property",
|
||||
"leadership-force_default_on_freeze",
|
||||
"leadership-greater",
|
||||
"leadership-follower-greater",
|
||||
"leadership-follower-callback-list",
|
||||
]
|
||||
|
||||
|
||||
def display_list(
|
||||
lst,
|
||||
|
|
@ -86,8 +69,6 @@ class PropertiesOptionError(AttributeError):
|
|||
orig_opt=None,
|
||||
help_properties=None,
|
||||
):
|
||||
if orig_opt:
|
||||
raise Exception("a la")
|
||||
if opt_type:
|
||||
self._opt_type = opt_type
|
||||
self._name = name
|
||||
|
|
@ -106,23 +87,10 @@ class PropertiesOptionError(AttributeError):
|
|||
self.help_properties = help_properties
|
||||
self._settings = settings
|
||||
self.msg = None
|
||||
if not self.help_properties:
|
||||
self.help_properties = self.proptype
|
||||
properties = list(self.help_properties)
|
||||
if properties == ["frozen"]:
|
||||
self.code = "property-frozen"
|
||||
elif properties == ["mandatory"]:
|
||||
self.code = "property-mandatory"
|
||||
else:
|
||||
self.code = "property-error"
|
||||
super().__init__(None)
|
||||
|
||||
def display_properties(self, force_property=False, add_quote=True):
|
||||
if force_property:
|
||||
properties = self.proptype
|
||||
else:
|
||||
properties = self.help_properties
|
||||
return display_list(list(properties), add_quote=add_quote)
|
||||
def set_orig_opt(self, opt):
|
||||
self._orig_opt = opt
|
||||
|
||||
def __str__(self):
|
||||
# this part is a bit slow, so only execute when display
|
||||
|
|
@ -130,81 +98,42 @@ class PropertiesOptionError(AttributeError):
|
|||
return self.msg
|
||||
if self._settings is None:
|
||||
return "error"
|
||||
arguments = [self._opt_type]
|
||||
if self._orig_opt:
|
||||
arguments.append(
|
||||
self._orig_opt.impl_get_display_name(subconfig, with_quote=True)
|
||||
)
|
||||
arguments.append(self._name)
|
||||
index = self._subconfig.index
|
||||
if index is not None:
|
||||
arguments.append(index)
|
||||
if self.code == "property-frozen":
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _(
|
||||
'cannot modify the {0} {1} at index "{2}" because {3} is frozen'
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
'cannot modify the {0} {1} at index "{2}" because is frozen'
|
||||
)
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot modify the {0} {1} because {2} is frozen")
|
||||
else:
|
||||
msg = _("cannot modify the {0} {1} because is frozen")
|
||||
elif self.code == "property-mandatory":
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because {3} hasn\'t value'
|
||||
)
|
||||
else:
|
||||
msg = _('{0} {1} at index "{2}" is mandatory but hasn\'t value')
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot access to {0} {1} because {2} hasn't value")
|
||||
else:
|
||||
msg = _("{0} {1} is mandatory but hasn't value")
|
||||
if self.help_properties:
|
||||
properties = list(self.help_properties)
|
||||
else:
|
||||
if index is not None:
|
||||
if self._orig_opt:
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because {3} has {4} {5}'
|
||||
)
|
||||
else:
|
||||
msg = _(
|
||||
'cannot access to {0} {1} at index "{2}" because has {3} {4}'
|
||||
)
|
||||
properties = list(self.proptype)
|
||||
only_one = len(properties) == 1
|
||||
properties_msg = display_list(properties, add_quote=True)
|
||||
if only_one:
|
||||
prop_msg = _("property")
|
||||
else:
|
||||
prop_msg = _("properties")
|
||||
if properties == ["frozen"]:
|
||||
if self._orig_opt:
|
||||
msg = _('cannot modify the {0} {1} because "{2}" has {3} {4}')
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _("cannot access to {0} {1} because {2} has {3} {4}")
|
||||
else:
|
||||
msg = _("cannot access to {0} {1} because has {2} {3}")
|
||||
only_one = len(self.help_properties) == 1
|
||||
if only_one:
|
||||
arguments.append(_("property"))
|
||||
msg = _("cannot modify the {0} {1} because has {2} {3}")
|
||||
else:
|
||||
if self._orig_opt:
|
||||
msg = _('cannot access to {0} {1} because "{2}" has {3} {4}')
|
||||
else:
|
||||
arguments.append(_("properties"))
|
||||
arguments.append(self.display_properties())
|
||||
self.msg = msg.format(*arguments)
|
||||
msg = _("cannot access to {0} {1} because has {2} {3}")
|
||||
if self._orig_opt:
|
||||
# FIXME _orig_opt ?
|
||||
self.msg = msg.format(
|
||||
self._opt_type,
|
||||
self._orig_opt.impl_get_display_name(subconfig, with_quote=True),
|
||||
self._name,
|
||||
prop_msg,
|
||||
properties_msg,
|
||||
)
|
||||
else:
|
||||
self.msg = msg.format(self._opt_type, self._name, prop_msg, properties_msg)
|
||||
del self._opt_type, self._name
|
||||
del self._settings, self._orig_opt
|
||||
return self.msg
|
||||
|
||||
|
||||
class AttributeOptionError(AttributeError):
|
||||
def __init__(self, path: str, code: TiramisuErrorCode) -> None:
|
||||
self.path = path
|
||||
self.code = code
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.code == "option-dynamic":
|
||||
return _('cannot access to "{0}" it\'s a dynamic option').format(self.path)
|
||||
return _('"{0}" is not an option').format(self.path)
|
||||
|
||||
|
||||
# ____________________________________________________________
|
||||
# Exceptions for a Config
|
||||
class ConfigError(Exception):
|
||||
|
|
@ -229,74 +158,8 @@ class ConflictError(Exception):
|
|||
# ____________________________________________________________
|
||||
# miscellaneous exceptions
|
||||
class LeadershipError(Exception):
|
||||
def __init__(
|
||||
self,
|
||||
subconfig: Union[str, "SubConfig"],
|
||||
code,
|
||||
*,
|
||||
prop=None,
|
||||
index=None,
|
||||
length=None,
|
||||
callback=None,
|
||||
args=None,
|
||||
kwargs=None,
|
||||
ret=None,
|
||||
):
|
||||
if isinstance(subconfig, str):
|
||||
self.path = self.display_name = subconfig
|
||||
else:
|
||||
self.path = subconfig.path
|
||||
option = subconfig.option
|
||||
self.display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
self.code = code
|
||||
if prop:
|
||||
self.prop = prop
|
||||
if index:
|
||||
self.index = index
|
||||
if length:
|
||||
self.length = length
|
||||
if callback:
|
||||
self.callback = callback
|
||||
if args:
|
||||
self.args = args
|
||||
if kwargs:
|
||||
self.kwargs = kwargs
|
||||
if ret:
|
||||
self.ret = ret
|
||||
|
||||
def __str__(self):
|
||||
if self.code == "leadership-group_type":
|
||||
return _('cannot set "group_type" attribute for the Leadership {0}').format(
|
||||
self.display_name
|
||||
)
|
||||
if self.code == "leadership-wrong_property":
|
||||
return _('the leader {0} cannot have "{1}" property').format(
|
||||
self.display_name, self.prop
|
||||
)
|
||||
if self.code == "leadership-force_default_on_freeze":
|
||||
return _(
|
||||
'the leader {0} cannot have "force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
|
||||
).format(self.display_name)
|
||||
if self.code == "leadership-reduce":
|
||||
return _("cannot reduce length of the leader {0}").format(self.display_name)
|
||||
if self.code == "leadership-greater":
|
||||
return _(
|
||||
'index "{0}" is greater than the leadership length "{1}" for option {2}'
|
||||
).format(self.index, self.length, self.display_name)
|
||||
if self.code == "leadership-follower-greater":
|
||||
return _(
|
||||
"the follower option {0} has greater length ({1}) than the leader length ({2})"
|
||||
).format(self.display_name, self.index, self.length)
|
||||
if self.code == "leadership-follower-callback-list":
|
||||
if self.args or self.kwargs:
|
||||
return _(
|
||||
'the "{0}" function with positional arguments "{1}" and keyword arguments "{2}" must not return a list ("{3}") for the follower option {4}'
|
||||
).format(
|
||||
self.callback, self.args, self.kwargs, self.ret, self.display_name
|
||||
)
|
||||
return _(
|
||||
'the "{0}" function must not return a list ("{1}") for the follower option {2}'
|
||||
).format(self.callback, self.ret, self.display_name)
|
||||
"problem with a leadership's value length"
|
||||
pass
|
||||
|
||||
|
||||
class ConstError(TypeError):
|
||||
|
|
@ -309,7 +172,7 @@ class _CommonError:
|
|||
self.val = val
|
||||
self.display_type = display_type
|
||||
self.opt = weakref.ref(opt)
|
||||
self.name = opt.impl_get_display_name(subconfig, with_quote=True)
|
||||
self.name = opt.impl_get_display_name(subconfig)
|
||||
self.err_msg = err_msg
|
||||
self.index = index
|
||||
super().__init__(self.err_msg)
|
||||
|
|
@ -318,9 +181,7 @@ class _CommonError:
|
|||
try:
|
||||
msg = self.prefix
|
||||
except AttributeError:
|
||||
self.prefix = self.tmpl.format(
|
||||
self.val, _(self.display_type), self.name, self.index
|
||||
)
|
||||
self.prefix = self.tmpl.format(self.val, _(self.display_type), self.name)
|
||||
msg = self.prefix
|
||||
if self.err_msg:
|
||||
if msg:
|
||||
|
|
@ -335,20 +196,13 @@ class _CommonError:
|
|||
class ValueWarning(_CommonError, UserWarning):
|
||||
tmpl = None
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if ValueWarning.tmpl is None:
|
||||
if kwargs.get("index") is None:
|
||||
ValueWarning.tmpl = _(
|
||||
'attention, "{0}" could be an invalid {1} for {2}'
|
||||
)
|
||||
else:
|
||||
ValueWarning.tmpl = _(
|
||||
'attention, "{0}" could be an invalid {1} for {2} at index "{3}"'
|
||||
)
|
||||
if list(kwargs) == ["msg"]:
|
||||
self.msg = kwargs["msg"]
|
||||
ValueWarning.tmpl = _('attention, "{0}" could be an invalid {1} for "{2}"')
|
||||
if len(args) == 1 and not kwargs:
|
||||
self.msg = args[0]
|
||||
else:
|
||||
super().__init__(**kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.msg = None
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -360,13 +214,10 @@ class ValueWarning(_CommonError, UserWarning):
|
|||
class ValueOptionError(_CommonError, ValueError):
|
||||
tmpl = None
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if ValueOptionError.tmpl is None:
|
||||
if kwargs.get("index") is None:
|
||||
self.tmpl = _('"{0}" is an invalid {1} for {2}')
|
||||
else:
|
||||
self.tmpl = _('"{0}" is an invalid {1} for {2} at index "{3}"')
|
||||
super().__init__(**kwargs)
|
||||
ValueOptionError.tmpl = _('"{0}" is an invalid {1} for "{2}"')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class ValueErrorWarning(ValueWarning):
|
||||
|
|
@ -374,39 +225,5 @@ class ValueErrorWarning(ValueWarning):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if ValueErrorWarning.tmpl is None:
|
||||
ValueErrorWarning.tmpl = _('"{0}" is an invalid {1} for {2}')
|
||||
ValueErrorWarning.tmpl = _('"{0}" is an invalid {1} for "{2}"')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class CancelParam(Exception):
|
||||
def __init__(self, origin_path, current_path):
|
||||
super().__init__()
|
||||
self.origin_path = origin_path
|
||||
self.current_path = current_path
|
||||
|
||||
def __ne__(self, value):
|
||||
return value is None or value == ""
|
||||
|
||||
def __eq__(self, value):
|
||||
return value is None or value == ""
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
|
||||
|
||||
class Errors:
|
||||
@staticmethod
|
||||
def raise_carry_out_calculation_error(
|
||||
subconfig, message, original_error, option=None, extra_keys=[]
|
||||
):
|
||||
if option is None:
|
||||
option = subconfig.option
|
||||
display_name = option.impl_get_display_name(subconfig, with_quote=True)
|
||||
if original_error:
|
||||
raise ConfigError(
|
||||
message.format(display_name, original_error, *extra_keys)
|
||||
) from original_error
|
||||
raise ConfigError(message.format(display_name, extra_keys))
|
||||
|
||||
|
||||
errors = Errors()
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -88,8 +88,6 @@ class Base:
|
|||
assert isinstance(properties, frozenset), _(
|
||||
"invalid properties type {0} for {1}," " must be a frozenset"
|
||||
).format(type(properties), name)
|
||||
if not self.impl_is_optiondescription() and "novalidator" not in properties:
|
||||
properties = properties | {"validator"}
|
||||
_setattr = object.__setattr__
|
||||
_setattr(self, "_name", name)
|
||||
_setattr(self, "_informations", {"doc": doc})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# -*- 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
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
"""DomainnameOption
|
||||
"""
|
||||
import re
|
||||
import socket
|
||||
from ipaddress import ip_interface
|
||||
from typing import Any, Optional, List
|
||||
|
||||
|
|
@ -54,18 +53,12 @@ class DomainnameOption(StrOption):
|
|||
type: str = "domainname",
|
||||
allow_without_dot: bool = False,
|
||||
allow_startswith_dot: bool = False,
|
||||
test_existence: bool = False,
|
||||
_extra: dict = None,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-branches,too-many-locals,too-many-arguments
|
||||
if _extra is None:
|
||||
extra = {}
|
||||
else:
|
||||
extra = _extra
|
||||
if type not in ["netbios", "hostname", "domainname"]:
|
||||
raise ValueError(_("unknown type {0} for hostname").format(type))
|
||||
extra["type"] = type
|
||||
extra = {"_dom_type": type}
|
||||
if not isinstance(allow_ip, bool):
|
||||
raise ValueError(_("allow_ip must be a boolean"))
|
||||
if not isinstance(allow_cidr_network, bool):
|
||||
|
|
@ -74,8 +67,7 @@ class DomainnameOption(StrOption):
|
|||
raise ValueError(_("allow_without_dot must be a boolean"))
|
||||
if not isinstance(allow_startswith_dot, bool):
|
||||
raise ValueError(_("allow_startswith_dot must be a boolean"))
|
||||
extra["allow_without_dot"] = allow_without_dot
|
||||
extra["test_existence"] = test_existence
|
||||
extra["_allow_without_dot"] = allow_without_dot
|
||||
if type == "domainname":
|
||||
if allow_without_dot:
|
||||
min_time = 0
|
||||
|
|
@ -84,20 +76,14 @@ class DomainnameOption(StrOption):
|
|||
regexp = r"((?!-)[a-z0-9-]{{{1},{0}}}\.){{{1},}}[a-z0-9-]{{1,{0}}}".format(
|
||||
self._get_len(type), min_time
|
||||
)
|
||||
msg = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number, "-" and "." characters are allowed'
|
||||
)
|
||||
msg_warning = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number, "-" and "." characters are recommanded'
|
||||
)
|
||||
else:
|
||||
regexp = r"((?!-)[a-z0-9-]{{1,{0}}})".format(self._get_len(type))
|
||||
msg = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number and "-" characters are allowed'
|
||||
)
|
||||
msg_warning = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number and "-" characters are recommanded'
|
||||
)
|
||||
msg = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number, "-" and "." characters are allowed'
|
||||
)
|
||||
msg_warning = _(
|
||||
'must start with lowercase characters followed by lowercase characters, number, "-" and "." characters are recommanded'
|
||||
)
|
||||
if allow_ip:
|
||||
msg = _("could be a IP, otherwise {}").format(msg)
|
||||
msg_warning = _("could be a IP, otherwise {}").format(msg_warning)
|
||||
|
|
@ -119,15 +105,15 @@ class DomainnameOption(StrOption):
|
|||
name,
|
||||
doc,
|
||||
)
|
||||
extra["allow_ip"] = allow_ip
|
||||
extra["_allow_ip"] = allow_ip
|
||||
if allow_cidr_network:
|
||||
extra["_network"] = NetworkOption(
|
||||
name,
|
||||
doc,
|
||||
cidr=True,
|
||||
)
|
||||
extra["allow_cidr_network"] = allow_cidr_network
|
||||
extra["allow_startswith_dot"] = allow_startswith_dot
|
||||
extra["_allow_cidr_network"] = allow_cidr_network
|
||||
extra["_allow_startswith_dot"] = allow_startswith_dot
|
||||
|
||||
super().__init__(
|
||||
name,
|
||||
|
|
@ -151,13 +137,13 @@ class DomainnameOption(StrOption):
|
|||
_("invalid length (max {0})" "").format(part_name_length)
|
||||
)
|
||||
|
||||
part_name_length = self._get_len(self.impl_get_extra("type"))
|
||||
if self.impl_get_extra("type") == "domainname":
|
||||
if not self.impl_get_extra("allow_without_dot") and not "." in value:
|
||||
part_name_length = self._get_len(self.impl_get_extra("_dom_type"))
|
||||
if self.impl_get_extra("_dom_type") == "domainname":
|
||||
if not self.impl_get_extra("_allow_without_dot") and not "." in value:
|
||||
raise ValueError(_("must have dot"))
|
||||
if len(value) > 255:
|
||||
raise ValueError(_("invalid length (max 255)"))
|
||||
if self.impl_get_extra("allow_startswith_dot") and value.startswith("."):
|
||||
if self.impl_get_extra("_allow_startswith_dot") and value.startswith("."):
|
||||
val = value[1:]
|
||||
else:
|
||||
val = value
|
||||
|
|
@ -169,22 +155,10 @@ class DomainnameOption(StrOption):
|
|||
_valid_length(dom)
|
||||
else:
|
||||
_valid_length(value)
|
||||
self._validate_domain_resolution(value)
|
||||
|
||||
def _validate_domain_resolution(self, value: str) -> None:
|
||||
if not value.startswith(".") and self.impl_get_extra("test_existence") is True:
|
||||
try:
|
||||
socket.gethostbyname(value)
|
||||
except socket.gaierror as err:
|
||||
raise ValueError(_("DNS resolution failed").format(value)) from err
|
||||
except Exception as err:
|
||||
raise ValueError(
|
||||
_("error resolving DNS: {1}").format(value, err)
|
||||
) from err
|
||||
|
||||
def _validate_ip_network(self, value: str) -> None:
|
||||
allow_ip = self.impl_get_extra("allow_ip")
|
||||
allow_cidr_network = self.impl_get_extra("allow_cidr_network")
|
||||
allow_ip = self.impl_get_extra("_allow_ip")
|
||||
allow_cidr_network = self.impl_get_extra("_allow_cidr_network")
|
||||
if allow_ip is False and allow_cidr_network is False:
|
||||
raise ValueError(_("must not be an IP"))
|
||||
if allow_ip is True:
|
||||
|
|
@ -210,7 +184,7 @@ class DomainnameOption(StrOption):
|
|||
def _second_level_validation_domain(self, value: str, warnings_only: bool) -> None:
|
||||
if self.impl_get_extra("_has_upper").search(value):
|
||||
raise ValueError(_("some characters are uppercase"))
|
||||
if self.impl_get_extra("allow_startswith_dot") and value.startswith("."):
|
||||
if self.impl_get_extra("_allow_startswith_dot") and value.startswith("."):
|
||||
val = value[1:]
|
||||
else:
|
||||
val = value
|
||||
|
|
@ -226,8 +200,8 @@ class DomainnameOption(StrOption):
|
|||
def _second_level_validation_ip_network(
|
||||
self, value: str, warnings_only: bool
|
||||
) -> None:
|
||||
allow_ip = self.impl_get_extra("allow_ip")
|
||||
allow_cidr_network = self.impl_get_extra("allow_cidr_network")
|
||||
allow_ip = self.impl_get_extra("_allow_ip")
|
||||
allow_cidr_network = self.impl_get_extra("_allow_cidr_network")
|
||||
# it's an IP so validate with IPOption
|
||||
if allow_ip is True and allow_cidr_network is False:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ class DynOptionDescription(OptionDescription):
|
|||
)[0]
|
||||
if values is None:
|
||||
values = []
|
||||
values_ = []
|
||||
if __debug__:
|
||||
if not isinstance(values, list):
|
||||
raise ValueError(
|
||||
|
|
@ -133,7 +134,6 @@ class DynOptionDescription(OptionDescription):
|
|||
self.impl_get_display_name(subconfig, with_quote=True), values
|
||||
)
|
||||
)
|
||||
values_ = []
|
||||
for val in values:
|
||||
cval = self.convert_identifier_to_path(val)
|
||||
if not isinstance(cval, str) or re.match(NAME_REGEXP, cval) is None:
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ class FilenameOption(StrOption):
|
|||
if typ not in ["file", "directory"]:
|
||||
raise ValueError(f'unknown type "{typ}" for "{name}"')
|
||||
extra = {
|
||||
"allow_relative": allow_relative,
|
||||
"test_existence": test_existence,
|
||||
"types": types,
|
||||
"_allow_relative": allow_relative,
|
||||
"_test_existence": test_existence,
|
||||
"_types": types,
|
||||
}
|
||||
super().__init__(name, *args, extra=extra, **kwargs)
|
||||
|
||||
|
|
@ -63,10 +63,10 @@ class FilenameOption(StrOption):
|
|||
value: str,
|
||||
) -> None:
|
||||
super().validate(value)
|
||||
if not self.impl_get_extra("allow_relative") and not value.startswith("/"):
|
||||
if not self.impl_get_extra("_allow_relative") and not value.startswith("/"):
|
||||
raise ValueError(_('must starts with "/"'))
|
||||
if value is not None and self.impl_get_extra("test_existence"):
|
||||
types = self.impl_get_extra("types")
|
||||
if value is not None and self.impl_get_extra("_test_existence"):
|
||||
types = self.impl_get_extra("_types")
|
||||
file = Path(value)
|
||||
found = False
|
||||
if "file" in types and file.is_file():
|
||||
|
|
@ -74,12 +74,8 @@ class FilenameOption(StrOption):
|
|||
if not found and "directory" in types and file.is_dir():
|
||||
found = True
|
||||
if not found:
|
||||
translated_types = [
|
||||
{"file": _("file"), "directory": _("directory")}.get(typ)
|
||||
for typ in types
|
||||
]
|
||||
raise ValueError(
|
||||
_("cannot find this {0}").format(
|
||||
display_list(translated_types, separator="or"), value
|
||||
_('cannot find {0} "{1}"').format(
|
||||
display_list(types, separator="or"), value
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class IntOption(Option):
|
|||
value: int,
|
||||
) -> None:
|
||||
if not isinstance(value, int):
|
||||
raise ValueError(_("which is not an integer"))
|
||||
raise ValueError()
|
||||
|
||||
def second_level_validation(self, value, warnings_only):
|
||||
min_number = self.impl_get_extra("min_number")
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ class IPOption(StrOption):
|
|||
):
|
||||
if extra is None:
|
||||
extra = {}
|
||||
extra["private_only"] = private_only
|
||||
extra["allow_reserved"] = allow_reserved
|
||||
extra["cidr"] = cidr
|
||||
extra["_private_only"] = private_only
|
||||
extra["_allow_reserved"] = allow_reserved
|
||||
extra["_cidr"] = cidr
|
||||
super().__init__(*args, extra=extra, **kwargs)
|
||||
|
||||
def _validate_cidr(self, value):
|
||||
|
|
@ -66,7 +66,7 @@ class IPOption(StrOption):
|
|||
|
||||
def validate(self, value: str) -> None:
|
||||
super().validate(value)
|
||||
if self.impl_get_extra("cidr"):
|
||||
if self.impl_get_extra("_cidr"):
|
||||
if "/" not in value:
|
||||
raise ValueError(_('CIDR address must have a "/"'))
|
||||
self._validate_cidr(value)
|
||||
|
|
@ -75,13 +75,13 @@ class IPOption(StrOption):
|
|||
|
||||
def second_level_validation(self, value: str, warnings_only: bool) -> None:
|
||||
ip_obj = ip_interface(value)
|
||||
if not self.impl_get_extra("allow_reserved") and ip_obj.is_reserved:
|
||||
if not self.impl_get_extra("_allow_reserved") and ip_obj.is_reserved:
|
||||
if warnings_only:
|
||||
msg = _("shouldn't be reserved IP")
|
||||
else:
|
||||
msg = _("mustn't be reserved IP")
|
||||
raise ValueError(msg)
|
||||
if self.impl_get_extra("private_only") and not ip_obj.is_private:
|
||||
if self.impl_get_extra("_private_only") and not ip_obj.is_private:
|
||||
if warnings_only:
|
||||
msg = _("should be private IP")
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ class Leadership(OptionDescription):
|
|||
**kwargs,
|
||||
) -> None:
|
||||
if "group_type" in kwargs:
|
||||
raise LeadershipError(name, "leadership-group_type")
|
||||
raise LeadershipError(
|
||||
_('cannot set "group_type" attribute for a Leadership')
|
||||
)
|
||||
super().__init__(
|
||||
name,
|
||||
doc,
|
||||
|
|
@ -83,7 +85,9 @@ class Leadership(OptionDescription):
|
|||
if prop not in ALLOWED_LEADER_PROPERTIES and not isinstance(
|
||||
prop, Calculation
|
||||
):
|
||||
raise LeadershipError(name, "leadership-wrong_property", prop=prop)
|
||||
raise LeadershipError(
|
||||
_('leader cannot have "{}" property').format(prop)
|
||||
)
|
||||
|
||||
def _check_child_is_valid(
|
||||
self,
|
||||
|
|
@ -108,7 +112,7 @@ class Leadership(OptionDescription):
|
|||
if not child.impl_is_multi():
|
||||
raise ValueError(
|
||||
_(
|
||||
"only multi option are allowed in leadership {0} but option "
|
||||
"only multi option allowed in leadership {0} but option "
|
||||
"{1} is not a multi"
|
||||
""
|
||||
).format(
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ class NetworkOption(StrOption):
|
|||
_type = "network address"
|
||||
|
||||
def __init__(self, *args, cidr=False, **kwargs):
|
||||
extra = {"cidr": cidr}
|
||||
extra = {"_cidr": cidr}
|
||||
super().__init__(*args, extra=extra, **kwargs)
|
||||
|
||||
def validate(self, value: str) -> None:
|
||||
super().validate(value)
|
||||
if value.count(".") != 3:
|
||||
raise ValueError()
|
||||
cidr = self.impl_get_extra("cidr")
|
||||
cidr = self.impl_get_extra("_cidr")
|
||||
if cidr:
|
||||
if "/" not in value:
|
||||
raise ValueError(_("must use CIDR notation"))
|
||||
|
|
|
|||
|
|
@ -127,6 +127,11 @@ class Option(BaseOption):
|
|||
def test_multi_value(value):
|
||||
if isinstance(value, Calculation):
|
||||
return
|
||||
# option_bag = OptionBag(self,
|
||||
# None,
|
||||
# undefined,
|
||||
# properties=None,
|
||||
# )
|
||||
try:
|
||||
self.validate(value)
|
||||
self.validate_with_option(
|
||||
|
|
@ -178,19 +183,16 @@ class Option(BaseOption):
|
|||
# undefined,
|
||||
# properties=None,
|
||||
# )
|
||||
self_properties = getattr(self, "_properties", {})
|
||||
self.impl_validate(
|
||||
None,
|
||||
default,
|
||||
loaded=True,
|
||||
self_properties=self_properties,
|
||||
)
|
||||
self.impl_validate(
|
||||
None,
|
||||
default,
|
||||
check_error=False,
|
||||
loaded=True,
|
||||
self_properties=self_properties,
|
||||
)
|
||||
self.value_dependencies(default)
|
||||
if (is_multi and default != []) or (not is_multi and default is not None):
|
||||
|
|
@ -259,22 +261,16 @@ class Option(BaseOption):
|
|||
*,
|
||||
check_error: bool = True,
|
||||
loaded: bool = False,
|
||||
self_properties: frozenset = frozenset(),
|
||||
) -> bool:
|
||||
"""Return True if value is really valid
|
||||
If not validate or invalid return it returns False
|
||||
"""
|
||||
if check_error:
|
||||
if subconfig:
|
||||
config_properties = subconfig.config_bag.properties
|
||||
self_properties = subconfig.properties
|
||||
else:
|
||||
config_properties = {"validator"}
|
||||
if (
|
||||
"validator" not in config_properties
|
||||
or "validator" not in self_properties
|
||||
):
|
||||
return False
|
||||
if (
|
||||
check_error
|
||||
and subconfig
|
||||
and not "validator" in subconfig.config_bag.properties
|
||||
):
|
||||
return False
|
||||
if subconfig:
|
||||
force_index = subconfig.index
|
||||
else:
|
||||
|
|
@ -333,12 +329,12 @@ class Option(BaseOption):
|
|||
except ValueWarning as warn:
|
||||
warnings.warn_explicit(
|
||||
ValueWarning(
|
||||
subconfig=subconfig,
|
||||
val=val,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(warn),
|
||||
index=_index,
|
||||
subconfig,
|
||||
val,
|
||||
_(self.get_type()),
|
||||
self,
|
||||
str(warn),
|
||||
_index,
|
||||
),
|
||||
ValueWarning,
|
||||
self.__class__.__name__,
|
||||
|
|
@ -374,12 +370,12 @@ class Option(BaseOption):
|
|||
if is_warnings_only:
|
||||
warnings.warn_explicit(
|
||||
ValueWarning(
|
||||
subconfig=subconfig,
|
||||
val=_value,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(err),
|
||||
index=_index,
|
||||
subconfig,
|
||||
_value,
|
||||
_(self.get_type()),
|
||||
self,
|
||||
str(err),
|
||||
_index,
|
||||
),
|
||||
ValueWarning,
|
||||
self.__class__.__name__,
|
||||
|
|
@ -446,21 +442,11 @@ class Option(BaseOption):
|
|||
or "demoting_error_warning" not in subconfig.config_bag.properties
|
||||
):
|
||||
raise ValueOptionError(
|
||||
subconfig=subconfig,
|
||||
val=val,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(err),
|
||||
index=err_index,
|
||||
subconfig, val, _(self.get_type()), self, str(err), err_index
|
||||
) from err
|
||||
warnings.warn_explicit(
|
||||
ValueErrorWarning(
|
||||
subconfig=subconfig,
|
||||
val=val,
|
||||
display_type=_(self.get_type()),
|
||||
opt=self,
|
||||
err_msg=str(err),
|
||||
index=err_index,
|
||||
subconfig, val, _(self.get_type()), self, str(err), err_index
|
||||
),
|
||||
ValueErrorWarning,
|
||||
self.__class__.__name__,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from ..setting import ConfigBag, groups, undefined, owners, Undefined
|
|||
from .baseoption import BaseOption
|
||||
|
||||
# from .syndynoption import SubDynOptionDescription, SynDynOptionDescription
|
||||
from ..error import ConfigError, ConflictError, AttributeOptionError
|
||||
from ..error import ConfigError, ConflictError
|
||||
|
||||
|
||||
class CacheOptionDescription(BaseOption):
|
||||
|
|
@ -232,20 +232,19 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
|
||||
def get_child_not_dynamic(
|
||||
self,
|
||||
name: str,
|
||||
allow_dynoption: bool,
|
||||
parent: "SubConfig",
|
||||
name,
|
||||
allow_dynoption,
|
||||
):
|
||||
if name in self._children[0]: # pylint: disable=no-member
|
||||
option = self._children[1][
|
||||
self._children[0].index(name)
|
||||
] # pylint: disable=no-member
|
||||
if option.impl_is_dynoptiondescription() and not allow_dynoption:
|
||||
if parent.path:
|
||||
path = parent.path + "." + name
|
||||
else:
|
||||
path = name
|
||||
raise AttributeOptionError(path, "option-dynamic")
|
||||
raise AttributeError(
|
||||
_(
|
||||
'unknown option "{0}" in root optiondescription (it\'s a dynamic option)'
|
||||
).format(name)
|
||||
)
|
||||
return option
|
||||
|
||||
def get_child(
|
||||
|
|
@ -262,7 +261,6 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
option = self.get_child_not_dynamic(
|
||||
name,
|
||||
allow_dynoption,
|
||||
parent,
|
||||
)
|
||||
if option:
|
||||
return option
|
||||
|
|
@ -276,11 +274,15 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
if not with_identifier:
|
||||
return child
|
||||
return identifier, child
|
||||
if parent.path is None:
|
||||
path = name
|
||||
else:
|
||||
path = parent.path + "." + name
|
||||
raise AttributeOptionError(path, "option-not-found")
|
||||
if self.impl_get_group_type() == groups.root: # pylint: disable=no-member
|
||||
raise AttributeError(
|
||||
_('unknown option "{0}" in root optiondescription').format(name)
|
||||
)
|
||||
raise AttributeError(
|
||||
_('unknown option "{0}" in optiondescription {1}').format(
|
||||
name, self.impl_get_display_name(parent, with_quote=True)
|
||||
)
|
||||
)
|
||||
|
||||
def get_children(self) -> List[BaseOption]:
|
||||
"""get children"""
|
||||
|
|
|
|||
|
|
@ -50,21 +50,15 @@ class PortOption(StrOption):
|
|||
allow_registred: bool = True,
|
||||
allow_protocol: bool = False,
|
||||
allow_private: bool = False,
|
||||
_extra: dict = None,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
if _extra is None:
|
||||
extra = {}
|
||||
else:
|
||||
extra = _extra
|
||||
extra["allow_range"] = allow_range
|
||||
extra["allow_protocol"] = allow_protocol
|
||||
extra["allow_zero"] = allow_zero
|
||||
extra["allow_wellknown"] = allow_wellknown
|
||||
extra["allow_registred"] = allow_registred
|
||||
extra["allow_private"] = allow_private
|
||||
extra["_min_value"] = None
|
||||
extra["_max_value"] = None
|
||||
|
||||
extra = {
|
||||
"_allow_range": allow_range,
|
||||
"_allow_protocol": allow_protocol,
|
||||
"_min_value": None,
|
||||
"_max_value": None,
|
||||
}
|
||||
ports_min = [0, 1, 1024, 49152]
|
||||
ports_max = [0, 1023, 49151, 65535]
|
||||
is_finally = False
|
||||
|
|
@ -88,11 +82,11 @@ class PortOption(StrOption):
|
|||
|
||||
def validate(self, value: str) -> None:
|
||||
super().validate(value)
|
||||
if self.impl_get_extra("allow_protocol") and (
|
||||
if self.impl_get_extra("_allow_protocol") and (
|
||||
value.startswith("tcp:") or value.startswith("udp:")
|
||||
):
|
||||
value = [value[4:]]
|
||||
elif self.impl_get_extra("allow_range") and ":" in str(value):
|
||||
elif self.impl_get_extra("_allow_range") and ":" in str(value):
|
||||
value = value.split(":")
|
||||
if len(value) != 2:
|
||||
raise ValueError(_("range must have two values only"))
|
||||
|
|
@ -108,7 +102,7 @@ class PortOption(StrOption):
|
|||
raise ValueError()
|
||||
|
||||
def second_level_validation(self, value: str, warnings_only: bool) -> None:
|
||||
if self.impl_get_extra("allow_protocol") and (
|
||||
if self.impl_get_extra("_allow_protocol") and (
|
||||
value.startswith("tcp:") or value.startswith("udp:")
|
||||
):
|
||||
value = [value[4:]]
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class StrOption(Option):
|
|||
) -> None:
|
||||
"""validation"""
|
||||
if not isinstance(value, str):
|
||||
raise ValueError(_("which is not a string"))
|
||||
raise ValueError()
|
||||
|
||||
|
||||
class RegexpOption(StrOption):
|
||||
|
|
|
|||
|
|
@ -54,25 +54,24 @@ class URLOption(StrOption):
|
|||
**kwargs,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-arguments,too-many-locals,redefined-builtin
|
||||
extra = {}
|
||||
extra["_domainname"] = DomainnameOption(
|
||||
name,
|
||||
doc,
|
||||
allow_ip=allow_ip,
|
||||
type=type,
|
||||
allow_without_dot=allow_without_dot,
|
||||
_extra=extra,
|
||||
)
|
||||
extra["_port"] = PortOption(
|
||||
name,
|
||||
doc,
|
||||
allow_range=allow_range,
|
||||
allow_zero=allow_zero,
|
||||
allow_wellknown=allow_wellknown,
|
||||
allow_registred=allow_registred,
|
||||
allow_private=allow_private,
|
||||
_extra=extra,
|
||||
)
|
||||
extra = {
|
||||
"_domainname": DomainnameOption(
|
||||
name,
|
||||
doc,
|
||||
allow_ip=allow_ip,
|
||||
type=type,
|
||||
allow_without_dot=allow_without_dot,
|
||||
),
|
||||
"_port": PortOption(
|
||||
name,
|
||||
doc,
|
||||
allow_range=allow_range,
|
||||
allow_zero=allow_zero,
|
||||
allow_wellknown=allow_wellknown,
|
||||
allow_registred=allow_registred,
|
||||
allow_private=allow_private,
|
||||
),
|
||||
}
|
||||
super().__init__(
|
||||
name,
|
||||
doc,
|
||||
|
|
@ -111,18 +110,10 @@ class URLOption(StrOption):
|
|||
domain, port, files = self._get_domain_port_files(value)
|
||||
# validate port
|
||||
portoption = self.impl_get_extra("_port")
|
||||
try:
|
||||
portoption.validate(port)
|
||||
except ValueError as err:
|
||||
msg = _('the port "{0}" is invalid: {1}').format(domain, err)
|
||||
raise ValueError(msg) from err
|
||||
portoption.validate(port)
|
||||
# validate domainname
|
||||
domainnameoption = self.impl_get_extra("_domainname")
|
||||
try:
|
||||
domainnameoption.validate(domain)
|
||||
except ValueError as err:
|
||||
msg = _('the domain "{0}" is invalid: {1}').format(domain, err)
|
||||
raise ValueError(msg) from err
|
||||
domainnameoption.validate(domain)
|
||||
# validate files
|
||||
if files is not None and files != "" and not self.path_re.search(files):
|
||||
raise ValueError(_("must ends with a valid resource name"))
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ EXPIRATION_TIME = 5
|
|||
# demoting_error_warning
|
||||
# all value errors are convert to warning (ValueErrorWarning)
|
||||
DEFAULT_PROPERTIES = frozenset(["cache", "validator", "warnings"])
|
||||
SPECIAL_PROPERTIES = {"frozen", "mandatory", "empty", "force_store_value", "validator"}
|
||||
SPECIAL_PROPERTIES = {"frozen", "mandatory", "empty", "force_store_value"}
|
||||
|
||||
# Config can be in two defaut mode:
|
||||
#
|
||||
|
|
@ -149,7 +149,6 @@ FORBIDDEN_SET_PERMISSIVES = frozenset(
|
|||
"force_default_on_freeze",
|
||||
"force_metaconfig_on_freeze",
|
||||
"force_store_value",
|
||||
"validator",
|
||||
]
|
||||
)
|
||||
ALLOWED_LEADER_PROPERTIES = {
|
||||
|
|
@ -159,8 +158,6 @@ ALLOWED_LEADER_PROPERTIES = {
|
|||
"unique",
|
||||
"force_store_value",
|
||||
"mandatory",
|
||||
"validator",
|
||||
"novalidator",
|
||||
"force_default_on_freeze",
|
||||
"force_metaconfig_on_freeze",
|
||||
"frozen",
|
||||
|
|
@ -476,7 +473,7 @@ class Settings:
|
|||
and new_prop not in ALLOWED_LEADER_PROPERTIES
|
||||
):
|
||||
raise LeadershipError(
|
||||
subconfig, "leadership-wrong_property", prop=new_prop
|
||||
_('leader cannot have "{new_prop}" property')
|
||||
)
|
||||
props.add(new_prop)
|
||||
props -= self.getpermissives(subconfig)
|
||||
|
|
@ -564,15 +561,19 @@ class Settings:
|
|||
not_allowed_properties = properties - ALLOWED_LEADER_PROPERTIES
|
||||
if not_allowed_properties:
|
||||
raise LeadershipError(
|
||||
subconfig,
|
||||
"leadership-wrong_property",
|
||||
prop=display_list(not_allowed_properties),
|
||||
_('leader cannot have "{0}" property').format(
|
||||
display_list(not_allowed_properties)
|
||||
)
|
||||
)
|
||||
if (
|
||||
"force_default_on_freeze" in properties
|
||||
or "force_metaconfig_on_freeze" in properties
|
||||
) and "frozen" not in properties:
|
||||
raise LeadershipError(subconfig, "leadership-force_default_on_freeze")
|
||||
raise LeadershipError(
|
||||
_(
|
||||
'a leader ({0}) cannot have "force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
|
||||
).format(opt.impl_get_display_name())
|
||||
)
|
||||
self._properties.setdefault(subconfig.path, {})[subconfig.index] = properties
|
||||
# values too because of follower values could have a PropertiesOptionError has value
|
||||
subconfig.config_bag.context.reset_cache(subconfig)
|
||||
|
|
|
|||
|
|
@ -646,9 +646,9 @@ class TiramisuDict:
|
|||
if self.remotable == "all" or childapi.has_dependency():
|
||||
obj_form["remote"] = True
|
||||
if childtype == "IPOption" and (
|
||||
child.impl_get_extra("private_only")
|
||||
or not child.impl_get_extra("allow_reserved")
|
||||
or child.impl_get_extra("cidr")
|
||||
child.impl_get_extra("_private_only")
|
||||
or not child.impl_get_extra("_allow_reserved")
|
||||
or child.impl_get_extra("_cidr")
|
||||
):
|
||||
obj_form["remote"] = True
|
||||
if childtype == "DateOption":
|
||||
|
|
|
|||
|
|
@ -265,10 +265,9 @@ class Values:
|
|||
) -> None:
|
||||
"""set value to option"""
|
||||
owner = self.get_context_owner()
|
||||
self_properties = subconfig.properties
|
||||
setting_properties = subconfig.config_bag.properties
|
||||
ori_value = value
|
||||
if "validator" in setting_properties and "validator" in self_properties:
|
||||
if "validator" in setting_properties:
|
||||
value, has_calculation = self.setvalue_validation(
|
||||
subconfig,
|
||||
value,
|
||||
|
|
@ -296,7 +295,6 @@ class Values:
|
|||
)
|
||||
validator = (
|
||||
"validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
and "demoting_error_warning" not in setting_properties
|
||||
)
|
||||
if validator and not has_calculation:
|
||||
|
|
@ -306,11 +304,7 @@ class Values:
|
|||
value,
|
||||
validated=validator,
|
||||
)
|
||||
elif (
|
||||
"validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
and has_calculation
|
||||
):
|
||||
elif "validator" in setting_properties and has_calculation:
|
||||
cache = subconfig.config_bag.context.get_values_cache()
|
||||
cache.delcache(subconfig.path)
|
||||
|
||||
|
|
@ -593,39 +587,35 @@ class Values:
|
|||
"""reset value for an option"""
|
||||
config_bag = subconfig.config_bag
|
||||
hasvalue = self.hasvalue(subconfig.path)
|
||||
self_properties = subconfig.properties
|
||||
context = config_bag.context
|
||||
setting_properties = config_bag.properties
|
||||
if (
|
||||
validate
|
||||
and hasvalue
|
||||
and "validator" in setting_properties
|
||||
and "validator" in self_properties
|
||||
):
|
||||
fake_context = context.gen_fake_context()
|
||||
fake_config_bag = config_bag.copy()
|
||||
fake_config_bag.remove_validation()
|
||||
fake_config_bag.context = fake_context
|
||||
fake_subconfig = fake_context.get_sub_config(
|
||||
fake_config_bag,
|
||||
subconfig.path,
|
||||
subconfig.index,
|
||||
validate_properties=False,
|
||||
)
|
||||
fake_values = fake_context.get_values()
|
||||
fake_values.reset(fake_subconfig)
|
||||
fake_subconfig.config_bag.properties = setting_properties
|
||||
value = fake_values.get_default_value(fake_subconfig)
|
||||
fake_values.setvalue_validation(
|
||||
fake_subconfig,
|
||||
value,
|
||||
)
|
||||
if validate:
|
||||
if hasvalue and "validator" in setting_properties:
|
||||
fake_context = context.gen_fake_context()
|
||||
fake_config_bag = config_bag.copy()
|
||||
fake_config_bag.remove_validation()
|
||||
fake_config_bag.context = fake_context
|
||||
fake_subconfig = fake_context.get_sub_config(
|
||||
fake_config_bag,
|
||||
subconfig.path,
|
||||
subconfig.index,
|
||||
validate_properties=False,
|
||||
)
|
||||
fake_values = fake_context.get_values()
|
||||
fake_values.reset(fake_subconfig)
|
||||
fake_subconfig.config_bag.properties = setting_properties
|
||||
value = fake_values.get_default_value(fake_subconfig)
|
||||
fake_values.setvalue_validation(
|
||||
fake_subconfig,
|
||||
value,
|
||||
)
|
||||
# if hasvalue:
|
||||
opt = subconfig.option
|
||||
if opt.impl_is_leader():
|
||||
opt.impl_get_leadership().reset(subconfig.parent)
|
||||
if (
|
||||
"force_store_value" in setting_properties
|
||||
and "force_store_value" in self_properties
|
||||
and "force_store_value" in subconfig.properties
|
||||
):
|
||||
value = self.get_default_value(subconfig)
|
||||
|
||||
|
|
@ -672,11 +662,10 @@ class Values:
|
|||
index=subconfig.index,
|
||||
):
|
||||
return
|
||||
self_properties = subconfig.properties
|
||||
config_bag = subconfig.config_bag
|
||||
context = config_bag.context
|
||||
setting_properties = config_bag.properties
|
||||
if "validator" in setting_properties and "validator" in self_properties:
|
||||
if "validator" in setting_properties:
|
||||
fake_context = context.gen_fake_context()
|
||||
fake_config_bag = config_bag.copy()
|
||||
fake_config_bag.remove_validation()
|
||||
|
|
@ -697,7 +686,7 @@ class Values:
|
|||
)
|
||||
if (
|
||||
"force_store_value" in setting_properties
|
||||
and "force_store_value" in self_properties
|
||||
and "force_store_value" in subconfig.properties
|
||||
):
|
||||
value = self.get_default_value(
|
||||
subconfig,
|
||||
|
|
|
|||
Loading…
Reference in a new issue