todict for tiramisu 4
This commit is contained in:
parent
0a4e1445db
commit
50f0f67629
35 changed files with 361 additions and 226 deletions
2
AUTHORS
2
AUTHORS
|
@ -1,7 +1,7 @@
|
||||||
Authors
|
Authors
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Emmanuel Garette <egarette@cadoles.com> lead developer
|
Emmanuel Garette <egarette@silique.fr> lead developer
|
||||||
Gwenaël Rémond <gremond@cadoles.com> developer
|
Gwenaël Rémond <gremond@cadoles.com> developer
|
||||||
|
|
||||||
Daniel Dehennin <daniel.dehennin@ac-dijon.fr> contributor
|
Daniel Dehennin <daniel.dehennin@ac-dijon.fr> contributor
|
||||||
|
|
|
@ -6,7 +6,7 @@ def get_description():
|
||||||
option1 = ChoiceOption('choice', "Choice description", ("hide", "show"), default='hide', properties=('mandatory',))
|
option1 = ChoiceOption('choice', "Choice description", ("hide", "show"), default='hide', properties=('mandatory',))
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('hide')}))
|
'expected': ParamValue('hide')}))
|
||||||
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,))
|
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,))
|
||||||
descr1 = OptionDescription("options", "Common configuration", [option1, option2])
|
descr1 = OptionDescription("options", "Common configuration", [option1, option2])
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": null}
|
{
|
||||||
|
"options.unicode": null
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": "val"}
|
{
|
||||||
|
"options.unicode": "val"
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True)
|
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option2, todict=True),
|
kwargs={'condition': ParamOption(option2),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True)
|
option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True)
|
||||||
|
|
|
@ -10,7 +10,7 @@ def get_description():
|
||||||
option3 = StrOption('unicode3', "Unicode follower 2", multi=True)
|
option3 = StrOption('unicode3', "Unicode follower 2", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option, todict=True),
|
kwargs={'condition': ParamOption(option),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
descr1 = Leadership("unicode1", "Common configuration",
|
descr1 = Leadership("unicode1", "Common configuration",
|
||||||
|
|
|
@ -9,7 +9,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Unicode follower 2", multi=True)
|
option2 = StrOption('unicode2', "Unicode follower 2", multi=True)
|
||||||
disabled_property = Calculation(calc_value,
|
disabled_property = Calculation(calc_value,
|
||||||
Params(ParamValue('disabled'),
|
Params(ParamValue('disabled'),
|
||||||
kwargs={'condition': ParamOption(option, todict=True),
|
kwargs={'condition': ParamOption(option),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 3", properties=(disabled_property,), multi=True)
|
option3 = StrOption('unicode3', "Unicode follower 3", properties=(disabled_property,), multi=True)
|
||||||
|
|
|
@ -8,7 +8,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Unicode follower 1", multi=True)
|
option2 = StrOption('unicode2', "Unicode follower 1", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
||||||
|
|
|
@ -8,7 +8,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Unicode follower 1", multi=True)
|
option2 = StrOption('unicode2', "Unicode follower 1", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
||||||
|
|
|
@ -8,7 +8,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 2'", multi=True)
|
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 2'", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option2, todict=True),
|
kwargs={'condition': ParamOption(option2),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,))
|
||||||
|
|
|
@ -9,7 +9,7 @@ def get_description():
|
||||||
option2 = StrOption('unicode2', "Unicode follower 2", multi=True)
|
option2 = StrOption('unicode2', "Unicode follower 2", multi=True)
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option, todict=True),
|
kwargs={'condition': ParamOption(option),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True)
|
option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True)
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
{"options.unicode.unicode": ["val3", "val4"],
|
{
|
||||||
"options.unicode.unicode1": ["super1", "super2"],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test", "test"],
|
{
|
||||||
"options.unicode.unicode3": [null, "super"]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val4",
|
||||||
|
"options.unicode.unicode1": "super2",
|
||||||
|
"options.unicode.unicode2": "test",
|
||||||
|
"options.unicode.unicode3": "super"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,16 @@
|
||||||
{"options.unicode.unicode": ["val1", "val2"],
|
{
|
||||||
"options.unicode.unicode1": [null, null],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["follower2", "follower2"],
|
{
|
||||||
"options.unicode.unicode3": [null, null]}
|
"options.unicode.unicode": "val1",
|
||||||
|
"options.unicode.unicode1": null,
|
||||||
|
"options.unicode.unicode2": "follower2",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val2",
|
||||||
|
"options.unicode.unicode1": null,
|
||||||
|
"options.unicode.unicode2": "follower2",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,10 @@
|
||||||
{"options.unicode.unicode": ["val3"],
|
{
|
||||||
"options.unicode.unicode1": ["super1"],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test"],
|
{
|
||||||
"options.unicode.unicode3": [null]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,22 @@
|
||||||
{"options.unicode.unicode": ["val3", "val4", "val5"],
|
{
|
||||||
"options.unicode.unicode1": ["super1", "super2", null],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test", "test", "follower2"],
|
{
|
||||||
"options.unicode.unicode3": [null, "super", null]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val4",
|
||||||
|
"options.unicode.unicode1": "super2",
|
||||||
|
"options.unicode.unicode2": "test",
|
||||||
|
"options.unicode.unicode3": "super"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val5",
|
||||||
|
"options.unicode.unicode1": null,
|
||||||
|
"options.unicode.unicode2": "follower2",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,22 @@
|
||||||
{"options.unicode.unicode": ["val3", "val4", "val5"],
|
{
|
||||||
"options.unicode.unicode1": ["super1", "super2", null],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test", "test", "follower2"],
|
{
|
||||||
"options.unicode.unicode3": [null, "super", null]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val4",
|
||||||
|
"options.unicode.unicode1": "super2",
|
||||||
|
"options.unicode.unicode2": "test",
|
||||||
|
"options.unicode.unicode3": "super"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val5",
|
||||||
|
"options.unicode.unicode1": null,
|
||||||
|
"options.unicode.unicode2": "follower2",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,16 @@
|
||||||
{"options.unicode.unicode": ["val3", "val4"],
|
{
|
||||||
"options.unicode.unicode1": ["super1", "super2"],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test", "follower2"],
|
{
|
||||||
"options.unicode.unicode3": [null, "super"]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val4",
|
||||||
|
"options.unicode.unicode1": "super2",
|
||||||
|
"options.unicode.unicode2": "follower2",
|
||||||
|
"options.unicode.unicode3": "super"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,16 @@
|
||||||
{"options.unicode.unicode": ["val3", "val4"],
|
{
|
||||||
"options.unicode.unicode1": ["super1", "super2"],
|
"options.unicode.unicode": [
|
||||||
"options.unicode.unicode2": ["pas test", "test2"],
|
{
|
||||||
"options.unicode.unicode3": [null, "super"]}
|
"options.unicode.unicode": "val3",
|
||||||
|
"options.unicode.unicode1": "super1",
|
||||||
|
"options.unicode.unicode2": "pas test",
|
||||||
|
"options.unicode.unicode3": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"options.unicode.unicode": "val4",
|
||||||
|
"options.unicode.unicode1": "super2",
|
||||||
|
"options.unicode.unicode2": "test2",
|
||||||
|
"options.unicode.unicode3": "super"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": "a"}
|
{
|
||||||
|
"options.unicode": "a"
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": "val"}
|
{
|
||||||
|
"options.unicode": "val"
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": null}
|
{
|
||||||
|
"options.unicode": null
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
{"options.unicode": []}
|
{
|
||||||
|
"options.unicode": []
|
||||||
|
}
|
|
@ -1 +1,5 @@
|
||||||
{"options.unicode": ["val"]}
|
{
|
||||||
|
"options.unicode": [
|
||||||
|
"val"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,7 @@
|
||||||
{"options.unicode": ["c", "d", "e"]}
|
{
|
||||||
|
"options.unicode": [
|
||||||
|
"c",
|
||||||
|
"d",
|
||||||
|
"e"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,6 @@
|
||||||
{"options.unicode": ["a", "b"]}
|
{
|
||||||
|
"options.unicode": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1 +1,7 @@
|
||||||
{"options.unicode": ["c", "f", "e"]}
|
{
|
||||||
|
"options.unicode": [
|
||||||
|
"c",
|
||||||
|
"f",
|
||||||
|
"e"
|
||||||
|
]
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ def get_description():
|
||||||
option1 = StrOption('unicode1', "Value 'test' must show Unicode 2")
|
option1 = StrOption('unicode1', "Value 'test' must show Unicode 2")
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,), multi=True)
|
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,), multi=True)
|
||||||
|
|
|
@ -10,7 +10,7 @@ def get_description():
|
||||||
option3 = StrOption('unicode3', "Unicode 3")
|
option3 = StrOption('unicode3', "Unicode 3")
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
descr2 = OptionDescription("unicode1", "OptionDescription with 2 options", [option2, option3], properties=(hidden_property,))
|
descr2 = OptionDescription("unicode1", "OptionDescription with 2 options", [option2, option3], properties=(hidden_property,))
|
||||||
|
|
|
@ -7,7 +7,7 @@ def get_description():
|
||||||
option1 = StrOption('unicode1', "Value 'test' must show Unicode 2")
|
option1 = StrOption('unicode1', "Value 'test' must show Unicode 2")
|
||||||
hidden_property = Calculation(calc_value,
|
hidden_property = Calculation(calc_value,
|
||||||
Params(ParamValue('hidden'),
|
Params(ParamValue('hidden'),
|
||||||
kwargs={'condition': ParamOption(option1, todict=True),
|
kwargs={'condition': ParamOption(option1),
|
||||||
'expected': ParamValue('test'),
|
'expected': ParamValue('test'),
|
||||||
'reverse_condition': ParamValue(True)}))
|
'reverse_condition': ParamValue(True)}))
|
||||||
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,))
|
option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,))
|
||||||
|
|
|
@ -23,8 +23,8 @@ def datapath():
|
||||||
|
|
||||||
|
|
||||||
def list_data(ext='.py'):
|
def list_data(ext='.py'):
|
||||||
# if ext == '.py':
|
# if ext == '.py':
|
||||||
# return ['choice1_leadership_hidden.py']
|
# return ['unicode1_leadership_requires.py']
|
||||||
datadir = datapath()
|
datadir = datapath()
|
||||||
filenames = listdir(datadir)
|
filenames = listdir(datadir)
|
||||||
filenames.sort()
|
filenames.sort()
|
||||||
|
@ -40,7 +40,8 @@ def load_config(filename,
|
||||||
add_extra_od=False,
|
add_extra_od=False,
|
||||||
remote='minimum',
|
remote='minimum',
|
||||||
clearable='minimum',
|
clearable='minimum',
|
||||||
root=None):
|
root=None,
|
||||||
|
):
|
||||||
modulepath = splitext(filename)[0]
|
modulepath = splitext(filename)[0]
|
||||||
mod = __import__(modulepath)
|
mod = __import__(modulepath)
|
||||||
descr = mod.get_description()
|
descr = mod.get_description()
|
||||||
|
@ -169,7 +170,8 @@ def test_jsons(filename):
|
||||||
print(" {} (remote: {}, clearable: {})".format(filename, remote, clearable))
|
print(" {} (remote: {}, clearable: {})".format(filename, remote, clearable))
|
||||||
values = load_config(filename,
|
values = load_config(filename,
|
||||||
remote=remote,
|
remote=remote,
|
||||||
clearable=clearable)
|
clearable=clearable,
|
||||||
|
)
|
||||||
#
|
#
|
||||||
if not isfile(join(datadir, modulepath + '.json')) and \
|
if not isfile(join(datadir, modulepath + '.json')) and \
|
||||||
clearable == 'minimum' and \
|
clearable == 'minimum' and \
|
||||||
|
@ -216,6 +218,27 @@ def test_jsons(filename):
|
||||||
assert values == expected, "error in file {}".format(filename)
|
assert values == expected, "error in file {}".format(filename)
|
||||||
|
|
||||||
|
|
||||||
|
def loads_yml(fh, issub, modulepath):
|
||||||
|
dico = loads(fh.read())
|
||||||
|
if issub:
|
||||||
|
new_dico_ori = {}
|
||||||
|
for key, value in dico.items():
|
||||||
|
key = modulepath + '.' + key
|
||||||
|
if isinstance(value, list):
|
||||||
|
new_value = []
|
||||||
|
for val in value:
|
||||||
|
if isinstance(val, dict):
|
||||||
|
new_val = {}
|
||||||
|
for k, v in val.items():
|
||||||
|
new_val[modulepath + '.' + k] = v
|
||||||
|
val = new_val
|
||||||
|
new_value.append(val)
|
||||||
|
value = new_value
|
||||||
|
new_dico_ori[key] = value
|
||||||
|
dico = new_dico_ori
|
||||||
|
return dico
|
||||||
|
|
||||||
|
|
||||||
def test_jsons_subconfig(filename):
|
def test_jsons_subconfig(filename):
|
||||||
debug = False
|
debug = False
|
||||||
# debug = True
|
# debug = True
|
||||||
|
@ -311,13 +334,7 @@ def test_updates(filename_mod):
|
||||||
dico_ori = None
|
dico_ori = None
|
||||||
else:
|
else:
|
||||||
with open(join(datadir, modulepath + '.dict'), 'r') as fh:
|
with open(join(datadir, modulepath + '.dict'), 'r') as fh:
|
||||||
dico_ori = loads(fh.read())
|
dico_ori = loads_yml(fh, issub, modulepath)
|
||||||
if issub:
|
|
||||||
new_dico_ori = {}
|
|
||||||
for key, value in dico_ori.items():
|
|
||||||
key = modulepath + '.' + key
|
|
||||||
new_dico_ori[key] = value
|
|
||||||
dico_ori = new_dico_ori
|
|
||||||
# modify config
|
# modify config
|
||||||
with open(join(datadir, modulepath + '.mod{}'.format(idx)), 'r') as fh:
|
with open(join(datadir, modulepath + '.mod{}'.format(idx)), 'r') as fh:
|
||||||
body = loads(fh.read())['body']
|
body = loads(fh.read())['body']
|
||||||
|
@ -343,13 +360,7 @@ def test_updates(filename_mod):
|
||||||
dico_mod = None
|
dico_mod = None
|
||||||
else:
|
else:
|
||||||
with open(join(datadir, modulepath + '.dict{}'.format(idx)), 'r') as fh:
|
with open(join(datadir, modulepath + '.dict{}'.format(idx)), 'r') as fh:
|
||||||
dico_mod = loads(fh.read())
|
dico_mod = loads_yml(fh, issub, modulepath)
|
||||||
if issub:
|
|
||||||
new_dico = {}
|
|
||||||
for key, value in dico_mod.items():
|
|
||||||
key = modulepath + '.' + key
|
|
||||||
new_dico[key] = value
|
|
||||||
dico_mod = new_dico
|
|
||||||
if root is None:
|
if root is None:
|
||||||
root_path = ''
|
root_path = ''
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -232,8 +232,9 @@ def test_leader_list(config_type):
|
||||||
assert ret[0].name() == 'leadership'
|
assert ret[0].name() == 'leadership'
|
||||||
#
|
#
|
||||||
ret = cfg.option('leadership').list('all')
|
ret = cfg.option('leadership').list('all')
|
||||||
assert len(ret) == 1
|
assert len(ret) == 2
|
||||||
assert ret[0].name() == 'ip_admin_eth0'
|
assert ret[0].name() == 'ip_admin_eth0'
|
||||||
|
assert ret[1].name() == 'netmask_admin_eth0'
|
||||||
#
|
#
|
||||||
cfg.option('leadership.ip_admin_eth0').value.set(['a', 'b'])
|
cfg.option('leadership.ip_admin_eth0').value.set(['a', 'b'])
|
||||||
cfg.option('leadership.netmask_admin_eth0', 0).value.set('c')
|
cfg.option('leadership.netmask_admin_eth0', 0).value.set('c')
|
||||||
|
|
|
@ -58,8 +58,8 @@ def test_mod_read_only_write():
|
||||||
od1 = OptionDescription("options", "", [s])
|
od1 = OptionDescription("options", "", [s])
|
||||||
config = Config(od1)
|
config = Config(od1)
|
||||||
config2 = Config(od1)
|
config2 = Config(od1)
|
||||||
assert config.property.getdefault() == {'cache', 'validator', 'warnings'}
|
assert config.property.default() == {'cache', 'validator', 'warnings'}
|
||||||
assert config.property.getdefault('read_only', 'append') == {'frozen',
|
assert config.property.default('read_only', 'append') == {'frozen',
|
||||||
'disabled',
|
'disabled',
|
||||||
'validator',
|
'validator',
|
||||||
'everything_frozen',
|
'everything_frozen',
|
||||||
|
@ -67,16 +67,16 @@ def test_mod_read_only_write():
|
||||||
'empty',
|
'empty',
|
||||||
'force_store_value',
|
'force_store_value',
|
||||||
}
|
}
|
||||||
assert config.property.getdefault('read_only', 'remove') == {'permissive',
|
assert config.property.default('read_only', 'remove') == {'permissive',
|
||||||
'hidden',
|
'hidden',
|
||||||
}
|
}
|
||||||
assert config.property.getdefault('read_write', 'append') == {'frozen',
|
assert config.property.default('read_write', 'append') == {'frozen',
|
||||||
'disabled',
|
'disabled',
|
||||||
'validator',
|
'validator',
|
||||||
'hidden',
|
'hidden',
|
||||||
'force_store_value',
|
'force_store_value',
|
||||||
}
|
}
|
||||||
assert config.property.getdefault('read_write', 'remove') == {'permissive',
|
assert config.property.default('read_write', 'remove') == {'permissive',
|
||||||
'everything_frozen',
|
'everything_frozen',
|
||||||
'mandatory',
|
'mandatory',
|
||||||
'empty',
|
'empty',
|
||||||
|
@ -94,12 +94,12 @@ def test_mod_read_only_write():
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
config.property.setdefault(type='read_only', when='append', properties=['disabled'])
|
config.property.setdefault(type='read_only', when='append', properties=['disabled'])
|
||||||
|
|
||||||
assert config.property.getdefault() == {'cache'}
|
assert config.property.default() == {'cache'}
|
||||||
assert config.property.getdefault('read_only', 'append') == {'disabled'}
|
assert config.property.default('read_only', 'append') == {'disabled'}
|
||||||
assert config.property.getdefault('read_only', 'remove') == {'hidden'}
|
assert config.property.default('read_only', 'remove') == {'hidden'}
|
||||||
assert config.property.getdefault('read_write', 'append') == {'disabled',
|
assert config.property.default('read_write', 'append') == {'disabled',
|
||||||
'hidden'}
|
'hidden'}
|
||||||
assert config.property.getdefault('read_write', 'remove') == set([])
|
assert config.property.default('read_write', 'remove') == set([])
|
||||||
#
|
#
|
||||||
config.property.read_only()
|
config.property.read_only()
|
||||||
assert config.property.get() == {'cache', 'disabled'}
|
assert config.property.get() == {'cache', 'disabled'}
|
||||||
|
@ -108,29 +108,33 @@ def test_mod_read_only_write():
|
||||||
config.property.read_only()
|
config.property.read_only()
|
||||||
assert config.property.get() == {'cache', 'disabled'}
|
assert config.property.get() == {'cache', 'disabled'}
|
||||||
#
|
#
|
||||||
assert config2.property.getdefault() == {'cache', 'validator', 'warnings'}
|
assert config2.property.default() == {'cache', 'validator', 'warnings'}
|
||||||
assert config2.property.getdefault('read_only', 'append') == {'frozen',
|
assert config2.property.default('read_only', 'append') == {'frozen',
|
||||||
'disabled',
|
'disabled',
|
||||||
'validator',
|
'validator',
|
||||||
'everything_frozen',
|
'everything_frozen',
|
||||||
'mandatory',
|
'mandatory',
|
||||||
'empty',
|
'empty',
|
||||||
'force_store_value'}
|
'force_store_value',
|
||||||
assert config2.property.getdefault('read_only', 'remove') == {'permissive',
|
}
|
||||||
'hidden'}
|
assert config2.property.default('read_only', 'remove') == {'permissive',
|
||||||
assert config2.property.getdefault('read_write', 'append') == {'frozen',
|
'hidden',
|
||||||
|
}
|
||||||
|
assert config2.property.default('read_write', 'append') == {'frozen',
|
||||||
'disabled',
|
'disabled',
|
||||||
'validator',
|
'validator',
|
||||||
'hidden',
|
'hidden',
|
||||||
'force_store_value'}
|
'force_store_value',
|
||||||
assert config2.property.getdefault('read_write', 'remove') == {'permissive',
|
}
|
||||||
|
assert config2.property.default('read_write', 'remove') == {'permissive',
|
||||||
'everything_frozen',
|
'everything_frozen',
|
||||||
'mandatory',
|
'mandatory',
|
||||||
'empty'}
|
'empty',
|
||||||
|
}
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
config2.property.getdefault('unknown', 'remove')
|
config2.property.default('unknown', 'remove')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
config2.property.getdefault('read_write', 'unknown')
|
config2.property.default('read_write', 'unknown')
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ from .option import RegexpOption, OptionDescription, ChoiceOption
|
||||||
from .todict import TiramisuDict
|
from .todict import TiramisuDict
|
||||||
|
|
||||||
|
|
||||||
TIRAMISU_VERSION = 3
|
TIRAMISU_VERSION = 4
|
||||||
|
|
||||||
|
|
||||||
class TiramisuHelp:
|
class TiramisuHelp:
|
||||||
|
@ -166,7 +166,7 @@ class CommonTiramisuOption(CommonTiramisu):
|
||||||
self._config_bag = config_bag
|
self._config_bag = config_bag
|
||||||
|
|
||||||
def __getattr__(self, subfunc):
|
def __getattr__(self, subfunc):
|
||||||
raise ConfigError(_('please specify a valid sub function ({})').format(subfunc))
|
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
|
||||||
|
|
||||||
|
|
||||||
class _TiramisuOptionWalk:
|
class _TiramisuOptionWalk:
|
||||||
|
@ -188,6 +188,7 @@ class _TiramisuOptionWalk:
|
||||||
recursive=recursive,
|
recursive=recursive,
|
||||||
types=types,
|
types=types,
|
||||||
group_type=group_type,
|
group_type=group_type,
|
||||||
|
flatten_leadership=True,
|
||||||
):
|
):
|
||||||
if isinstance(option_bag, dict):
|
if isinstance(option_bag, dict):
|
||||||
for opts_bag in option_bag.values():
|
for opts_bag in option_bag.values():
|
||||||
|
@ -214,7 +215,7 @@ class _TiramisuOptionOptionDescription:
|
||||||
"""Manage option"""
|
"""Manage option"""
|
||||||
_validate_properties = False
|
_validate_properties = False
|
||||||
|
|
||||||
@option_type(['optiondescription', 'option', 'with_or_without_index'])
|
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||||
def get(self, options_bag: List[OptionBag]):
|
def get(self, options_bag: List[OptionBag]):
|
||||||
"""Get Tiramisu option"""
|
"""Get Tiramisu option"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
|
@ -277,7 +278,7 @@ class _TiramisuOptionOptionDescription:
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
return option_bag.option.impl_is_optiondescription()
|
return option_bag.option.impl_is_optiondescription()
|
||||||
|
|
||||||
@option_type(['optiondescription', 'option', 'with_index'])
|
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||||
def properties(self,
|
def properties(self,
|
||||||
options_bag: List[OptionBag],
|
options_bag: List[OptionBag],
|
||||||
only_raises=False,
|
only_raises=False,
|
||||||
|
@ -319,7 +320,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
||||||
"""Test if option is a leader"""
|
"""Test if option is a leader"""
|
||||||
return options_bag[-1].option.impl_is_leader()
|
return options_bag[-1].option.impl_is_leader()
|
||||||
|
|
||||||
@option_type(['option', 'with_or_without_index'])
|
@option_type(['option', 'with_or_without_index', 'symlink'])
|
||||||
def isfollower(self, options_bag: List[OptionBag]):
|
def isfollower(self, options_bag: List[OptionBag]):
|
||||||
"""Test if option is a follower"""
|
"""Test if option is a follower"""
|
||||||
return options_bag[-1].option.impl_is_follower()
|
return options_bag[-1].option.impl_is_follower()
|
||||||
|
@ -362,12 +363,12 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
||||||
type = option.get_type()
|
type = option.get_type()
|
||||||
if isinstance(option, RegexpOption):
|
if isinstance(option, RegexpOption):
|
||||||
return option._regexp.pattern
|
return option._regexp.pattern
|
||||||
if type == 'integer':
|
if type == _('integer'):
|
||||||
# FIXME negative too!
|
# FIXME negative too!
|
||||||
return r'^[0-9]+$'
|
return r'^[0-9]+$'
|
||||||
if type == 'domainname':
|
if type == _('domain name'):
|
||||||
return option.impl_get_extra('_domain_re').pattern
|
return option.impl_get_extra('_domain_re').pattern
|
||||||
if type in ['ip', 'network', 'netmask']:
|
if type in [_('ip'), _('network'), _('netmask')]:
|
||||||
#FIXME only from 0.0.0.0 to 255.255.255.255
|
#FIXME only from 0.0.0.0 to 255.255.255.255
|
||||||
return r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
return r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
||||||
|
|
||||||
|
@ -439,7 +440,7 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
"""Manage option's property"""
|
"""Manage option's property"""
|
||||||
_validate_properties = False
|
_validate_properties = False
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'with_index'])
|
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||||
def get(self,
|
def get(self,
|
||||||
options_bag: List[OptionBag],
|
options_bag: List[OptionBag],
|
||||||
only_raises=False,
|
only_raises=False,
|
||||||
|
@ -495,11 +496,10 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
class TiramisuOptionPermissive(CommonTiramisuOption):
|
class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||||
"""Manage option's permissive"""
|
"""Manage option's permissive"""
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'symlink', 'with_index'])
|
@option_type(['option', 'optiondescription', 'symlink', 'with_or_without_index'])
|
||||||
def get(self, options_bag: List[OptionBag]):
|
def get(self, options_bag: List[OptionBag]):
|
||||||
"""Get permissives value"""
|
"""Get permissives value"""
|
||||||
option_bag = options_bag[-1]
|
return self._config_bag.context.get_settings().getpermissives(options_bag[-1])
|
||||||
return self._config_bag.context.get_settings().getpermissives(option_bag)
|
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||||
def set(self,
|
def set(self,
|
||||||
|
@ -522,7 +522,7 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||||
class TiramisuOptionInformation(CommonTiramisuOption):
|
class TiramisuOptionInformation(CommonTiramisuOption):
|
||||||
"""Manage option's informations"""
|
"""Manage option's informations"""
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
@option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink'])
|
||||||
def get(self,
|
def get(self,
|
||||||
options_bag: List[OptionBag],
|
options_bag: List[OptionBag],
|
||||||
name: str,
|
name: str,
|
||||||
|
@ -561,7 +561,7 @@ class TiramisuOptionInformation(CommonTiramisuOption):
|
||||||
path=option_bag.path,
|
path=option_bag.path,
|
||||||
)
|
)
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
@option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink'])
|
||||||
def list(self,
|
def list(self,
|
||||||
options_bag: List[OptionBag],
|
options_bag: List[OptionBag],
|
||||||
) -> list:
|
) -> list:
|
||||||
|
@ -662,7 +662,7 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@option_type(['choice', 'with_index'])
|
@option_type(['choice', 'with_or_without_index'])
|
||||||
def list(self, options_bag: List[OptionBag]):
|
def list(self, options_bag: List[OptionBag]):
|
||||||
"""All values available for a ChoiceOption"""
|
"""All values available for a ChoiceOption"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
|
@ -754,7 +754,7 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig):
|
||||||
self._index,
|
self._index,
|
||||||
self._config_bag,
|
self._config_bag,
|
||||||
)
|
)
|
||||||
raise ConfigError(_('please specify a valid sub function ({})').format(subfunc))
|
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
|
||||||
|
|
||||||
@option_type('optiondescription')
|
@option_type('optiondescription')
|
||||||
def find(self,
|
def find(self,
|
||||||
|
@ -793,7 +793,7 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig):
|
||||||
recursive=False,
|
recursive=False,
|
||||||
group_type=None,
|
group_type=None,
|
||||||
):
|
):
|
||||||
"""List options (by default list only option)"""
|
"""List options inside an option description (by default list only option)"""
|
||||||
return self._list(options_bag[-1],
|
return self._list(options_bag[-1],
|
||||||
type,
|
type,
|
||||||
group_type,
|
group_type,
|
||||||
|
@ -804,10 +804,9 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig):
|
||||||
clearable: str="all",
|
clearable: str="all",
|
||||||
remotable: str="minimum",
|
remotable: str="minimum",
|
||||||
):
|
):
|
||||||
root = self._option_bag.option.impl_getpath()
|
config = self._config_bag.context
|
||||||
config = self._option_bag.config_bag.context
|
|
||||||
self._tiramisu_dict = TiramisuDict(self._return_config(config),
|
self._tiramisu_dict = TiramisuDict(self._return_config(config),
|
||||||
root=root,
|
root=self._path,
|
||||||
clearable=clearable,
|
clearable=clearable,
|
||||||
remotable=remotable)
|
remotable=remotable)
|
||||||
|
|
||||||
|
@ -1098,14 +1097,15 @@ class TiramisuContextProperty(TiramisuConfig):
|
||||||
else:
|
else:
|
||||||
raise ValueError(_('unknown type {}').format(type))
|
raise ValueError(_('unknown type {}').format(type))
|
||||||
|
|
||||||
def getdefault(self,
|
def default(self,
|
||||||
type: Optional[str]=None,
|
type: Optional[str]=None,
|
||||||
when: Optional[str]=None,
|
when: Optional[str]=None,
|
||||||
) -> Set[str]:
|
) -> Set[str]:
|
||||||
setting = self._config_bag.context.get_settings()
|
setting = self._config_bag.context.get_settings()
|
||||||
if type is None and when is None:
|
if type is None and when is None:
|
||||||
return setting.default_properties
|
return setting.default_properties
|
||||||
|
if type == 'current':
|
||||||
|
return setting.get_context_properties(self._config_bag.context.properties_cache)
|
||||||
if when not in ['append', 'remove']:
|
if when not in ['append', 'remove']:
|
||||||
raise ValueError(_('unknown when {} (must be in append or remove)').format(when))
|
raise ValueError(_('unknown when {} (must be in append or remove)').format(when))
|
||||||
if type == 'read_only':
|
if type == 'read_only':
|
||||||
|
@ -1448,7 +1448,7 @@ class TiramisuAPI(TiramisuHelp):
|
||||||
# del config_bag.permissives
|
# del config_bag.permissives
|
||||||
return self._registers[subfunc](config_bag,
|
return self._registers[subfunc](config_bag,
|
||||||
self._orig_config_bags)
|
self._orig_config_bags)
|
||||||
raise ConfigError(_('please specify a valid sub function ({})').format(subfunc))
|
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
|
||||||
|
|
||||||
def __dir__(self):
|
def __dir__(self):
|
||||||
return list(self._registers.keys()) + \
|
return list(self._registers.keys()) + \
|
||||||
|
@ -1568,7 +1568,8 @@ class MixConfig(TiramisuAPI):
|
||||||
permissives = settings.get_context_permissives()
|
permissives = settings.get_context_permissives()
|
||||||
config_bag = ConfigBag(config,
|
config_bag = ConfigBag(config,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
permissives=permissives)
|
permissives=permissives,
|
||||||
|
)
|
||||||
super().__init__(config_bag)
|
super().__init__(config_bag)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -321,6 +321,7 @@ class _SubConfig:
|
||||||
group_type=None,
|
group_type=None,
|
||||||
recursive: bool=True,
|
recursive: bool=True,
|
||||||
walked: bool=False,
|
walked: bool=False,
|
||||||
|
flatten_leadership: bool=False,
|
||||||
):
|
):
|
||||||
"""walk to tree
|
"""walk to tree
|
||||||
"""
|
"""
|
||||||
|
@ -334,7 +335,7 @@ class _SubConfig:
|
||||||
if not recursive:
|
if not recursive:
|
||||||
# it's not recursive, so stop to walk
|
# it's not recursive, so stop to walk
|
||||||
return
|
return
|
||||||
if not option_bag.option.impl_is_leadership():
|
if not option_bag.option.impl_is_leadership() or flatten_leadership:
|
||||||
for opt in option_bag.option.get_children(option_bag.config_bag):
|
for opt in option_bag.option.get_children(option_bag.config_bag):
|
||||||
try:
|
try:
|
||||||
yield from self.walk(self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
yield from self.walk(self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
||||||
|
|
|
@ -10,16 +10,9 @@ from . import SynDynOption, RegexpOption, ChoiceOption, ParamOption
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
TYPES = {'SymLinkOption': 'symlink',
|
CONVERT_WEB_TYPE = {'bool': 'boolean',
|
||||||
'IntOption': 'integer',
|
'str': 'string',
|
||||||
'FloatOption': 'integer',
|
'int': 'integer',
|
||||||
'ChoiceOption': 'choice',
|
|
||||||
'BoolOption': 'boolean',
|
|
||||||
'PasswordOption': 'password',
|
|
||||||
'PortOption': 'integer',
|
|
||||||
'DateOption': 'date',
|
|
||||||
'DomainnameOption': 'domainname',
|
|
||||||
'StrOption': 'string'
|
|
||||||
}
|
}
|
||||||
INPUTS = ['string',
|
INPUTS = ['string',
|
||||||
'integer',
|
'integer',
|
||||||
|
@ -48,16 +41,16 @@ class Callbacks(object):
|
||||||
childapi,
|
childapi,
|
||||||
schema,
|
schema,
|
||||||
force_store_value):
|
force_store_value):
|
||||||
if self.remotable == 'all' or childapi.option.isoptiondescription():
|
if self.remotable == 'all' or childapi.isoptiondescription():
|
||||||
return
|
return
|
||||||
# callback, callback_params = childapi.option.callbacks()
|
# callback, callback_params = childapi.callbacks()
|
||||||
# if callback is None: # FIXME ? and force_store_value and self.clearable != 'all':
|
# if callback is None: # FIXME ? and force_store_value and self.clearable != 'all':
|
||||||
# return
|
# return
|
||||||
# self.callbacks.append((callback, callback_params, path, childapi, schema, force_store_value))
|
# self.callbacks.append((callback, callback_params, path, childapi, schema, force_store_value))
|
||||||
|
|
||||||
def process_properties(self, form):
|
def process_properties(self, form):
|
||||||
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
|
for callback, callback_params, path, childapi, schema, force_store_value in self.callbacks:
|
||||||
if childapi.option.isfollower():
|
if childapi.isfollower():
|
||||||
self.tiramisu_web.set_remotable(path, form, childapi)
|
self.tiramisu_web.set_remotable(path, form, childapi)
|
||||||
continue
|
continue
|
||||||
has_option = False
|
has_option = False
|
||||||
|
@ -65,10 +58,10 @@ class Callbacks(object):
|
||||||
for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
|
for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
|
||||||
if isinstance(callback_param, ParamOption):
|
if isinstance(callback_param, ParamOption):
|
||||||
has_option = True
|
has_option = True
|
||||||
if 'expire' in childapi.option.properties():
|
if 'expire' in childapi.properties():
|
||||||
self.tiramisu_web.set_remotable(callback_param.option.impl_getpath(), form)
|
self.tiramisu_web.set_remotable(callback_param.impl_getpath(), form)
|
||||||
if not has_option and form.get(path, {}).get('remote', False) == False:
|
if not has_option and form.get(path, {}).get('remote', False) == False:
|
||||||
if 'expire' in childapi.option.properties():
|
if 'expire' in childapi.properties():
|
||||||
self.tiramisu_web.set_remotable(path, form, childapi)
|
self.tiramisu_web.set_remotable(path, form, childapi)
|
||||||
elif childapi.owner.isdefault():
|
elif childapi.owner.isdefault():
|
||||||
# get calculated value and set clearable
|
# get calculated value and set clearable
|
||||||
|
@ -82,7 +75,7 @@ class Callbacks(object):
|
||||||
# if callback_params is not None:
|
# if callback_params is not None:
|
||||||
# for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
|
# for callback_param in chain(callback_params.args, callback_params.kwargs.values()):
|
||||||
# if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
|
# if isinstance(callback_param, ParamOption) and callback.__name__ == 'tiramisu_copy':
|
||||||
# opt_path = callback_param.option.impl_getpath()
|
# opt_path = callback_param.impl_getpath()
|
||||||
# if form.get(opt_path, {}).get('remote') is not True:
|
# if form.get(opt_path, {}).get('remote') is not True:
|
||||||
# form.setdefault(opt_path, {})
|
# form.setdefault(opt_path, {})
|
||||||
# form[opt_path].setdefault('copy', []).append(path)
|
# form[opt_path].setdefault('copy', []).append(path)
|
||||||
|
@ -100,8 +93,8 @@ class Consistencies(object):
|
||||||
|
|
||||||
def add(self, path, childapi, form):
|
def add(self, path, childapi, form):
|
||||||
return
|
return
|
||||||
if not childapi.option.isoptiondescription():
|
if not childapi.isoptiondescription():
|
||||||
for consistency in childapi.option.consistencies():
|
for consistency in childapi.consistencies():
|
||||||
cons_id, func, all_cons_opts, params = consistency
|
cons_id, func, all_cons_opts, params = consistency
|
||||||
if func == '_cons_not_equal' and params.get('transitive', True) is True:
|
if func == '_cons_not_equal' and params.get('transitive', True) is True:
|
||||||
options_path = []
|
options_path = []
|
||||||
|
@ -141,15 +134,15 @@ class Requires(object):
|
||||||
self.action_hide = self.tiramisu_web.config._config_bag.properties
|
self.action_hide = self.tiramisu_web.config._config_bag.properties
|
||||||
|
|
||||||
def set_master_remote(self, childapi, path, form):
|
def set_master_remote(self, childapi, path, form):
|
||||||
if childapi.option.isoptiondescription():
|
if childapi.isoptiondescription():
|
||||||
isfollower = False
|
isfollower = False
|
||||||
else:
|
else:
|
||||||
isfollower = childapi.option.isfollower()
|
isfollower = childapi.isfollower()
|
||||||
if isfollower:
|
if isfollower:
|
||||||
parent_path = path.rsplit('.', 1)[0]
|
parent_path = path.rsplit('.', 1)[0]
|
||||||
parent = self.tiramisu_web.config.unrestraint.option(parent_path)
|
parent = self.tiramisu_web.config.unrestraint.option(parent_path)
|
||||||
leader = parent.list()[0]
|
leader = parent.list()[0]
|
||||||
self.tiramisu_web.set_remotable(leader.option.path(), form, leader)
|
self.tiramisu_web.set_remotable(leader.path(), form, leader)
|
||||||
|
|
||||||
def manage_requires(self,
|
def manage_requires(self,
|
||||||
childapi,
|
childapi,
|
||||||
|
@ -157,7 +150,7 @@ class Requires(object):
|
||||||
form,
|
form,
|
||||||
current_action,
|
current_action,
|
||||||
):
|
):
|
||||||
for requires in childapi.option.properties(uncalculated=True):
|
for requires in childapi.properties(uncalculated=True):
|
||||||
if not isinstance(requires, str):
|
if not isinstance(requires, str):
|
||||||
option = requires.params.kwargs['condition'].option
|
option = requires.params.kwargs['condition'].option
|
||||||
expected = [requires.params.kwargs['expected'].value]
|
expected = [requires.params.kwargs['expected'].value]
|
||||||
|
@ -210,9 +203,9 @@ class Requires(object):
|
||||||
if isinstance(option, ChoiceOption):
|
if isinstance(option, ChoiceOption):
|
||||||
require_option = self.tiramisu_web.config.unrestraint.option(option_path)
|
require_option = self.tiramisu_web.config.unrestraint.option(option_path)
|
||||||
values = self.tiramisu_web.get_enum(require_option,
|
values = self.tiramisu_web.get_enum(require_option,
|
||||||
require_option.option.ismulti(),
|
require_option.ismulti(),
|
||||||
option_path,
|
option_path,
|
||||||
require_option.option.properties())
|
require_option.properties())
|
||||||
for value in values:
|
for value in values:
|
||||||
if value not in expected:
|
if value not in expected:
|
||||||
self.requires.setdefault(path,
|
self.requires.setdefault(path,
|
||||||
|
@ -238,7 +231,7 @@ class Requires(object):
|
||||||
|
|
||||||
def add(self, path, childapi, form):
|
def add(self, path, childapi, form):
|
||||||
#collect id of all options
|
#collect id of all options
|
||||||
child = childapi.option.get()
|
child = childapi.get()
|
||||||
if isinstance(child, SynDynOption):
|
if isinstance(child, SynDynOption):
|
||||||
child = child.opt
|
child = child.opt
|
||||||
self.options[child] = path
|
self.options[child] = path
|
||||||
|
@ -247,7 +240,8 @@ class Requires(object):
|
||||||
self.manage_requires(childapi,
|
self.manage_requires(childapi,
|
||||||
path,
|
path,
|
||||||
form,
|
form,
|
||||||
current_action)
|
current_action,
|
||||||
|
)
|
||||||
|
|
||||||
def process(self, form):
|
def process(self, form):
|
||||||
dependencies = {}
|
dependencies = {}
|
||||||
|
@ -337,15 +331,15 @@ class TiramisuDict:
|
||||||
obj['help'] = hlp
|
obj['help'] = hlp
|
||||||
|
|
||||||
def get_list(self, root, subchildapi):
|
def get_list(self, root, subchildapi):
|
||||||
ret = []
|
#ret = []
|
||||||
for childapi in subchildapi.list('all'):
|
for childapi in subchildapi.list('all'):
|
||||||
childname = childapi.option.name()
|
childname = childapi.name()
|
||||||
if root is None:
|
if root is None:
|
||||||
path = childname
|
path = childname
|
||||||
else:
|
else:
|
||||||
path = root + '.' + childname
|
path = root + '.' + childname
|
||||||
ret.append((path, childapi))
|
yield (path, childapi)
|
||||||
return ret
|
#return ret
|
||||||
|
|
||||||
def is_remote(self, path, form):
|
def is_remote(self, path, form):
|
||||||
if self.remotable == 'all':
|
if self.remotable == 'all':
|
||||||
|
@ -359,11 +353,11 @@ class TiramisuDict:
|
||||||
form.setdefault(path, {})['remote'] = True
|
form.setdefault(path, {})['remote'] = True
|
||||||
if childapi is None:
|
if childapi is None:
|
||||||
childapi = self.config.unrestraint.option(path)
|
childapi = self.config.unrestraint.option(path)
|
||||||
if childapi.option.isfollower():
|
if childapi.isfollower():
|
||||||
parent_path = path.rsplit('.', 1)[0]
|
parent_path = path.rsplit('.', 1)[0]
|
||||||
parent = self.config.unrestraint.option(parent_path)
|
parent = self.config.unrestraint.option(parent_path)
|
||||||
leader = parent.list()[0]
|
leader = parent.list()[0]
|
||||||
form.setdefault(leader.option.path(), {})['remote'] = True
|
form.setdefault(leader.path(), {})['remote'] = True
|
||||||
|
|
||||||
def walk(self,
|
def walk(self,
|
||||||
root,
|
root,
|
||||||
|
@ -391,13 +385,16 @@ class TiramisuDict:
|
||||||
subchildapi = self.config.unrestraint.option(root)
|
subchildapi = self.config.unrestraint.option(root)
|
||||||
isleadership = False
|
isleadership = False
|
||||||
else:
|
else:
|
||||||
isleadership = subchildapi.option.isleadership()
|
isleadership = subchildapi.isleadership()
|
||||||
leader_len = None
|
leader_len = None
|
||||||
for path, childapi in self.get_list(root, subchildapi):
|
for path, childapi in self.get_list(root, subchildapi):
|
||||||
if isleadership and leader_len is None:
|
if isleadership and leader_len is None:
|
||||||
leader_len = childapi.value.len()
|
leader_len = childapi.value.len()
|
||||||
one_is_remote = False
|
one_is_remote = False
|
||||||
props_no_requires = set(childapi.option.properties())
|
if not childapi.isoptiondescription() and childapi.isfollower():
|
||||||
|
props_no_requires = set()
|
||||||
|
else:
|
||||||
|
props_no_requires = set(childapi.properties())
|
||||||
if form is not None:
|
if form is not None:
|
||||||
self.requires.add(path,
|
self.requires.add(path,
|
||||||
childapi,
|
childapi,
|
||||||
|
@ -412,8 +409,7 @@ class TiramisuDict:
|
||||||
schema,
|
schema,
|
||||||
'force_store_value' in props_no_requires,
|
'force_store_value' in props_no_requires,
|
||||||
)
|
)
|
||||||
childapi_option = childapi.option
|
if model is not None and childapi.isoptiondescription() or not childapi.issymlinkoption():
|
||||||
if model is not None and childapi.option.isoptiondescription() or not childapi_option.issymlinkoption():
|
|
||||||
self.gen_model(model,
|
self.gen_model(model,
|
||||||
childapi,
|
childapi,
|
||||||
path,
|
path,
|
||||||
|
@ -422,9 +418,9 @@ class TiramisuDict:
|
||||||
)
|
)
|
||||||
if order is not None:
|
if order is not None:
|
||||||
order.append(path)
|
order.append(path)
|
||||||
if childapi.option.isoptiondescription():
|
if childapi.isoptiondescription():
|
||||||
web_type = 'optiondescription'
|
web_type = 'optiondescription'
|
||||||
if childapi_option.isleadership():
|
if childapi.isleadership():
|
||||||
type_ = 'array'
|
type_ = 'array'
|
||||||
else:
|
else:
|
||||||
type_ = 'object'
|
type_ = 'object'
|
||||||
|
@ -443,33 +439,32 @@ class TiramisuDict:
|
||||||
updates_status,
|
updates_status,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
child = childapi_option.get()
|
child = childapi.get()
|
||||||
childtype = child.__class__.__name__
|
childtype = child.__class__.__name__
|
||||||
if childtype == 'SynDynOption':
|
if childtype == 'SynDynOption':
|
||||||
childtype = child.opt.__class__.__name__
|
childtype = child.opt.__class__.__name__
|
||||||
if childapi_option.issymlinkoption():
|
if childapi.issymlinkoption():
|
||||||
web_type = 'symlink'
|
web_type = 'symlink'
|
||||||
value = None
|
value = None
|
||||||
defaultmulti = None
|
defaultmulti = None
|
||||||
is_multi = False
|
is_multi = False
|
||||||
else:
|
else:
|
||||||
web_type = childapi_option.type()
|
web_type = childapi.get().__class__.__name__.lower()[:-6]
|
||||||
value = childapi.option.default()
|
web_type = CONVERT_WEB_TYPE.get(web_type, web_type)
|
||||||
|
value = childapi.default()
|
||||||
if value == []:
|
if value == []:
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
is_multi = childapi_option.ismulti()
|
is_multi = childapi.ismulti()
|
||||||
if is_multi:
|
if is_multi:
|
||||||
defaultmulti = childapi_option.defaultmulti()
|
defaultmulti = childapi.defaultmulti()
|
||||||
if defaultmulti == []:
|
if defaultmulti == []:
|
||||||
defaultmulti = None
|
defaultmulti = None
|
||||||
else:
|
else:
|
||||||
defaultmulti = None
|
defaultmulti = None
|
||||||
|
|
||||||
if schema is not None:
|
if schema is not None:
|
||||||
self.gen_schema(schema,
|
self.gen_schema(schema,
|
||||||
childapi,
|
childapi,
|
||||||
childapi_option,
|
|
||||||
path,
|
path,
|
||||||
props_no_requires,
|
props_no_requires,
|
||||||
value,
|
value,
|
||||||
|
@ -483,12 +478,12 @@ class TiramisuDict:
|
||||||
web_type,
|
web_type,
|
||||||
path,
|
path,
|
||||||
child,
|
child,
|
||||||
childapi_option,
|
childapi,
|
||||||
childtype,
|
childtype,
|
||||||
)
|
)
|
||||||
if schema is not None:
|
if schema is not None:
|
||||||
if web_type != 'symlink':
|
if web_type != 'symlink':
|
||||||
schema[path]['title'] = childapi_option.description()
|
schema[path]['title'] = childapi.description()
|
||||||
self.add_help(schema[path],
|
self.add_help(schema[path],
|
||||||
childapi)
|
childapi)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
@ -513,7 +508,6 @@ class TiramisuDict:
|
||||||
def gen_schema(self,
|
def gen_schema(self,
|
||||||
schema,
|
schema,
|
||||||
childapi,
|
childapi,
|
||||||
childapi_option,
|
|
||||||
path,
|
path,
|
||||||
props_no_requires,
|
props_no_requires,
|
||||||
value,
|
value,
|
||||||
|
@ -523,8 +517,8 @@ class TiramisuDict:
|
||||||
form,
|
form,
|
||||||
):
|
):
|
||||||
schema[path] = {'type': web_type}
|
schema[path] = {'type': web_type}
|
||||||
if childapi_option.issymlinkoption():
|
if childapi.issymlinkoption():
|
||||||
sym_option = childapi_option.get()
|
sym_option = childapi.get()
|
||||||
schema[path]['opt_path'] = sym_option.impl_getopt().impl_getpath()
|
schema[path]['opt_path'] = sym_option.impl_getopt().impl_getpath()
|
||||||
else:
|
else:
|
||||||
if defaultmulti is not None:
|
if defaultmulti is not None:
|
||||||
|
@ -533,7 +527,7 @@ class TiramisuDict:
|
||||||
if is_multi:
|
if is_multi:
|
||||||
schema[path]['isMulti'] = is_multi
|
schema[path]['isMulti'] = is_multi
|
||||||
|
|
||||||
if childapi_option.issubmulti():
|
if childapi.issubmulti():
|
||||||
schema[path]['isSubMulti'] = True
|
schema[path]['isSubMulti'] = True
|
||||||
|
|
||||||
if 'auto_freeze' in props_no_requires:
|
if 'auto_freeze' in props_no_requires:
|
||||||
|
@ -561,7 +555,7 @@ class TiramisuDict:
|
||||||
props_no_requires,
|
props_no_requires,
|
||||||
):
|
):
|
||||||
values = childapi.value.list()
|
values = childapi.value.list()
|
||||||
empty_is_required = not childapi.option.isfollower() and is_multi
|
empty_is_required = not childapi.isfollower() and is_multi
|
||||||
if '' not in values and ((empty_is_required and not 'empty' in props_no_requires) or \
|
if '' not in values and ((empty_is_required and not 'empty' in props_no_requires) or \
|
||||||
(not empty_is_required and not 'mandatory' in props_no_requires)):
|
(not empty_is_required and not 'mandatory' in props_no_requires)):
|
||||||
values = [''] + list(values)
|
values = [''] + list(values)
|
||||||
|
@ -572,13 +566,13 @@ class TiramisuDict:
|
||||||
web_type,
|
web_type,
|
||||||
path,
|
path,
|
||||||
child,
|
child,
|
||||||
childapi_option,
|
childapi,
|
||||||
childtype,
|
childtype,
|
||||||
):
|
):
|
||||||
obj_form = {}
|
obj_form = {}
|
||||||
if path in form:
|
if path in form:
|
||||||
obj_form.update(form[path])
|
obj_form.update(form[path])
|
||||||
if not childapi_option.issymlinkoption():
|
if not childapi.issymlinkoption():
|
||||||
#if childapi_option.validator() != (None, None):
|
#if childapi_option.validator() != (None, None):
|
||||||
# obj_form['remote'] = True
|
# obj_form['remote'] = True
|
||||||
# params = childapi_option.validator()[1]
|
# params = childapi_option.validator()[1]
|
||||||
|
@ -590,14 +584,14 @@ class TiramisuDict:
|
||||||
obj_form['clearable'] = True
|
obj_form['clearable'] = True
|
||||||
if self.clearable != 'none':
|
if self.clearable != 'none':
|
||||||
obj_form['clearable'] = True
|
obj_form['clearable'] = True
|
||||||
if self.remotable == 'all' or childapi_option.has_dependency():
|
if self.remotable == 'all' or childapi.has_dependency():
|
||||||
obj_form['remote'] = True
|
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')):
|
if childtype == 'IPOption' and (child.impl_get_extra('_private_only') or not child.impl_get_extra('_allow_reserved') or child.impl_get_extra('_cidr')):
|
||||||
obj_form['remote'] = True
|
obj_form['remote'] = True
|
||||||
if childtype == 'DateOption':
|
if childtype == 'DateOption':
|
||||||
obj_form['remote'] = True
|
obj_form['remote'] = True
|
||||||
if not obj_form.get('remote', False):
|
if not obj_form.get('remote', False):
|
||||||
pattern = childapi_option.pattern()
|
pattern = childapi.pattern()
|
||||||
if pattern is not None:
|
if pattern is not None:
|
||||||
obj_form['pattern'] = pattern
|
obj_form['pattern'] = pattern
|
||||||
if childtype == 'PortOption':
|
if childtype == 'PortOption':
|
||||||
|
@ -619,10 +613,11 @@ class TiramisuDict:
|
||||||
old_properties = childapi._config_bag.properties
|
old_properties = childapi._config_bag.properties
|
||||||
config = childapi._config_bag.context
|
config = childapi._config_bag.context
|
||||||
settings = config.get_settings()
|
settings = config.get_settings()
|
||||||
childapi._config_bag.properties = self.config.property.get(default=True) # settings.get_context_properties(config._impl_properties_cache)
|
childapi._config_bag.properties = self.config.property.default('current') # settings.get_context_properties(config._impl_properties_cache)
|
||||||
childapi._config_bag.properties -= {'permissive'}
|
childapi._config_bag.properties -= {'permissive'}
|
||||||
properties = childapi.property.get(only_raises=True,
|
properties = childapi.property.get(only_raises=True,
|
||||||
uncalculated=True)
|
uncalculated=True,
|
||||||
|
)
|
||||||
properties -= childapi.permissive.get()
|
properties -= childapi.permissive.get()
|
||||||
# 'hidden=True' means cannot access with or without permissive option
|
# 'hidden=True' means cannot access with or without permissive option
|
||||||
# 'display=False' means cannot access only without permissive option
|
# 'display=False' means cannot access only without permissive option
|
||||||
|
@ -638,11 +633,11 @@ class TiramisuDict:
|
||||||
path,
|
path,
|
||||||
index,
|
index,
|
||||||
):
|
):
|
||||||
isfollower = childapi.option.isfollower()
|
isfollower = childapi.isfollower()
|
||||||
props = set(childapi.property.get())
|
props = set(childapi.property.get())
|
||||||
obj = self.gen_properties(props,
|
obj = self.gen_properties(props,
|
||||||
isfollower,
|
isfollower,
|
||||||
childapi.option.ismulti(),
|
childapi.ismulti(),
|
||||||
index)
|
index)
|
||||||
self.calc_raises_properties(obj, childapi)
|
self.calc_raises_properties(obj, childapi)
|
||||||
return obj
|
return obj
|
||||||
|
@ -687,7 +682,7 @@ class TiramisuDict:
|
||||||
leader_len,
|
leader_len,
|
||||||
updates_status,
|
updates_status,
|
||||||
):
|
):
|
||||||
if childapi.option.isoptiondescription():
|
if childapi.isoptiondescription():
|
||||||
props = set(childapi.property.get())
|
props = set(childapi.property.get())
|
||||||
obj = {}
|
obj = {}
|
||||||
self.calc_raises_properties(obj, childapi)
|
self.calc_raises_properties(obj, childapi)
|
||||||
|
@ -696,7 +691,7 @@ class TiramisuDict:
|
||||||
lprops.sort()
|
lprops.sort()
|
||||||
obj['properties'] = lprops
|
obj['properties'] = lprops
|
||||||
try:
|
try:
|
||||||
self.config.option(path).option.get()
|
self.config.option(path).get()
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -704,7 +699,7 @@ class TiramisuDict:
|
||||||
path,
|
path,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if childapi.option.isfollower():
|
if childapi.isfollower():
|
||||||
for index in range(leader_len):
|
for index in range(leader_len):
|
||||||
follower_childapi = self.config.unrestraint.option(path, index)
|
follower_childapi = self.config.unrestraint.option(path, index)
|
||||||
sobj = self._gen_model_properties(follower_childapi,
|
sobj = self._gen_model_properties(follower_childapi,
|
||||||
|
@ -727,7 +722,7 @@ class TiramisuDict:
|
||||||
updates_status,
|
updates_status,
|
||||||
)
|
)
|
||||||
if obj:
|
if obj:
|
||||||
if not childapi.option.isoptiondescription() and childapi.option.isfollower():
|
if not childapi.isoptiondescription() and childapi.isfollower():
|
||||||
model.setdefault(path, {})['null'] = obj
|
model.setdefault(path, {})['null'] = obj
|
||||||
else:
|
else:
|
||||||
model[path] = obj
|
model[path] = obj
|
||||||
|
@ -829,9 +824,9 @@ class TiramisuDict:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def del_value(self, childapi, path, index):
|
def del_value(self, childapi, path, index):
|
||||||
if index is not None and childapi.option.isleader():
|
if index is not None and childapi.isleader():
|
||||||
childapi.value.pop(index)
|
childapi.value.pop(index)
|
||||||
elif index is None or childapi.option.isfollower():
|
elif index is None or childapi.isfollower():
|
||||||
childapi.value.reset()
|
childapi.value.reset()
|
||||||
else:
|
else:
|
||||||
multi = childapi.value.get()
|
multi = childapi.value.get()
|
||||||
|
@ -844,7 +839,7 @@ class TiramisuDict:
|
||||||
childapi.value.set(multi)
|
childapi.value.set(multi)
|
||||||
|
|
||||||
def mod_value(self, childapi, path, index, value):
|
def mod_value(self, childapi, path, index, value):
|
||||||
if index is None or childapi.option.isfollower():
|
if index is None or childapi.isfollower():
|
||||||
childapi.value.set(value)
|
childapi.value.set(value)
|
||||||
else:
|
else:
|
||||||
multi = childapi.value.get()
|
multi = childapi.value.get()
|
||||||
|
@ -866,8 +861,7 @@ class TiramisuDict:
|
||||||
if oripath is not None and not path.startswith(oripath):
|
if oripath is not None and not path.startswith(oripath):
|
||||||
raise ValueError(_('not in current area'))
|
raise ValueError(_('not in current area'))
|
||||||
childapi = self.config.option(path)
|
childapi = self.config.option(path)
|
||||||
childapi_option = childapi.option
|
if childapi.isfollower():
|
||||||
if childapi_option.isfollower():
|
|
||||||
childapi = self.config.option(path, index)
|
childapi = self.config.option(path, index)
|
||||||
with warnings.catch_warnings(record=True) as warns:
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
try:
|
try:
|
||||||
|
@ -883,7 +877,7 @@ class TiramisuDict:
|
||||||
index,
|
index,
|
||||||
)
|
)
|
||||||
elif update['action'] == 'add':
|
elif update['action'] == 'add':
|
||||||
if childapi_option.ismulti():
|
if childapi.ismulti():
|
||||||
self.add_value(childapi, path, update['value'])
|
self.add_value(childapi, path, update['value'])
|
||||||
else:
|
else:
|
||||||
raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path))
|
raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path))
|
||||||
|
|
Loading…
Reference in a new issue