From 50f0f676298c540bc61e8ea0c7f85724d8701e69 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Mon, 19 Jun 2023 17:19:07 +0200 Subject: [PATCH] todict for tiramisu 4 --- AUTHORS | 2 +- tests/dict/data/choice1_requires.py | 2 +- tests/dict/data/unicode1.dict | 4 +- tests/dict/data/unicode1.dict1 | 4 +- .../dict/data/unicode1_leadership_requires.py | 2 +- .../data/unicode1_leadership_requires_all.py | 2 +- ...ode1_leadership_requires_disabled_value.py | 2 +- .../unicode1_leadership_requires_follower.py | 2 +- ...ode1_leadership_requires_follower_value.py | 2 +- .../unicode1_leadership_requires_followers.py | 2 +- .../unicode1_leadership_requires_value.py | 2 +- .../dict/data/unicode1_leadership_value.dict | 20 ++- .../dict/data/unicode1_leadership_value.dict1 | 20 ++- .../dict/data/unicode1_leadership_value.dict2 | 14 +- .../dict/data/unicode1_leadership_value.dict3 | 26 +++- .../dict/data/unicode1_leadership_value.dict4 | 26 +++- .../dict/data/unicode1_leadership_value.dict5 | 20 ++- .../dict/data/unicode1_leadership_value.dict6 | 20 ++- tests/dict/data/unicode1_mod_value.dict | 4 +- tests/dict/data/unicode1_mod_value.dict1 | 4 +- tests/dict/data/unicode1_mod_value.dict2 | 4 +- tests/dict/data/unicode1_multi.dict | 4 +- tests/dict/data/unicode1_multi.dict1 | 6 +- tests/dict/data/unicode1_multi_mod_value.dict | 8 +- .../dict/data/unicode1_multi_mod_value.dict1 | 7 +- .../dict/data/unicode1_multi_mod_value.dict2 | 8 +- tests/dict/data/unicode1_multi_requires.py | 2 +- .../unicode1_optiondescription_requires.py | 2 +- tests/dict/data/unicode1_requires.py | 2 +- tests/dict/test_json.py | 55 ++++--- tests/test_leadership.py | 3 +- tests/test_option_setting.py | 104 +++++++------ tiramisu/api.py | 55 +++---- tiramisu/config.py | 3 +- tiramisu/todict.py | 144 +++++++++--------- 35 files changed, 361 insertions(+), 226 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1410fed..602adc7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,7 +1,7 @@ Authors -------- -Emmanuel Garette lead developer +Emmanuel Garette lead developer Gwenaël Rémond developer Daniel Dehennin contributor diff --git a/tests/dict/data/choice1_requires.py b/tests/dict/data/choice1_requires.py index b62bb20..9fc013d 100644 --- a/tests/dict/data/choice1_requires.py +++ b/tests/dict/data/choice1_requires.py @@ -6,7 +6,7 @@ def get_description(): option1 = ChoiceOption('choice', "Choice description", ("hide", "show"), default='hide', properties=('mandatory',)) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('hide')})) option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,)) descr1 = OptionDescription("options", "Common configuration", [option1, option2]) diff --git a/tests/dict/data/unicode1.dict b/tests/dict/data/unicode1.dict index ba0b015..3235915 100644 --- a/tests/dict/data/unicode1.dict +++ b/tests/dict/data/unicode1.dict @@ -1 +1,3 @@ -{"options.unicode": null} +{ + "options.unicode": null +} \ No newline at end of file diff --git a/tests/dict/data/unicode1.dict1 b/tests/dict/data/unicode1.dict1 index 674e06e..988b2eb 100644 --- a/tests/dict/data/unicode1.dict1 +++ b/tests/dict/data/unicode1.dict1 @@ -1 +1,3 @@ -{"options.unicode": "val"} +{ + "options.unicode": "val" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_requires.py b/tests/dict/data/unicode1_leadership_requires.py index b2545d7..022f644 100644 --- a/tests/dict/data/unicode1_leadership_requires.py +++ b/tests/dict/data/unicode1_leadership_requires.py @@ -8,7 +8,7 @@ def get_description(): option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option2, todict=True), + kwargs={'condition': ParamOption(option2), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True) diff --git a/tests/dict/data/unicode1_leadership_requires_all.py b/tests/dict/data/unicode1_leadership_requires_all.py index f9164f8..8be4340 100644 --- a/tests/dict/data/unicode1_leadership_requires_all.py +++ b/tests/dict/data/unicode1_leadership_requires_all.py @@ -10,7 +10,7 @@ def get_description(): option3 = StrOption('unicode3', "Unicode follower 2", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option, todict=True), + kwargs={'condition': ParamOption(option), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) descr1 = Leadership("unicode1", "Common configuration", diff --git a/tests/dict/data/unicode1_leadership_requires_disabled_value.py b/tests/dict/data/unicode1_leadership_requires_disabled_value.py index 14d2535..c5b4149 100644 --- a/tests/dict/data/unicode1_leadership_requires_disabled_value.py +++ b/tests/dict/data/unicode1_leadership_requires_disabled_value.py @@ -9,7 +9,7 @@ def get_description(): option2 = StrOption('unicode2', "Unicode follower 2", multi=True) disabled_property = Calculation(calc_value, Params(ParamValue('disabled'), - kwargs={'condition': ParamOption(option, todict=True), + kwargs={'condition': ParamOption(option), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 3", properties=(disabled_property,), multi=True) diff --git a/tests/dict/data/unicode1_leadership_requires_follower.py b/tests/dict/data/unicode1_leadership_requires_follower.py index fc2ad9e..9d01efd 100644 --- a/tests/dict/data/unicode1_leadership_requires_follower.py +++ b/tests/dict/data/unicode1_leadership_requires_follower.py @@ -8,7 +8,7 @@ def get_description(): option2 = StrOption('unicode2', "Unicode follower 1", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,)) diff --git a/tests/dict/data/unicode1_leadership_requires_follower_value.py b/tests/dict/data/unicode1_leadership_requires_follower_value.py index 1bdf200..f3a87f2 100644 --- a/tests/dict/data/unicode1_leadership_requires_follower_value.py +++ b/tests/dict/data/unicode1_leadership_requires_follower_value.py @@ -8,7 +8,7 @@ def get_description(): option2 = StrOption('unicode2', "Unicode follower 1", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,)) diff --git a/tests/dict/data/unicode1_leadership_requires_followers.py b/tests/dict/data/unicode1_leadership_requires_followers.py index 9d71d6f..97ebc92 100644 --- a/tests/dict/data/unicode1_leadership_requires_followers.py +++ b/tests/dict/data/unicode1_leadership_requires_followers.py @@ -8,7 +8,7 @@ def get_description(): option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 2'", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option2, todict=True), + kwargs={'condition': ParamOption(option2), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 2", multi=True, properties=(hidden_property,)) diff --git a/tests/dict/data/unicode1_leadership_requires_value.py b/tests/dict/data/unicode1_leadership_requires_value.py index 80bc75c..9c01581 100644 --- a/tests/dict/data/unicode1_leadership_requires_value.py +++ b/tests/dict/data/unicode1_leadership_requires_value.py @@ -9,7 +9,7 @@ def get_description(): option2 = StrOption('unicode2', "Unicode follower 2", multi=True) hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option, todict=True), + kwargs={'condition': ParamOption(option), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option3 = StrOption('unicode3', "Unicode follower 3", properties=(hidden_property,), multi=True) diff --git a/tests/dict/data/unicode1_leadership_value.dict b/tests/dict/data/unicode1_leadership_value.dict index 4bb56b9..32785e3 100644 --- a/tests/dict/data/unicode1_leadership_value.dict +++ b/tests/dict/data/unicode1_leadership_value.dict @@ -1,4 +1,16 @@ -{"options.unicode.unicode": ["val3", "val4"], - "options.unicode.unicode1": ["super1", "super2"], - "options.unicode.unicode2": ["pas test", "test"], - "options.unicode.unicode3": [null, "super"]} +{ + "options.unicode.unicode": [ + { + "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" + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict1 b/tests/dict/data/unicode1_leadership_value.dict1 index f89aef6..7279dda 100644 --- a/tests/dict/data/unicode1_leadership_value.dict1 +++ b/tests/dict/data/unicode1_leadership_value.dict1 @@ -1,4 +1,16 @@ -{"options.unicode.unicode": ["val1", "val2"], - "options.unicode.unicode1": [null, null], - "options.unicode.unicode2": ["follower2", "follower2"], - "options.unicode.unicode3": [null, null]} +{ + "options.unicode.unicode": [ + { + "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 + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict2 b/tests/dict/data/unicode1_leadership_value.dict2 index 8fbff8b..dac7c62 100644 --- a/tests/dict/data/unicode1_leadership_value.dict2 +++ b/tests/dict/data/unicode1_leadership_value.dict2 @@ -1,4 +1,10 @@ -{"options.unicode.unicode": ["val3"], - "options.unicode.unicode1": ["super1"], - "options.unicode.unicode2": ["pas test"], - "options.unicode.unicode3": [null]} +{ + "options.unicode.unicode": [ + { + "options.unicode.unicode": "val3", + "options.unicode.unicode1": "super1", + "options.unicode.unicode2": "pas test", + "options.unicode.unicode3": null + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict3 b/tests/dict/data/unicode1_leadership_value.dict3 index 9f0ea36..f689db5 100644 --- a/tests/dict/data/unicode1_leadership_value.dict3 +++ b/tests/dict/data/unicode1_leadership_value.dict3 @@ -1,4 +1,22 @@ -{"options.unicode.unicode": ["val3", "val4", "val5"], - "options.unicode.unicode1": ["super1", "super2", null], - "options.unicode.unicode2": ["pas test", "test", "follower2"], - "options.unicode.unicode3": [null, "super", null]} +{ + "options.unicode.unicode": [ + { + "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 + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict4 b/tests/dict/data/unicode1_leadership_value.dict4 index 9f0ea36..f689db5 100644 --- a/tests/dict/data/unicode1_leadership_value.dict4 +++ b/tests/dict/data/unicode1_leadership_value.dict4 @@ -1,4 +1,22 @@ -{"options.unicode.unicode": ["val3", "val4", "val5"], - "options.unicode.unicode1": ["super1", "super2", null], - "options.unicode.unicode2": ["pas test", "test", "follower2"], - "options.unicode.unicode3": [null, "super", null]} +{ + "options.unicode.unicode": [ + { + "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 + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict5 b/tests/dict/data/unicode1_leadership_value.dict5 index 0c611c8..45b41dc 100644 --- a/tests/dict/data/unicode1_leadership_value.dict5 +++ b/tests/dict/data/unicode1_leadership_value.dict5 @@ -1,4 +1,16 @@ -{"options.unicode.unicode": ["val3", "val4"], - "options.unicode.unicode1": ["super1", "super2"], - "options.unicode.unicode2": ["pas test", "follower2"], - "options.unicode.unicode3": [null, "super"]} +{ + "options.unicode.unicode": [ + { + "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" + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_leadership_value.dict6 b/tests/dict/data/unicode1_leadership_value.dict6 index 752ff14..0758bcc 100644 --- a/tests/dict/data/unicode1_leadership_value.dict6 +++ b/tests/dict/data/unicode1_leadership_value.dict6 @@ -1,4 +1,16 @@ -{"options.unicode.unicode": ["val3", "val4"], - "options.unicode.unicode1": ["super1", "super2"], - "options.unicode.unicode2": ["pas test", "test2"], - "options.unicode.unicode3": [null, "super"]} +{ + "options.unicode.unicode": [ + { + "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" + } + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_mod_value.dict b/tests/dict/data/unicode1_mod_value.dict index f28f4dc..6e2c4de 100644 --- a/tests/dict/data/unicode1_mod_value.dict +++ b/tests/dict/data/unicode1_mod_value.dict @@ -1 +1,3 @@ -{"options.unicode": "a"} +{ + "options.unicode": "a" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_mod_value.dict1 b/tests/dict/data/unicode1_mod_value.dict1 index 674e06e..988b2eb 100644 --- a/tests/dict/data/unicode1_mod_value.dict1 +++ b/tests/dict/data/unicode1_mod_value.dict1 @@ -1 +1,3 @@ -{"options.unicode": "val"} +{ + "options.unicode": "val" +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_mod_value.dict2 b/tests/dict/data/unicode1_mod_value.dict2 index ba0b015..3235915 100644 --- a/tests/dict/data/unicode1_mod_value.dict2 +++ b/tests/dict/data/unicode1_mod_value.dict2 @@ -1 +1,3 @@ -{"options.unicode": null} +{ + "options.unicode": null +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi.dict b/tests/dict/data/unicode1_multi.dict index 66a217b..415294c 100644 --- a/tests/dict/data/unicode1_multi.dict +++ b/tests/dict/data/unicode1_multi.dict @@ -1 +1,3 @@ -{"options.unicode": []} +{ + "options.unicode": [] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi.dict1 b/tests/dict/data/unicode1_multi.dict1 index 9d6b074..e9a2a8b 100644 --- a/tests/dict/data/unicode1_multi.dict1 +++ b/tests/dict/data/unicode1_multi.dict1 @@ -1 +1,5 @@ -{"options.unicode": ["val"]} +{ + "options.unicode": [ + "val" + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_mod_value.dict b/tests/dict/data/unicode1_multi_mod_value.dict index 3aa1ece..a5ef0c6 100644 --- a/tests/dict/data/unicode1_multi_mod_value.dict +++ b/tests/dict/data/unicode1_multi_mod_value.dict @@ -1 +1,7 @@ -{"options.unicode": ["c", "d", "e"]} +{ + "options.unicode": [ + "c", + "d", + "e" + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_mod_value.dict1 b/tests/dict/data/unicode1_multi_mod_value.dict1 index f572a0b..58b587a 100644 --- a/tests/dict/data/unicode1_multi_mod_value.dict1 +++ b/tests/dict/data/unicode1_multi_mod_value.dict1 @@ -1 +1,6 @@ -{"options.unicode": ["a", "b"]} +{ + "options.unicode": [ + "a", + "b" + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_mod_value.dict2 b/tests/dict/data/unicode1_multi_mod_value.dict2 index 2b794c6..9664acb 100644 --- a/tests/dict/data/unicode1_multi_mod_value.dict2 +++ b/tests/dict/data/unicode1_multi_mod_value.dict2 @@ -1 +1,7 @@ -{"options.unicode": ["c", "f", "e"]} +{ + "options.unicode": [ + "c", + "f", + "e" + ] +} \ No newline at end of file diff --git a/tests/dict/data/unicode1_multi_requires.py b/tests/dict/data/unicode1_multi_requires.py index f8c3254..655b5e4 100644 --- a/tests/dict/data/unicode1_multi_requires.py +++ b/tests/dict/data/unicode1_multi_requires.py @@ -7,7 +7,7 @@ def get_description(): option1 = StrOption('unicode1', "Value 'test' must show Unicode 2") hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,), multi=True) diff --git a/tests/dict/data/unicode1_optiondescription_requires.py b/tests/dict/data/unicode1_optiondescription_requires.py index 12216cf..de09fec 100644 --- a/tests/dict/data/unicode1_optiondescription_requires.py +++ b/tests/dict/data/unicode1_optiondescription_requires.py @@ -10,7 +10,7 @@ def get_description(): option3 = StrOption('unicode3', "Unicode 3") hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) descr2 = OptionDescription("unicode1", "OptionDescription with 2 options", [option2, option3], properties=(hidden_property,)) diff --git a/tests/dict/data/unicode1_requires.py b/tests/dict/data/unicode1_requires.py index 657a206..6027148 100644 --- a/tests/dict/data/unicode1_requires.py +++ b/tests/dict/data/unicode1_requires.py @@ -7,7 +7,7 @@ def get_description(): option1 = StrOption('unicode1', "Value 'test' must show Unicode 2") hidden_property = Calculation(calc_value, Params(ParamValue('hidden'), - kwargs={'condition': ParamOption(option1, todict=True), + kwargs={'condition': ParamOption(option1), 'expected': ParamValue('test'), 'reverse_condition': ParamValue(True)})) option2 = StrOption('unicode2', "Unicode 2", properties=(hidden_property,)) diff --git a/tests/dict/test_json.py b/tests/dict/test_json.py index dd487d3..288d105 100644 --- a/tests/dict/test_json.py +++ b/tests/dict/test_json.py @@ -23,8 +23,8 @@ def datapath(): def list_data(ext='.py'): - # if ext == '.py': - # return ['choice1_leadership_hidden.py'] +# if ext == '.py': +# return ['unicode1_leadership_requires.py'] datadir = datapath() filenames = listdir(datadir) filenames.sort() @@ -37,10 +37,11 @@ def list_data(ext='.py'): def load_config(filename, - add_extra_od=False, - remote='minimum', - clearable='minimum', - root=None): + add_extra_od=False, + remote='minimum', + clearable='minimum', + root=None, + ): modulepath = splitext(filename)[0] mod = __import__(modulepath) descr = mod.get_description() @@ -168,8 +169,9 @@ def test_jsons(filename): if debug: print(" {} (remote: {}, clearable: {})".format(filename, remote, clearable)) values = load_config(filename, - remote=remote, - clearable=clearable) + remote=remote, + clearable=clearable, + ) # if not isfile(join(datadir, modulepath + '.json')) and \ clearable == 'minimum' and \ @@ -216,6 +218,27 @@ def test_jsons(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): debug = False # debug = True @@ -311,13 +334,7 @@ def test_updates(filename_mod): dico_ori = None else: with open(join(datadir, modulepath + '.dict'), 'r') as fh: - dico_ori = loads(fh.read()) - 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 + dico_ori = loads_yml(fh, issub, modulepath) # modify config with open(join(datadir, modulepath + '.mod{}'.format(idx)), 'r') as fh: body = loads(fh.read())['body'] @@ -343,13 +360,7 @@ def test_updates(filename_mod): dico_mod = None else: with open(join(datadir, modulepath + '.dict{}'.format(idx)), 'r') as fh: - dico_mod = loads(fh.read()) - if issub: - new_dico = {} - for key, value in dico_mod.items(): - key = modulepath + '.' + key - new_dico[key] = value - dico_mod = new_dico + dico_mod = loads_yml(fh, issub, modulepath) if root is None: root_path = '' else: diff --git a/tests/test_leadership.py b/tests/test_leadership.py index e06ec63..b80bc4c 100644 --- a/tests/test_leadership.py +++ b/tests/test_leadership.py @@ -232,8 +232,9 @@ def test_leader_list(config_type): assert ret[0].name() == 'leadership' # ret = cfg.option('leadership').list('all') - assert len(ret) == 1 + assert len(ret) == 2 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.netmask_admin_eth0', 0).value.set('c') diff --git a/tests/test_option_setting.py b/tests/test_option_setting.py index 519fa88..dc84a38 100644 --- a/tests/test_option_setting.py +++ b/tests/test_option_setting.py @@ -58,29 +58,29 @@ def test_mod_read_only_write(): od1 = OptionDescription("options", "", [s]) config = Config(od1) config2 = Config(od1) - assert config.property.getdefault() == {'cache', 'validator', 'warnings'} - assert config.property.getdefault('read_only', 'append') == {'frozen', - 'disabled', - 'validator', - 'everything_frozen', - 'mandatory', - 'empty', - 'force_store_value', - } - assert config.property.getdefault('read_only', 'remove') == {'permissive', - 'hidden', - } - assert config.property.getdefault('read_write', 'append') == {'frozen', - 'disabled', - 'validator', - 'hidden', - 'force_store_value', - } - assert config.property.getdefault('read_write', 'remove') == {'permissive', - 'everything_frozen', - 'mandatory', - 'empty', - } + assert config.property.default() == {'cache', 'validator', 'warnings'} + assert config.property.default('read_only', 'append') == {'frozen', + 'disabled', + 'validator', + 'everything_frozen', + 'mandatory', + 'empty', + 'force_store_value', + } + assert config.property.default('read_only', 'remove') == {'permissive', + 'hidden', + } + assert config.property.default('read_write', 'append') == {'frozen', + 'disabled', + 'validator', + 'hidden', + 'force_store_value', + } + assert config.property.default('read_write', 'remove') == {'permissive', + 'everything_frozen', + 'mandatory', + 'empty', + } # config.property.setdefault(frozenset(['cache'])) config.property.setdefault(type='read_only', when='append', properties=frozenset(['disabled'])) @@ -94,12 +94,12 @@ def test_mod_read_only_write(): with pytest.raises(TypeError): config.property.setdefault(type='read_only', when='append', properties=['disabled']) - assert config.property.getdefault() == {'cache'} - assert config.property.getdefault('read_only', 'append') == {'disabled'} - assert config.property.getdefault('read_only', 'remove') == {'hidden'} - assert config.property.getdefault('read_write', 'append') == {'disabled', - 'hidden'} - assert config.property.getdefault('read_write', 'remove') == set([]) + assert config.property.default() == {'cache'} + assert config.property.default('read_only', 'append') == {'disabled'} + assert config.property.default('read_only', 'remove') == {'hidden'} + assert config.property.default('read_write', 'append') == {'disabled', + 'hidden'} + assert config.property.default('read_write', 'remove') == set([]) # config.property.read_only() assert config.property.get() == {'cache', 'disabled'} @@ -108,29 +108,33 @@ def test_mod_read_only_write(): config.property.read_only() assert config.property.get() == {'cache', 'disabled'} # - assert config2.property.getdefault() == {'cache', 'validator', 'warnings'} - assert config2.property.getdefault('read_only', 'append') == {'frozen', - 'disabled', - 'validator', - 'everything_frozen', - 'mandatory', - 'empty', - 'force_store_value'} - assert config2.property.getdefault('read_only', 'remove') == {'permissive', - 'hidden'} - assert config2.property.getdefault('read_write', 'append') == {'frozen', - 'disabled', - 'validator', - 'hidden', - 'force_store_value'} - assert config2.property.getdefault('read_write', 'remove') == {'permissive', - 'everything_frozen', - 'mandatory', - 'empty'} + assert config2.property.default() == {'cache', 'validator', 'warnings'} + assert config2.property.default('read_only', 'append') == {'frozen', + 'disabled', + 'validator', + 'everything_frozen', + 'mandatory', + 'empty', + 'force_store_value', + } + assert config2.property.default('read_only', 'remove') == {'permissive', + 'hidden', + } + assert config2.property.default('read_write', 'append') == {'frozen', + 'disabled', + 'validator', + 'hidden', + 'force_store_value', + } + assert config2.property.default('read_write', 'remove') == {'permissive', + 'everything_frozen', + 'mandatory', + 'empty', + } with pytest.raises(ValueError): - config2.property.getdefault('unknown', 'remove') + config2.property.default('unknown', 'remove') with pytest.raises(ValueError): - config2.property.getdefault('read_write', 'unknown') + config2.property.default('read_write', 'unknown') # assert not list_sessions() diff --git a/tiramisu/api.py b/tiramisu/api.py index 4f5ec7e..3410938 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -30,7 +30,7 @@ from .option import RegexpOption, OptionDescription, ChoiceOption from .todict import TiramisuDict -TIRAMISU_VERSION = 3 +TIRAMISU_VERSION = 4 class TiramisuHelp: @@ -166,7 +166,7 @@ class CommonTiramisuOption(CommonTiramisu): self._config_bag = config_bag 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: @@ -188,6 +188,7 @@ class _TiramisuOptionWalk: recursive=recursive, types=types, group_type=group_type, + flatten_leadership=True, ): if isinstance(option_bag, dict): for opts_bag in option_bag.values(): @@ -214,7 +215,7 @@ class _TiramisuOptionOptionDescription: """Manage option""" _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]): """Get Tiramisu option""" option_bag = options_bag[-1] @@ -277,7 +278,7 @@ class _TiramisuOptionOptionDescription: option_bag = options_bag[-1] 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, options_bag: List[OptionBag], only_raises=False, @@ -319,7 +320,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription): """Test if option is a 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]): """Test if option is a follower""" return options_bag[-1].option.impl_is_follower() @@ -362,12 +363,12 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription): type = option.get_type() if isinstance(option, RegexpOption): return option._regexp.pattern - if type == 'integer': + if type == _('integer'): # FIXME negative too! return r'^[0-9]+$' - if type == 'domainname': + if type == _('domain name'): 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 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""" _validate_properties = False - @option_type(['option', 'optiondescription', 'with_index']) + @option_type(['option', 'optiondescription', 'with_or_without_index']) def get(self, options_bag: List[OptionBag], only_raises=False, @@ -495,11 +496,10 @@ class TiramisuOptionProperty(CommonTiramisuOption): class TiramisuOptionPermissive(CommonTiramisuOption): """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]): """Get permissives value""" - option_bag = options_bag[-1] - return self._config_bag.context.get_settings().getpermissives(option_bag) + return self._config_bag.context.get_settings().getpermissives(options_bag[-1]) @option_type(['option', 'optiondescription', 'with_or_without_index']) def set(self, @@ -522,7 +522,7 @@ class TiramisuOptionPermissive(CommonTiramisuOption): class TiramisuOptionInformation(CommonTiramisuOption): """Manage option's informations""" - @option_type(['option', 'optiondescription', 'with_or_without_index']) + @option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink']) def get(self, options_bag: List[OptionBag], name: str, @@ -561,7 +561,7 @@ class TiramisuOptionInformation(CommonTiramisuOption): path=option_bag.path, ) - @option_type(['option', 'optiondescription', 'with_or_without_index']) + @option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink']) def list(self, options_bag: List[OptionBag], ) -> list: @@ -662,7 +662,7 @@ class TiramisuOptionValue(CommonTiramisuOption): return False return True - @option_type(['choice', 'with_index']) + @option_type(['choice', 'with_or_without_index']) def list(self, options_bag: List[OptionBag]): """All values available for a ChoiceOption""" option_bag = options_bag[-1] @@ -754,7 +754,7 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig): self._index, 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') def find(self, @@ -793,7 +793,7 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig): recursive=False, 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], type, group_type, @@ -804,10 +804,9 @@ class TiramisuOption(CommonTiramisu, _TiramisuOptionOption, TiramisuConfig): clearable: str="all", remotable: str="minimum", ): - root = self._option_bag.option.impl_getpath() - config = self._option_bag.config_bag.context + config = self._config_bag.context self._tiramisu_dict = TiramisuDict(self._return_config(config), - root=root, + root=self._path, clearable=clearable, remotable=remotable) @@ -1098,14 +1097,15 @@ class TiramisuContextProperty(TiramisuConfig): else: raise ValueError(_('unknown type {}').format(type)) - def getdefault(self, - type: Optional[str]=None, - when: Optional[str]=None, - ) -> Set[str]: + def default(self, + type: Optional[str]=None, + when: Optional[str]=None, + ) -> Set[str]: setting = self._config_bag.context.get_settings() if type is None and when is None: return setting.default_properties - + if type == 'current': + return setting.get_context_properties(self._config_bag.context.properties_cache) if when not in ['append', 'remove']: raise ValueError(_('unknown when {} (must be in append or remove)').format(when)) if type == 'read_only': @@ -1448,7 +1448,7 @@ class TiramisuAPI(TiramisuHelp): # del config_bag.permissives return self._registers[subfunc](config_bag, 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): return list(self._registers.keys()) + \ @@ -1568,7 +1568,8 @@ class MixConfig(TiramisuAPI): permissives = settings.get_context_permissives() config_bag = ConfigBag(config, properties=properties, - permissives=permissives) + permissives=permissives, + ) super().__init__(config_bag) diff --git a/tiramisu/config.py b/tiramisu/config.py index 165b5ad..21ffaf6 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -321,6 +321,7 @@ class _SubConfig: group_type=None, recursive: bool=True, walked: bool=False, + flatten_leadership: bool=False, ): """walk to tree """ @@ -334,7 +335,7 @@ class _SubConfig: if not recursive: # it's not recursive, so stop to walk 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): try: yield from self.walk(self.get_sub_option_bag(option_bag, # pylint: disable=no-member diff --git a/tiramisu/todict.py b/tiramisu/todict.py index c484f4a..56f922f 100644 --- a/tiramisu/todict.py +++ b/tiramisu/todict.py @@ -10,17 +10,10 @@ from . import SynDynOption, RegexpOption, ChoiceOption, ParamOption from .i18n import _ -TYPES = {'SymLinkOption': 'symlink', - 'IntOption': 'integer', - 'FloatOption': 'integer', - 'ChoiceOption': 'choice', - 'BoolOption': 'boolean', - 'PasswordOption': 'password', - 'PortOption': 'integer', - 'DateOption': 'date', - 'DomainnameOption': 'domainname', - 'StrOption': 'string' - } +CONVERT_WEB_TYPE = {'bool': 'boolean', + 'str': 'string', + 'int': 'integer', + } INPUTS = ['string', 'integer', 'filename', @@ -48,16 +41,16 @@ class Callbacks(object): childapi, schema, force_store_value): - if self.remotable == 'all' or childapi.option.isoptiondescription(): + if self.remotable == 'all' or childapi.isoptiondescription(): 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': # return # self.callbacks.append((callback, callback_params, path, childapi, schema, force_store_value)) def process_properties(self, form): 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) continue has_option = False @@ -65,10 +58,10 @@ class Callbacks(object): for callback_param in chain(callback_params.args, callback_params.kwargs.values()): if isinstance(callback_param, ParamOption): has_option = True - if 'expire' in childapi.option.properties(): - self.tiramisu_web.set_remotable(callback_param.option.impl_getpath(), form) + if 'expire' in childapi.properties(): + self.tiramisu_web.set_remotable(callback_param.impl_getpath(), form) 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) elif childapi.owner.isdefault(): # get calculated value and set clearable @@ -82,7 +75,7 @@ class Callbacks(object): # if callback_params is not None: # for callback_param in chain(callback_params.args, callback_params.kwargs.values()): # 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: # form.setdefault(opt_path, {}) # form[opt_path].setdefault('copy', []).append(path) @@ -100,8 +93,8 @@ class Consistencies(object): def add(self, path, childapi, form): return - if not childapi.option.isoptiondescription(): - for consistency in childapi.option.consistencies(): + if not childapi.isoptiondescription(): + for consistency in childapi.consistencies(): cons_id, func, all_cons_opts, params = consistency if func == '_cons_not_equal' and params.get('transitive', True) is True: options_path = [] @@ -141,15 +134,15 @@ class Requires(object): self.action_hide = self.tiramisu_web.config._config_bag.properties def set_master_remote(self, childapi, path, form): - if childapi.option.isoptiondescription(): + if childapi.isoptiondescription(): isfollower = False else: - isfollower = childapi.option.isfollower() + isfollower = childapi.isfollower() if isfollower: parent_path = path.rsplit('.', 1)[0] parent = self.tiramisu_web.config.unrestraint.option(parent_path) 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, childapi, @@ -157,7 +150,7 @@ class Requires(object): form, current_action, ): - for requires in childapi.option.properties(uncalculated=True): + for requires in childapi.properties(uncalculated=True): if not isinstance(requires, str): option = requires.params.kwargs['condition'].option expected = [requires.params.kwargs['expected'].value] @@ -210,9 +203,9 @@ class Requires(object): if isinstance(option, ChoiceOption): require_option = self.tiramisu_web.config.unrestraint.option(option_path) values = self.tiramisu_web.get_enum(require_option, - require_option.option.ismulti(), + require_option.ismulti(), option_path, - require_option.option.properties()) + require_option.properties()) for value in values: if value not in expected: self.requires.setdefault(path, @@ -238,16 +231,17 @@ class Requires(object): def add(self, path, childapi, form): #collect id of all options - child = childapi.option.get() + child = childapi.get() if isinstance(child, SynDynOption): child = child.opt self.options[child] = path current_action = None self.manage_requires(childapi, - path, - form, - current_action) + path, + form, + current_action, + ) def process(self, form): dependencies = {} @@ -337,15 +331,15 @@ class TiramisuDict: obj['help'] = hlp def get_list(self, root, subchildapi): - ret = [] + #ret = [] for childapi in subchildapi.list('all'): - childname = childapi.option.name() + childname = childapi.name() if root is None: path = childname else: path = root + '.' + childname - ret.append((path, childapi)) - return ret + yield (path, childapi) + #return ret def is_remote(self, path, form): if self.remotable == 'all': @@ -359,11 +353,11 @@ class TiramisuDict: form.setdefault(path, {})['remote'] = True if childapi is None: childapi = self.config.unrestraint.option(path) - if childapi.option.isfollower(): + if childapi.isfollower(): parent_path = path.rsplit('.', 1)[0] parent = self.config.unrestraint.option(parent_path) leader = parent.list()[0] - form.setdefault(leader.option.path(), {})['remote'] = True + form.setdefault(leader.path(), {})['remote'] = True def walk(self, root, @@ -391,13 +385,16 @@ class TiramisuDict: subchildapi = self.config.unrestraint.option(root) isleadership = False else: - isleadership = subchildapi.option.isleadership() + isleadership = subchildapi.isleadership() leader_len = None for path, childapi in self.get_list(root, subchildapi): if isleadership and leader_len is None: leader_len = childapi.value.len() 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: self.requires.add(path, childapi, @@ -412,8 +409,7 @@ class TiramisuDict: schema, 'force_store_value' in props_no_requires, ) - childapi_option = childapi.option - if model is not None and childapi.option.isoptiondescription() or not childapi_option.issymlinkoption(): + if model is not None and childapi.isoptiondescription() or not childapi.issymlinkoption(): self.gen_model(model, childapi, path, @@ -422,9 +418,9 @@ class TiramisuDict: ) if order is not None: order.append(path) - if childapi.option.isoptiondescription(): + if childapi.isoptiondescription(): web_type = 'optiondescription' - if childapi_option.isleadership(): + if childapi.isleadership(): type_ = 'array' else: type_ = 'object' @@ -443,33 +439,32 @@ class TiramisuDict: updates_status, ) else: - child = childapi_option.get() + child = childapi.get() childtype = child.__class__.__name__ if childtype == 'SynDynOption': childtype = child.opt.__class__.__name__ - if childapi_option.issymlinkoption(): + if childapi.issymlinkoption(): web_type = 'symlink' value = None defaultmulti = None is_multi = False else: - web_type = childapi_option.type() - value = childapi.option.default() + web_type = childapi.get().__class__.__name__.lower()[:-6] + web_type = CONVERT_WEB_TYPE.get(web_type, web_type) + value = childapi.default() if value == []: value = None - is_multi = childapi_option.ismulti() + is_multi = childapi.ismulti() if is_multi: - defaultmulti = childapi_option.defaultmulti() + defaultmulti = childapi.defaultmulti() if defaultmulti == []: defaultmulti = None else: defaultmulti = None - if schema is not None: self.gen_schema(schema, childapi, - childapi_option, path, props_no_requires, value, @@ -483,12 +478,12 @@ class TiramisuDict: web_type, path, child, - childapi_option, + childapi, childtype, ) if schema is not None: if web_type != 'symlink': - schema[path]['title'] = childapi_option.description() + schema[path]['title'] = childapi.description() self.add_help(schema[path], childapi) except Exception as err: @@ -513,7 +508,6 @@ class TiramisuDict: def gen_schema(self, schema, childapi, - childapi_option, path, props_no_requires, value, @@ -523,8 +517,8 @@ class TiramisuDict: form, ): schema[path] = {'type': web_type} - if childapi_option.issymlinkoption(): - sym_option = childapi_option.get() + if childapi.issymlinkoption(): + sym_option = childapi.get() schema[path]['opt_path'] = sym_option.impl_getopt().impl_getpath() else: if defaultmulti is not None: @@ -533,7 +527,7 @@ class TiramisuDict: if is_multi: schema[path]['isMulti'] = is_multi - if childapi_option.issubmulti(): + if childapi.issubmulti(): schema[path]['isSubMulti'] = True if 'auto_freeze' in props_no_requires: @@ -561,7 +555,7 @@ class TiramisuDict: props_no_requires, ): 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 \ (not empty_is_required and not 'mandatory' in props_no_requires)): values = [''] + list(values) @@ -572,13 +566,13 @@ class TiramisuDict: web_type, path, child, - childapi_option, + childapi, childtype, ): obj_form = {} if path in form: obj_form.update(form[path]) - if not childapi_option.issymlinkoption(): + if not childapi.issymlinkoption(): #if childapi_option.validator() != (None, None): # obj_form['remote'] = True # params = childapi_option.validator()[1] @@ -590,14 +584,14 @@ class TiramisuDict: obj_form['clearable'] = True if self.clearable != 'none': 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 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 if childtype == 'DateOption': obj_form['remote'] = True if not obj_form.get('remote', False): - pattern = childapi_option.pattern() + pattern = childapi.pattern() if pattern is not None: obj_form['pattern'] = pattern if childtype == 'PortOption': @@ -619,10 +613,11 @@ class TiramisuDict: old_properties = childapi._config_bag.properties config = childapi._config_bag.context 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'} properties = childapi.property.get(only_raises=True, - uncalculated=True) + uncalculated=True, + ) properties -= childapi.permissive.get() # 'hidden=True' means cannot access with or without permissive option # 'display=False' means cannot access only without permissive option @@ -638,11 +633,11 @@ class TiramisuDict: path, index, ): - isfollower = childapi.option.isfollower() + isfollower = childapi.isfollower() props = set(childapi.property.get()) obj = self.gen_properties(props, isfollower, - childapi.option.ismulti(), + childapi.ismulti(), index) self.calc_raises_properties(obj, childapi) return obj @@ -687,7 +682,7 @@ class TiramisuDict: leader_len, updates_status, ): - if childapi.option.isoptiondescription(): + if childapi.isoptiondescription(): props = set(childapi.property.get()) obj = {} self.calc_raises_properties(obj, childapi) @@ -696,7 +691,7 @@ class TiramisuDict: lprops.sort() obj['properties'] = lprops try: - self.config.option(path).option.get() + self.config.option(path).get() except PropertiesOptionError: pass else: @@ -704,7 +699,7 @@ class TiramisuDict: path, None, ) - if childapi.option.isfollower(): + if childapi.isfollower(): for index in range(leader_len): follower_childapi = self.config.unrestraint.option(path, index) sobj = self._gen_model_properties(follower_childapi, @@ -727,7 +722,7 @@ class TiramisuDict: updates_status, ) if obj: - if not childapi.option.isoptiondescription() and childapi.option.isfollower(): + if not childapi.isoptiondescription() and childapi.isfollower(): model.setdefault(path, {})['null'] = obj else: model[path] = obj @@ -829,9 +824,9 @@ class TiramisuDict: return ret 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) - elif index is None or childapi.option.isfollower(): + elif index is None or childapi.isfollower(): childapi.value.reset() else: multi = childapi.value.get() @@ -844,7 +839,7 @@ class TiramisuDict: childapi.value.set(multi) 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) else: multi = childapi.value.get() @@ -866,8 +861,7 @@ class TiramisuDict: if oripath is not None and not path.startswith(oripath): raise ValueError(_('not in current area')) childapi = self.config.option(path) - childapi_option = childapi.option - if childapi_option.isfollower(): + if childapi.isfollower(): childapi = self.config.option(path, index) with warnings.catch_warnings(record=True) as warns: try: @@ -883,7 +877,7 @@ class TiramisuDict: index, ) elif update['action'] == 'add': - if childapi_option.ismulti(): + if childapi.ismulti(): self.add_value(childapi, path, update['value']) else: raise ValueError(_('only multi option can have action "add", but "{}" is not a multi').format(path))