From 527ae40950c0b1d8f15c8872234dc2d394200520 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Thu, 23 Nov 2017 16:56:14 +0100 Subject: [PATCH] refactor --- test/api/test_owner.py | 822 ++++++++++++++++--------- tiramisu/api.py | 122 +++- tiramisu/config.py | 261 ++++---- tiramisu/error.py | 55 +- tiramisu/option/baseoption.py | 76 ++- tiramisu/option/option.py | 38 +- tiramisu/option/optiondescription.py | 135 ++-- tiramisu/option/usernameoption.py | 4 +- tiramisu/setting.py | 144 ++--- tiramisu/storage/dictionary/storage.py | 2 +- tiramisu/storage/dictionary/value.py | 33 +- tiramisu/storage/util.py | 10 +- tiramisu/value.py | 269 ++++---- 13 files changed, 1178 insertions(+), 793 deletions(-) diff --git a/test/api/test_owner.py b/test/api/test_owner.py index c300bd6..9c74c2b 100644 --- a/test/api/test_owner.py +++ b/test/api/test_owner.py @@ -8,7 +8,7 @@ from .autopath import do_autopath do_autopath() from tiramisu import Config, MetaConfig, \ StrOption, OptionDescription, MasterSlaves, DynOptionDescription, \ - getapi, submulti, undefined + getapi, submulti, undefined, owners from tiramisu.error import PropertiesOptionError, APIError, ConfigError from collections import OrderedDict ICON = u'\u2937' @@ -66,7 +66,7 @@ def autocheck(func): @autocheck -def autocheck_option_multi(api, path, **kwargs): +def autocheck_option_multi(api, path, confread, confwrite, **kwargs): if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): api.option(path).option.ismulti() api.option(path).option.issubmulti() @@ -115,53 +115,57 @@ def autocheck_option_multi(api, path, **kwargs): @autocheck -def autocheck_default_owner(api, path, **kwargs): +def autocheck_default_owner(api, path, confread, confwrite, **kwargs): """check different value of owner when any value is set to this option """ isslave = api.unrestraint.option(path).option.isslave() # check if owner is a string "default" and 'isdefault' - if not isslave: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).owner.get() == 'default' - assert api.forcepermissive.option(path).owner.get() == 'default' - # - assert api.option(path).owner.isdefault() - assert api.forcepermissive.option(path).owner.isdefault() - elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).owner.get()") - assert api.forcepermissive.option(path).owner.get() == 'default' - # - raises(PropertiesOptionError, "api.option(path).owner.isdefault()") - assert api.forcepermissive.option(path).owner.isdefault() + def do(conf): + if not isslave: + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path).owner.get() == 'default' + assert api.forcepermissive.config(conf).option(path).owner.get() == 'default' + # + assert api.config(conf).option(path).owner.isdefault() + assert api.forcepermissive.config(conf).option(path).owner.isdefault() + elif not kwargs.get('propertyerror', False): + raises(PropertiesOptionError, "api.config(conf).option(path).owner.get()") + assert api.forcepermissive.config(conf).option(path).owner.get() == 'default' + # + raises(PropertiesOptionError, "api.config(conf).option(path).owner.isdefault()") + assert api.forcepermissive.config(conf).option(path).owner.isdefault() + else: + raises(PropertiesOptionError, "api.config(conf).option(path).owner.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).owner.get()") + # + raises(PropertiesOptionError, "api.config(conf).option(path).owner.isdefault()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).owner.isdefault()") else: - raises(PropertiesOptionError, "api.option(path).owner.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.get()") - # - raises(PropertiesOptionError, "api.option(path).owner.isdefault()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.isdefault()") - else: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path, 0).owner.get() == 'default' - assert api.forcepermissive.option(path, 0).owner.get() == 'default' - # - assert api.option(path, 0).owner.isdefault() - assert api.forcepermissive.option(path, 0).owner.isdefault() - elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path, 0).owner.get()") - assert api.forcepermissive.option(path, 0).owner.get() == 'default' - # - assert api.option(path, 0).owner.isdefault() - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).owner.isdefault()") - else: - raises(PropertiesOptionError, "api.option(path, 0).owner.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).owner.get()") - # - raises(PropertiesOptionError, "api.option(path, 0).owner.isdefault()") - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).owner.isdefault()") + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path, 0).owner.get() == 'default' + assert api.forcepermissive.config(conf).option(path, 0).owner.get() == 'default' + # + assert api.config(conf).option(path, 0).owner.isdefault() + assert api.forcepermissive.config(conf).option(path, 0).owner.isdefault() + elif not kwargs.get('propertyerror', False): + raises(PropertiesOptionError, "api.config(conf).option(path, 0).owner.get()") + assert api.forcepermissive.config(conf).option(path, 0).owner.get() == 'default' + # + assert api.config(conf).option(path, 0).owner.isdefault() + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).owner.isdefault()") + else: + raises(PropertiesOptionError, "api.config(conf).option(path, 0).owner.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).owner.get()") + # + raises(PropertiesOptionError, "api.config(conf).option(path, 0).owner.isdefault()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).owner.isdefault()") - # unrestraint is not allowed - raises(APIError, "api.unrestraint.option(path).owner.get()") - raises(APIError, "api.unrestraint.option(path).owner.isdefault()") + # unrestraint is not allowed + raises(APIError, "api.unrestraint.config(conf).option(path).owner.get()") + raises(APIError, "api.unrestraint.config(conf).option(path).owner.isdefault()") + do(confread) + if confread != confwrite: + do(confwrite) def _getdefault(api, path, multi, isslave, submulti_): @@ -171,7 +175,7 @@ def _getdefault(api, path, multi, isslave, submulti_): return empty_value -def _autocheck_default_value(api, path, **kwargs): +def _autocheck_default_value(api, path, conf, **kwargs): """set and get values """ # check if is a multi, a master or a slave @@ -186,35 +190,38 @@ def _autocheck_default_value(api, path, **kwargs): # cannot test for slave (we cannot get all values for a slave) if not isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).value.get() == empty_value - assert api.forcepermissive.option(path).value.get() == empty_value + assert api.config(conf).option(path).value.get() == empty_value + assert api.forcepermissive.config(conf).option(path).value.get() == empty_value elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).value.get()") - assert api.forcepermissive.option(path).value.get() == empty_value + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + assert api.forcepermissive.config(conf).option(path).value.get() == empty_value else: - raises(PropertiesOptionError, "api.option(path).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).value.get()") + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).value.get()") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path, 0).value.get() == empty_value - assert api.option(path, 1).value.get() == empty_value - assert api.forcepermissive.option(path, 0).value.get() == empty_value - assert api.forcepermissive.option(path, 1).value.get() == empty_value + assert api.config(conf).option(path, 0).value.get() == empty_value + assert api.config(conf).option(path, 1).value.get() == empty_value + assert api.forcepermissive.config(conf).option(path, 0).value.get() == empty_value + assert api.forcepermissive.config(conf).option(path, 1).value.get() == empty_value elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - assert api.forcepermissive.option(path, 0).value.get() == empty_value - assert api.forcepermissive.option(path, 1).value.get() == empty_value + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + assert api.forcepermissive.config(conf).option(path, 0).value.get() == empty_value + assert api.forcepermissive.config(conf).option(path, 1).value.get() == empty_value else: - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).value.get()") + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).value.get()") @autocheck -def autocheck_default_value(api, path, **kwargs): - _autocheck_default_value(api, path, **kwargs) +def autocheck_default_value(api, path, confread, confwrite, **kwargs): + _autocheck_default_value(api, path, confread, **kwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **kwargs) -def _autocheck_set_value(api, path, **kwargs): + +def _autocheck_set_value(api, path, conf, **kwargs): set_permissive = kwargs.get('set_permissive', True) multi = api.unrestraint.option(path).option.ismulti() submulti_ = api.unrestraint.option(path).option.issubmulti() @@ -231,64 +238,64 @@ def _autocheck_set_value(api, path, **kwargs): # for master must append, not set if ismaster: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - raises(APIError, "api.option(path, 0).value.set(first_value[0])") + raises(APIError, "api.config(conf).option(path, 0).value.set(first_value[0])") if not set_permissive: - api.option(path).value.set([first_value[0]]) + api.config(conf).option(path).value.set([first_value[0]]) else: - api.forcepermissive.option(path).value.set([first_value[0]]) + api.forcepermissive.config(conf).option(path).value.set([first_value[0]]) elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).value.set([first_value[0]])") + raises(PropertiesOptionError, "api.config(conf).option(path).value.set([first_value[0]])") if set_permissive: - api.forcepermissive.option(path).value.set([first_value[0]]) + api.forcepermissive.config(conf).option(path).value.set([first_value[0]]) else: - raises(PropertiesOptionError, "api.option(path).value.set([first_value[0]])") + raises(PropertiesOptionError, "api.config(conf).option(path).value.set([first_value[0]])") raises(PropertiesOptionError, - "api.forcepermissive.option(path).value.set([first_value[0]])") - raises(APIError, "api.unrestraint.option(path).value.set(first_value[1])") + "api.forcepermissive.config(conf).option(path).value.set([first_value[0]])") + raises(APIError, "api.unrestraint.config(conf).option(path).value.set(first_value[1])") elif isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not set_permissive: - api.option(path, 0).value.set(first_value[0]) + api.config(conf).option(path, 0).value.set(first_value[0]) else: - api.forcepermissive.option(path, 0).value.set(first_value[0]) + api.forcepermissive.config(conf).option(path, 0).value.set(first_value[0]) elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path, 0).value.set(first_value[0])") + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.set(first_value[0])") if set_permissive: - api.forcepermissive.option(path, 0).value.set(first_value[0]) + api.forcepermissive.config(conf).option(path, 0).value.set(first_value[0]) else: - raises(PropertiesOptionError, "api.option(path, 0).value.set(first_value[0])") + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.set(first_value[0])") raises(PropertiesOptionError, - "api.forcepermissive.option(path, 0).value.set(first_value[0])") + "api.forcepermissive.config(conf).option(path, 0).value.set(first_value[0])") raises(APIError, - "api.unrestraint.option(path).value.set([first_value[0], first_value[1]])") + "api.unrestraint.config(conf).option(path).value.set([first_value[0], first_value[1]])") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not set_permissive: - api.option(path).value.set(first_value) + api.config(conf).option(path).value.set(first_value) else: - api.forcepermissive.option(path).value.set(first_value) + api.forcepermissive.config(conf).option(path).value.set(first_value) elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).value.set(first_value)") + raises(PropertiesOptionError, "api.config(conf).option(path).value.set(first_value)") if set_permissive: - api.forcepermissive.option(path).value.set(first_value) + api.forcepermissive.config(conf).option(path).value.set(first_value) else: - raises(PropertiesOptionError, "api.option(path).value.set(first_value)") - raises(PropertiesOptionError, "api.forcepermissive.option(path).value.set(first_value)") - raises(APIError, "api.unrestraint.option(path).value.set(first_value)") + raises(PropertiesOptionError, "api.config(conf).option(path).value.set(first_value)") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).value.set(first_value)") + raises(APIError, "api.unrestraint.config(conf).option(path).value.set(first_value)") @autocheck -def autocheck_set_value(api, path, **kwargs): - _autocheck_set_value(api, path, **kwargs) +def autocheck_set_value(api, path, confread, confwrite, **kwargs): + _autocheck_set_value(api, path, confwrite, **kwargs) @autocheck -def autocheck_get_value_permissive(api, path, **kwargs): +def autocheck_get_value_permissive(api, path, confread, confwrite, **kwargs): multi = api.unrestraint.option(path).option.ismulti() submulti_ = api.unrestraint.option(path).option.issubmulti() isslave = api.unrestraint.option(path).option.isslave() - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) if not multi: first_value = FIRST_VALUE elif submulti_ is False: @@ -296,30 +303,34 @@ def autocheck_get_value_permissive(api, path, **kwargs): else: first_value = SUBLIST_FIRST_VALUE - # get value after set value without permissive - if isslave: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path, 0).value.get() == first_value[0] - assert api.forcepermissive.option(path, 0).value.get() == first_value[0] - elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - assert api.forcepermissive.option(path, 0).value.get() == first_value + def do(conf): + # get value after set value without permissive + if isslave: + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path, 0).value.get() == first_value[0] + assert api.forcepermissive.config(conf).option(path, 0).value.get() == first_value[0] + elif kwargs.get('permissive', False): + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + assert api.forcepermissive.config(conf).option(path, 0).value.get() == first_value + else: + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).value.get()") else: - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).value.get()") - else: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).value.get() == first_value - assert api.forcepermissive.option(path).value.get() == first_value - elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path).value.get()") - assert api.forcepermissive.option(path).value.get() == first_value - else: - raises(PropertiesOptionError, "api.option(path).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).value.get()") + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path).value.get() == first_value + assert api.forcepermissive.config(conf).option(path).value.get() == first_value + elif kwargs.get('permissive', False): + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + assert api.forcepermissive.config(conf).option(path).value.get() == first_value + else: + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).value.get()") + do(confread) + if confread != confwrite: + do(confwrite) -def _autocheck_get_value(api, path, **kwargs): +def _autocheck_get_value(api, path, conf, **kwargs): multi = api.unrestraint.option(path).option.ismulti() submulti_ = api.unrestraint.option(path).option.issubmulti() isslave = api.unrestraint.option(path).option.isslave() @@ -334,37 +345,39 @@ def _autocheck_get_value(api, path, **kwargs): # get value after set value without permissive if isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path, 0).value.get() == first_value[0] - assert api.forcepermissive.option(path, 0).value.get() == first_value[0] + assert api.config(conf).option(path, 0).value.get() == first_value[0] + assert api.forcepermissive.config(conf).option(path, 0).value.get() == first_value[0] elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - assert api.forcepermissive.option(path, 0).value.get() == empty_value + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + assert api.forcepermissive.config(conf).option(path, 0).value.get() == empty_value else: - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path, 0).value.get()") + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path, 0).value.get()") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).value.get() == first_value - assert api.forcepermissive.option(path).value.get() == first_value + assert api.config(conf).option(path).value.get() == first_value + assert api.forcepermissive.config(conf).option(path).value.get() == first_value elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path).value.get()") - assert api.forcepermissive.option(path).value.get() == empty_value + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + assert api.forcepermissive.config(conf).option(path).value.get() == empty_value else: - raises(PropertiesOptionError, "api.option(path).value.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).value.get()") + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).value.get()") @autocheck -def autocheck_get_value(api, path, **kwargs): - _autocheck_set_value(api, path, set_permissive=False, **kwargs) - _autocheck_get_value(api, path, **kwargs) +def autocheck_get_value(api, path, confread, confwrite, **kwargs): + _autocheck_set_value(api, path, confwrite, set_permissive=False, **kwargs) + _autocheck_get_value(api, path, confread, **kwargs) + if confread != confwrite: + _autocheck_get_value(api, path, confwrite, **kwargs) @autocheck -def autocheck_value_slave(api, path, **kwargs): +def autocheck_value_slave(api, path, confread, confwrite, **kwargs): isslave = api.unrestraint.option(path).option.isslave() if not isslave: - #FIXME raises(APIError, "api.option(path).value.len()") + #FIXME raises(APIError, "api.config(confread).option(path).value.len()") return if kwargs.get('propertyerror', False): raises(PropertiesOptionError, "api.option(path).value.len()") @@ -379,15 +392,19 @@ def autocheck_value_slave(api, path, **kwargs): second_value = SUBLIST_SECOND_VALUE empty_value = _getdefault(api, path, multi, isslave, submulti_) - if not kwargs.get('permissive', False): - length = api.option(path).value.len() - assert api.forcepermissive.option(path).value.len() == length - else: - raises(PropertiesOptionError, "api.option(path).value.len()") - length = api.forcepermissive.option(path).value.len() - - assert length == 2 + def do(conf): + if not kwargs.get('permissive', False): + length = api.config(conf).option(path).value.len() + assert api.forcepermissive.config(conf).option(path).value.len() == length + else: + raises(PropertiesOptionError, "api.config(conf).option(path).value.len()") + length = api.forcepermissive.config(conf).option(path).value.len() + assert length == 2 + do(confread) + if confread != confwrite: + do(confwrite) + length = 2 value = [] for idx in range(length): value.append(api.forcepermissive.option(path, idx).value.get()) @@ -410,7 +427,7 @@ def autocheck_value_slave(api, path, **kwargs): @autocheck -def autocheck_reset_value(api, path, **kwargs): +def autocheck_reset_value(api, path, confread, confwrite, **kwargs): # check if is a multi, a master or a slave multi = api.unrestraint.option(path).option.ismulti() submulti_ = api.unrestraint.option(path).option.issubmulti() @@ -427,70 +444,81 @@ def autocheck_reset_value(api, path, **kwargs): first_value = SUBLIST_FIRST_VALUE second_value = SUBLIST_SECOND_VALUE empty_value = _getdefault(api, path, multi, isslave, submulti_) - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) # reset value without permissive if not isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path).value.reset() + api.config(confwrite).option(path).value.reset() else: - raises(PropertiesOptionError, "api.option(path).value.reset()") + raises(PropertiesOptionError, "api.config(confwrite).option(path).value.reset()") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path, 0).value.reset() + api.config(confwrite).option(path, 0).value.reset() else: - raises(PropertiesOptionError, "api.option(path, 0).value.reset()") + raises(PropertiesOptionError, "api.config(confwrite).option(path, 0).value.reset()") # get value after reset value without permissive - if isslave: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path, 0).value.get() == empty_value - assert api.option(path, 1).value.get() == second_value[1] - elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path, 0).value.get()") - assert api.forcepermissive.option(path, 0).value.get() == empty_value - assert api.forcepermissive.option(path, 1).value.get() == second_value[1] - else: - if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).value.get() == empty_value - elif kwargs.get('permissive', False): - raises(PropertiesOptionError, "api.option(path).value.get()") - assert api.forcepermissive.option(path).value.get() == first_value + def do(conf): + if isslave: + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path, 0).value.get() == empty_value + assert api.config(conf).option(path, 1).value.get() == second_value[1] + elif kwargs.get('permissive', False): + raises(PropertiesOptionError, "api.config(conf).option(path, 0).value.get()") + assert api.forcepermissive.config(conf).option(path, 0).value.get() == empty_value + assert api.forcepermissive.config(conf).option(path, 1).value.get() == second_value[1] + else: + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert api.config(conf).option(path).value.get() == empty_value + elif kwargs.get('permissive', False): + raises(PropertiesOptionError, "api.config(conf).option(path).value.get()") + assert api.forcepermissive.config(conf).option(path).value.get() == first_value + do(confread) + if confread != confwrite: + do(confwrite) @autocheck -def autocheck_reset_value_permissive(api, path, **kwargs): +def autocheck_reset_value_permissive(api, path, confread, confwrite, **kwargs): # check if is a multi, a master or a slave isslave = api.unrestraint.option(path).option.isslave() - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) # reset value with permissive if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not isslave: - api.forcepermissive.option(path).value.reset() + api.forcepermissive.config(confwrite).option(path).value.reset() else: api.forcepermissive.option(path, 1).value.reset() elif kwargs.get('permissive', False): if not isslave: - api.forcepermissive.option(path).value.reset() + api.forcepermissive.config(confwrite).option(path).value.reset() else: api.forcepermissive.option(path, 1).value.reset() else: if not isslave: - raises(PropertiesOptionError, "api.forcepermissive.option(path).value.reset()") + raises(PropertiesOptionError, "api.forcepermissive.config(confwrite).option(path).value.reset()") else: raises(PropertiesOptionError, "api.forcepermissive.option(path, 1).value.reset()") - _autocheck_default_value(api, path, **kwargs) + _autocheck_default_value(api, path, confread, **kwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **kwargs) @autocheck -def autocheck_display(api, path, **kwargs): +def autocheck_display(api, path, confread, confwrite, **kwargs): """re set value """ - #FIXME make_dict? - assert api.config - _autocheck_set_value(api, path, **kwargs) - assert api.config + make_dict = kwargs['make_dict'] + make_dict_value = kwargs['make_dict_value'] + assert api.config(confread).config.make_dict() == make_dict + if confread != confwrite: + assert(api.config(confwrite).config.make_dict()) == make_dict + _autocheck_set_value(api, path, confwrite, **kwargs) + assert api.config(confread).config.make_dict() == make_dict_value + if confread != confwrite: + assert(api.config(confwrite).config.make_dict()) == make_dict_value def _getproperties(multi, isslave, kwargs): @@ -508,28 +536,29 @@ def _getproperties(multi, isslave, kwargs): return default_props, frozenset(properties) -def _check_default_properties(api, path, kwargs, props_permissive, props): +def _check_default_properties(api, path, conf, kwargs, props_permissive, props): if not api.unrestraint.option(path).option.isslave(): if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert set(api.option(path).property.get()) == set(props_permissive) - assert set(api.forcepermissive.option(path).property.get()) == set(props_permissive) + assert set(api.config(conf).option(path).property.get()) == set(props_permissive) + assert set(api.config(conf).forcepermissive.option(path).property.get()) == set(props_permissive) elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).property.get()") - assert set(api.forcepermissive.option(path).property.get()) == set(props) + raises(PropertiesOptionError, "api.config(conf).option(path).property.get()") + assert set(api.forcepermissive.config(conf).option(path).property.get()) == set(props) else: - raises(PropertiesOptionError, "api.option(path).property.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).property.get()") + raises(PropertiesOptionError, "api.config(conf).option(path).property.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).property.get()") raises(APIError, "api.unrestraint.option(path).property.get()") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert set(api.option(path, 0).property.get()) == set(props) - assert set(api.option(path, 1).property.get()) == set(props) + assert set(api.config(conf).option(path, 0).property.get()) == set(props) + assert set(api.config(conf).option(path, 1).property.get()) == set(props) else: - raises(PropertiesOptionError, "api.option(path, 0).property.get()") + raises(PropertiesOptionError, "api.config(conf).option(path, 0).property.get()") raises(APIError, "api.unrestraint.option(path, 0).property.get()") -def _autocheck_property(api, path, **kwargs): +@autocheck +def autocheck_property(api, path, confread, confwrite, **kwargs): """get property from path """ # check if is a multi or a slave @@ -538,23 +567,25 @@ def _autocheck_property(api, path, **kwargs): default_props, properties = _getproperties(multi, isslave, kwargs) - _check_default_properties(api, path, kwargs, default_props, default_props) + _check_default_properties(api, path, confread, kwargs, default_props, default_props) + _check_default_properties(api, path, confwrite, kwargs, default_props, default_props) # set properties without permissive if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path).property.set(properties) + api.config(confwrite).option(path).property.set(properties) else: - raises(PropertiesOptionError, "api.option(path).property.set(properties)") + raises(PropertiesOptionError, "api.config(confwrite).option(path).property.set(properties)") - _check_default_properties(api, path, kwargs, properties, default_props) + _check_default_properties(api, path, confread, kwargs, properties, default_props) + if confread != confwrite: + _check_default_properties(api, path, confwrite, kwargs, properties, default_props) + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + raises(ConfigError, "api.config(confread).option(path).property.set(properties)") -@autocheck -def autocheck_property(api, path, **kwargs): - _autocheck_property(api, path, **kwargs) -def _property_permissive(api, path, **kwargs): +def _property_permissive(api, path, confread, confwrite, **kwargs): # check if is a multi or a slave multi = api.unrestraint.option(path).option.ismulti() isslave = api.unrestraint.option(path).option.isslave() @@ -572,29 +603,35 @@ def _property_permissive(api, path, **kwargs): default_props.extend(extra_properties) default_props, properties = _getproperties(multi, isslave, kwargs) - _check_default_properties(api, path, kwargs, default_props, default_props) + _check_default_properties(api, path, confwrite, kwargs, default_props, default_props) + if confwrite != confread: + _check_default_properties(api, path, confread, kwargs, default_props, default_props) # set properties with permissive if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path).property.set(properties) - api.forcepermissive.option(path).property.set(properties) + api.config(confwrite).option(path).property.set(properties) + api.forcepermissive.config(confwrite).option(path).property.set(properties) elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).property.set(properties)") - api.forcepermissive.option(path).property.set(properties) + raises(PropertiesOptionError, "api.config(confwrite).option(path).property.set(properties)") + api.forcepermissive.config(confwrite).option(path).property.set(properties) else: - raises(PropertiesOptionError, "api.option(path).property.set(properties)") - raises(PropertiesOptionError, "api.forcepermissive.option(path).property.set(properties)") + raises(PropertiesOptionError, "api.config(confwrite).option(path).property.set(properties)") + raises(PropertiesOptionError, "api.forcepermissive.config(confwrite).option(path).property.set(properties)") - _check_default_properties(api, path, kwargs, properties, properties) + _check_default_properties(api, path, confwrite, kwargs, properties, properties) + if confwrite != confread: + _check_default_properties(api, path, confread, kwargs, properties, properties) + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + raises(ConfigError, "api.config(confread).option(path).property.set(properties)") @autocheck -def autocheck_property_permissive(api, path, **kwargs): - _property_permissive(api, path, **kwargs) +def autocheck_property_permissive(api, path, confread, confwrite, **kwargs): + _property_permissive(api, path, confread, confwrite, **kwargs) @autocheck -def autocheck_reset_property(api, path, **kwargs): +def autocheck_reset_property(api, path, confread, confwrite, **kwargs): """check properties after set with permissive """ # check if is a multi or a slave @@ -602,25 +639,29 @@ def autocheck_reset_property(api, path, **kwargs): isslave = api.unrestraint.option(path).option.isslave() default_props, properties = _getproperties(multi, isslave, kwargs) - _property_permissive(api, path, **kwargs) + _property_permissive(api, path, confread, confwrite, **kwargs) # reset properties without permissive if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path).property.reset() + api.config(confwrite).option(path).property.reset() else: - raises(PropertiesOptionError, "api.option(path).property.reset()") + raises(PropertiesOptionError, "api.config(confwrite).option(path).property.reset()") - _check_default_properties(api, path, kwargs, default_props, properties) + _check_default_properties(api, path, confread, kwargs, default_props, properties) + if confread != confwrite: + _check_default_properties(api, path, confwrite, kwargs, default_props, properties) + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + raises(ConfigError, "api.config(confread).option(path).property.reset()") @autocheck -def autocheck_reset_property_permissive(api, path, **kwargs): +def autocheck_reset_property_permissive(api, path, confread, confwrite, **kwargs): # check if is a multi or a slave multi = api.unrestraint.option(path).option.ismulti() isslave = api.unrestraint.option(path).option.isslave() default_props, properties = _getproperties(multi, isslave, kwargs) - _property_permissive(api, path, **kwargs) + _property_permissive(api, path, confread, confwrite, **kwargs) # reset properties with permissive raises(APIError, "api.unrestraint.option(path).property.set(properties)") @@ -631,27 +672,29 @@ def autocheck_reset_property_permissive(api, path, **kwargs): elif kwargs.get('permissive', False): api.forcepermissive.option(path).property.reset() - _check_default_properties(api, path, kwargs, default_props, default_props) + _check_default_properties(api, path, confwrite, kwargs, default_props, default_props) + if confread != confwrite: + _check_default_properties(api, path, confread, kwargs, default_props, default_props) @autocheck -def autocheck_context_owner(api, path, **kwargs): +def autocheck_context_owner(api, path, confread, confwrite, **kwargs): owner = api.owner.get() assert owner == OWNER -def _check_owner(api, path, kwargs, owner, permissive_owner): +def _check_owner(api, path, conf, kwargs, owner, permissive_owner): isslave = api.unrestraint.option(path).option.isslave() if not isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).owner.get() == owner - assert api.forcepermissive.option(path).owner.get() == owner + assert api.config(conf).option(path).owner.get() == owner + assert api.forcepermissive.config(conf).option(path).owner.get() == owner elif not kwargs.get('propertyerror', False): - raises(PropertiesOptionError, "api.option(path).owner.get()") - assert api.forcepermissive.option(path).owner.get() == permissive_owner + raises(PropertiesOptionError, "api.config(conf).option(path).owner.get()") + assert api.forcepermissive.config(conf).option(path).owner.get() == permissive_owner else: - raises(PropertiesOptionError, "api.option(path).owner.get()") - raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.get()") + raises(PropertiesOptionError, "api.config(conf).option(path).owner.get()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).owner.get()") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): assert api.option(path, 0).owner.get() == 'default' @@ -669,101 +712,114 @@ def _check_owner(api, path, kwargs, owner, permissive_owner): @autocheck -def autocheck_owner_with_value(api, path, **kwargs): +def autocheck_owner_with_value(api, path, confread, confwrite, **kwargs): """value is now changed, check owner in this case """ - _autocheck_set_value(api, path, **kwargs) - _check_owner(api, path, kwargs, OWNER, OWNER) + _autocheck_set_value(api, path, confwrite, **kwargs) + _check_owner(api, path, confwrite, kwargs, OWNER, OWNER) + if confread != confwrite: + _check_owner(api, path, confread, kwargs, owners.meta, owners.meta) @autocheck -def autocheck_default_owner_with_value(api, path, **kwargs): - _autocheck_set_value(api, path, **kwargs) - # check if is a isslave - isslave = api.unrestraint.option(path).option.isslave() +def autocheck_default_owner_with_value(api, path, confread, confwrite, **kwargs): + _autocheck_set_value(api, path, confwrite, **kwargs) # test if is default owner without permissive if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - assert api.option(path).owner.isdefault() is False + assert api.config(confwrite).option(path).owner.isdefault() is False + assert api.config(confread).option(path).owner.isdefault() is False else: - raises(PropertiesOptionError, "api.option(path).owner.isdefault()") + raises(PropertiesOptionError, "api.config(confwrite).option(path).owner.isdefault()") + raises(PropertiesOptionError, "api.config(confread).option(path).owner.isdefault()") @autocheck -def autocheck_default_owner_with_value_permissive(api, path, **kwargs): +def autocheck_default_owner_with_value_permissive(api, path, confread, confwrite, **kwargs): # check if is a isslave isslave = api.unrestraint.option(path).option.isslave() - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) - # test if is default owner with permissive - if not kwargs.get('propertyerror', False): - if not isslave: - assert api.forcepermissive.option(path).owner.isdefault() is False + def do(conf): + # test if is default owner with permissive + if not kwargs.get('propertyerror', False): + if not isslave: + assert api.forcepermissive.config(conf).option(path).owner.isdefault() is False + else: + assert api.forcepermissive.config(conf).option(path, 0).owner.isdefault() is True + assert api.forcepermissive.config(conf).option(path, 1).owner.isdefault() is False else: - assert api.forcepermissive.option(path, 0).owner.isdefault() is True - assert api.forcepermissive.option(path, 1).owner.isdefault() is False - else: - raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.isdefault()") + raises(PropertiesOptionError, "api.forcepermissive.config(conf).option(path).owner.isdefault()") + do(confwrite) + if confwrite != confread: + do(confread) @autocheck -def autocheck_set_owner_no_value(api, path, **kwargs): +def autocheck_set_owner_no_value(api, path, confread, confwrite, **kwargs): isslave = api.unrestraint.option(path).option.isslave() if not kwargs.get('propertyerror', False): if not isslave: - raises(ConfigError, "api.forcepermissive.option(path).owner.set('new_user')") + raises(ConfigError, "api.forcepermissive.config(confwrite).option(path).owner.set('new_user')") else: raises(ConfigError, "api.forcepermissive.option(path, 1).owner.set('new_user')") @autocheck -def autocheck_set_owner(api, path, **kwargs): +def autocheck_set_owner(api, path, confread, confwrite, **kwargs): # test set owner without permissive isslave = api.unrestraint.option(path).option.isslave() - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) # set owner without permissive if not isslave: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): - api.option(path).owner.set('new_user') + api.config(confwrite).option(path).owner.set('new_user') + raises(ConfigError, "api.config(confwrite).option(path).owner.set('default')") + raises(ConfigError, "api.config(confwrite).option(path).owner.set('forced')") + raises(ConfigError, "api.config(confwrite).option(path).owner.set('meta')") else: - raises(PropertiesOptionError, "api.option(path).owner.set('new_user')") + raises(PropertiesOptionError, "api.config(confwrite).option(path).owner.set('new_user')") else: if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): api.option(path, 1).owner.set('new_user') else: raises(PropertiesOptionError, "api.option(path, 1).owner.set('new_user')") - _check_owner(api, path, kwargs, 'new_user', OWNER) + _check_owner(api, path, confwrite, kwargs, owners.new_user, OWNER) + if confwrite != confread: + _check_owner(api, path, confread, kwargs, owners.meta, owners.meta) @autocheck -def autocheck_set_owner_permissive(api, path, **kwargs): +def autocheck_set_owner_permissive(api, path, confread, confwrite, **kwargs): isslave = api.unrestraint.option(path).option.isslave() - _autocheck_set_value(api, path, **kwargs) + _autocheck_set_value(api, path, confwrite, **kwargs) # set owner with permissive if not kwargs.get('propertyerror', False): if not isslave: - api.forcepermissive.option(path).owner.set('new_user1') + api.forcepermissive.config(confwrite).option(path).owner.set('new_user1') else: api.forcepermissive.option(path, 1).owner.set('new_user1') else: if not isslave: raises(PropertiesOptionError, - "api.forcepermissive.option(path).owner.set('new_user1')") + "api.forcepermissive.config(confwrite).option(path).owner.set('new_user1')") else: raises(PropertiesOptionError, "api.forcepermissive.option(path, 1).owner.set('new_user1')") - _check_owner(api, path, kwargs, 'new_user1', 'new_user1') + _check_owner(api, path, confwrite, kwargs, 'new_user1', 'new_user1') + if confwrite != confread: + _check_owner(api, path, confread, kwargs, owners.meta, owners.meta) @autocheck -def autocheck_option(api, path, **kwargs): +def autocheck_option(api, path, confread, confwrite, **kwargs): expected_name = path.split('.')[-1] if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): current_name = api.option(path).option.getname() @@ -793,62 +849,206 @@ def autocheck_option(api, path, **kwargs): @autocheck -def autocheck_permissive(api, path, **kwargs): +def autocheck_permissive(api, path, confread, confwrite, **kwargs): """test permissive for hidden and disabled value """ # no permissive before - assert api.unrestraint.option(path).permissive.get() == frozenset() + assert api.unrestraint.config(confread).option(path).permissive.get() == frozenset() if kwargs.get('permissive_od', False): - assert api.unrestraint.option(path.rsplit('.', 1)[0]).permissive.get() == frozenset() + assert api.unrestraint.config(confread).option(path.rsplit('.', 1)[0]).permissive.get() == frozenset() # cannot access to hidden value without forcepermissive # and to disabled value (with forcepermissive too) - _autocheck_default_value(api, path, **kwargs) + # + # with meta confread == confwrite + _autocheck_default_value(api, path, confread, **kwargs) # set permissive - api.unrestraint.option(path).permissive.set(frozenset(['disabled'])) + api.unrestraint.config(confwrite).option(path).permissive.set(frozenset(['disabled'])) # have permissive - assert api.unrestraint.option(path).permissive.get() == frozenset(['disabled']) + assert api.unrestraint.config(confwrite).option(path).permissive.get() == frozenset(['disabled']) + if confwrite != confread: + assert api.unrestraint.config(confread).option(path).permissive.get() == frozenset(['disabled']) # can access to disabled value ckwargs = copy(kwargs) ckwargs['propertyerror'] = False - _autocheck_default_value(api, path, **ckwargs) + _autocheck_default_value(api, path, confread, **ckwargs) - api.unrestraint.option(path).permissive.set(frozenset(['disabled', 'hidden'])) + api.unrestraint.config(confwrite).option(path).permissive.set(frozenset(['disabled', 'hidden'])) # can access to all value except when optiondescript have hidden if not ckwargs.get('permissive_od', False): ckwargs['permissive'] = False - _autocheck_default_value(api, path, **ckwargs) + _autocheck_default_value(api, path, confread, **ckwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **ckwargs) if ckwargs.get('permissive_od', False): # set permissive to OptionDescription - api.unrestraint.option(path.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled', - 'hidden'])) + api.unrestraint.config(confwrite).option(path.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled', + 'hidden'])) ckwargs['permissive'] = False - _autocheck_default_value(api, path, **ckwargs) + _autocheck_default_value(api, path, confread, **ckwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **ckwargs) # only hidden - api.unrestraint.option(path).permissive.set(frozenset(['hidden'])) + api.unrestraint.config(confwrite).option(path).permissive.set(frozenset(['hidden'])) if ckwargs.get('permissive_od', False): - _autocheck_default_value(api, path, **ckwargs) - api.unrestraint.option(path.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden'])) + _autocheck_default_value(api, path, confread, **ckwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **ckwargs) + api.unrestraint.config(confwrite).option(path.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden'])) ckwargs = copy(kwargs) ckwargs['permissive'] = False - _autocheck_default_value(api, path, **ckwargs) + _autocheck_default_value(api, path, confread, **ckwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **ckwargs) # no permissive - api.unrestraint.option(path).permissive.set(frozenset()) + api.unrestraint.config(confwrite).option(path).permissive.set(frozenset()) if ckwargs.get('permissive_od', False): - _autocheck_default_value(api, path, **ckwargs) - api.unrestraint.option(path.rsplit('.', 1)[0]).permissive.set(frozenset()) - _autocheck_default_value(api, path, **kwargs) + _autocheck_default_value(api, path, confread, **ckwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **ckwargs) + api.unrestraint.config(confwrite).option(path.rsplit('.', 1)[0]).permissive.set(frozenset()) + _autocheck_default_value(api, path, confread, **kwargs) + if confread != confwrite: + _autocheck_default_value(api, path, confwrite, **kwargs) +@autocheck +def autocheck_option_get(api, path, confread, confwrite, **kwargs): + if '.' in path: + name = path.rsplit('.', 1)[1] + else: + name = path + assert api.option.get(path).impl_getname() == name -def check_all(cfg, path, meta, multi, default, default_multi, require, consistency, **kwargs): + +@autocheck +def autocheck_find(api, path, confread, confwrite, **kwargs): + def _getoption(opt): + if opt.impl_is_dynsymlinkoption(): + opt = opt.impl_getopt() + return opt + + def _getoptions(opts): + nopts = [] + for opt in opts: + nopts.append(_getoption(opt)) + return nopts + + if '.' in path: + name = path.rsplit('.', 1)[1] + else: + name = path + option = _getoption(api.option.get(path)) + + def do(conf): + if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): + assert option == _getoption(api.config(conf).option.find_first(name)) + assert option == _getoption(api.forcepermissive.config(conf).option.find_first(name)) + elif kwargs.get('permissive', False): + raises(AttributeError, "api.config(conf).option.find_first(name)") + assert option == _getoption(api.forcepermissive.config(conf).option.find_first(name)) + else: + raises(AttributeError, "api.config(conf).option.find_first(name)") + raises(AttributeError, "api.forcepermissive.config(conf).option.find_first(name)") + assert option == _getoption(api.unrestraint.config(conf).option.find_first(name)) + assert [option] == _getoptions(api.unrestraint.config(conf).option.find(name)) + assert path == api.unrestraint.config(conf).option.find_first(name, 'path') + assert [path] == api.unrestraint.config(conf).option.find(name, 'path') + do(confread) + if confread != confwrite: + do(confwrite) + + +def check_all(cfg, paths, path, meta, multi, default, default_multi, require, consistency, weakrefs, **kwargs): + def _build_make_dict(): + dico = {} + dico_value = {} + if multi is False: + value = FIRST_VALUE + elif multi is True: + value = LIST_FIRST_VALUE + else: + value = SUBLIST_FIRST_VALUE + if not default or submulti: + if not multi: + default_value = None + else: + default_value = [] + else: + default_value = value + + is_dyn = False + dyns = [] + has_value = False + for cpath, options in paths.items(): + if options is None: + break + if '.' in cpath: + dirname, name = cpath.split('.')[-2:] + else: + dirname = '' + name = cpath + if options.get(dirname, {}).get('hidden'): + continue + if options.get(dirname, {}).get('dyn'): + is_dyn = True + no_propertieserror = not options.get(name, {}).get('disabled') and not options.get(name, {}).get('hidden') + allow_req = require and req + if is_dyn: + dyns.append(no_propertieserror or allow_req) + elif no_propertieserror or allow_req: + dico[cpath] = default_value + if path == cpath: + dico_value[cpath] = value + else: + dico_value[cpath] = default_value + has_value = True + if is_dyn: + idx = 0 + for cpath in list(paths.keys())[len(dyns):]: + + if dyns[idx]: + dico[cpath] = default_value + if path == cpath: + dico_value[cpath] = value + else: + dico_value[cpath] = default_value + idx += 1 + if idx == len(dyns): + idx = 0 + if require: + if not req: + dico['extraoptrequire'] = None + dico_value['extraoptrequire'] = None + else: + dico['extraoptrequire'] = 'value' + dico_value['extraoptrequire'] = 'value' + if consistency and has_value: + cpath = list(dico.keys())[0] + if "." in cpath: + cpath = cpath.rsplit('.', 1)[0] + '.' + else: + cpath = '' + if multi: + value = [] + else: + value = None + if is_dyn: + dico[cpath + 'extraoptconsistencyval1'] = value + dico[cpath[:-2] + '2.' + 'extraoptconsistencyval2'] = value + dico_value[cpath + 'extraoptconsistencyval1'] = value + dico_value[cpath[:-2] + '2.' + 'extraoptconsistencyval2'] = value + else: + dico[cpath + 'extraoptconsistency'] = value + dico_value[cpath + 'extraoptconsistency'] = value + return dico, dico_value if DISPLAY: text = u' {} launch tests for {}'.format(ICON, path) if multi is True: @@ -861,19 +1061,33 @@ def check_all(cfg, path, meta, multi, default, default_multi, require, consisten text += u' with default value' if default_multi is True: text += u' with default multi' + if require: + text += u' with requirement' + if consistency: + text += u' with consistency' text += u', kwargs: {}'.format(kwargs) print(text) - api = getapi(cfg) - if api.unrestraint.option(path).option.isslave(): - master_path = path.rsplit('.', 1)[0] + '.master' - api.option(master_path).value.set(LIST_SECOND_VALUE) if not require: requires = [False] else: requires = [False, True] + confwrite = confread = None + idx = 0 for req in requires: + kwargs['make_dict'], kwargs['make_dict_value'] = _build_make_dict() for func in autocheck_registers: - api = getapi(cfg.duplicate()) + cfg_name = 'conftest' + str(idx) + idx += 1 + ncfg = cfg.duplicate(session_id=cfg_name) + if meta: + confwrite = None + confread = cfg_name + ncfg = MetaConfig([ncfg], session_id='metatest') + weakrefs.append(weakref.ref(cfg)) + api = getapi(ncfg) + if api.unrestraint.option(path).option.isslave(): + master_path = path.rsplit('.', 1)[0] + '.master' + api.option(master_path).value.set(LIST_SECOND_VALUE) #FIXME devrait etre dans la config ca ... api.read_write() ckwargs = copy(kwargs) @@ -887,7 +1101,7 @@ def check_all(cfg, path, meta, multi, default, default_multi, require, consisten if DISPLAY: print(u' {} {}'.format(ICON, func.__name__)) try: - func(api, path, **ckwargs) + func(api, path, confread, confwrite, **ckwargs) except Exception as err: msg = u'error in function {} for {}'.format(func.__name__, path) if multi is True: @@ -898,6 +1112,8 @@ def check_all(cfg, path, meta, multi, default, default_multi, require, consisten msg += u' with default value' print(u'{}: {}'.format(msg, ckwargs)) raise err + del api + del ncfg def check_deref(weakrefs): @@ -1027,9 +1243,6 @@ def make_conf(options, meta, multi, default, default_multi, require, consistency return None, None cfg = Config(rootod, session_id='conftest') weakrefs.append(weakref.ref(cfg)) - if meta: - cfg = MetaConfig([cfg], session_id='metatest') - weakrefs.append(weakref.ref(cfg)) del goptions return cfg, weakrefs, dyn @@ -1056,7 +1269,7 @@ DICT_PATHS = [ OrderedDict([('odmaster.first', {'master': {'master': True}}), ('odmaster.second', {'second': {'disabled': True, 'slave': True}}), ('odmaster.third', {'third': {'hidden': True, 'slave': True}})]), - ##test a config with dynoption + #test a config with dynoption OrderedDict([('subod.first', {'subod': {'dyn': True}}), ('subod.second', {'second': {'disabled': True}}), ('subod.third', {'third': {'hidden': True}}), @@ -1124,35 +1337,34 @@ def test_options(paths): return kwargs lpaths = list(paths.keys()) - meta = False - #for meta in (False, True): - for consistency in (False, True): - for require in (False, True): - for default_multi in (False, True): - for default in (False, True): - for multi in (False, True, submulti): - if multi is submulti and consistency: - continue - if multi is False and default_multi: - continue - cfg, weakrefs, dyn = make_conf(paths, meta, multi, default, default_multi, require, consistency) - if cfg is None: - continue - if dyn: - cnt = 0 - idx = 0 - for index, lpath in enumerate(lpaths): - if paths[lpath]: - cnt += 1 - else: - check_all(cfg, lpaths[index], meta, multi, default, - default_multi, require, consistency, **get_kwargs(lpaths[idx])) - idx += 1 - if idx == cnt: - idx = 0 - else: - for lpath in lpaths: - check_all(cfg, lpath, meta, multi, default, - default_multi, require, consistency, **get_kwargs(lpath)) - del cfg - check_deref(weakrefs) + for meta in (False, True): + for consistency in (False, True): + for require in (False, True): + for default_multi in (False, True): + for default in (False, True): + for multi in (False, True, submulti): + if multi is submulti and consistency: + continue + if multi is False and default_multi: + continue + cfg, weakrefs, dyn = make_conf(paths, meta, multi, default, default_multi, require, consistency) + if cfg is None: + continue + if dyn: + cnt = 0 + idx = 0 + for index, lpath in enumerate(lpaths): + if paths[lpath]: + cnt += 1 + else: + check_all(cfg, paths, lpaths[index], meta, multi, default, + default_multi, require, consistency, weakrefs, **get_kwargs(lpaths[idx])) + idx += 1 + if idx == cnt: + idx = 0 + else: + for lpath in lpaths: + check_all(cfg, paths, lpath, meta, multi, default, + default_multi, require, consistency, weakrefs, **get_kwargs(lpath)) + del cfg + check_deref(weakrefs) diff --git a/tiramisu/api.py b/tiramisu/api.py index 8e7222a..9472fd0 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -395,32 +395,64 @@ class TiramisuOption(object): class TiramisuContext(object): - def __init__(self, config): + def __init__(self, + config, + force_permissive, + force_unrestraint, + setting_properties=None): + if setting_properties is None: + setting_properties = config.cfgimpl_get_settings().get_context_properties() self.config = config + self.force_permissive = force_permissive + self.force_unrestraint = force_unrestraint + self.setting_properties = setting_properties class TiramisuContextOwner(TiramisuContext): def get(self): return self.config.cfgimpl_get_settings().getowner() -class TiramisuAPI(object): - icon = '\u2937' - tmpl_help = ' {} {}: {}' +class TiramisuContextOption(TiramisuContext): + def find_first(self, + name, + type='option'): + check_properties = self.force_unrestraint or self.force_unrestraint + return self.config.find_first(byname=name, + type_=type, + setting_properties=self.setting_properties, + force_permissive=self.force_permissive, + check_properties=not self.force_unrestraint) + def find(self, + name, + type='option'): + return self.config.find(byname=name, + type_=type, + setting_properties=self.setting_properties, + force_permissive=self.force_permissive, + check_properties=not self.force_unrestraint) + + def get(self, path): + return self.config.unwrap_from_path(path, + validate=False, + validate_properties=False) + + +class TiramisuOptionDispatcher(TiramisuContextOption): def __init__(self, config, - force_permissive=False, - force_unrestraint=False): - self.config = config - self.force_permissive = force_permissive - self.force_unrestraint = force_unrestraint + force_permissive, + force_unrestraint): + self.setting_properties = config.cfgimpl_get_settings().get_context_properties() + super(TiramisuOptionDispatcher, self).__init__(config, + force_permissive, + force_unrestraint, + self.setting_properties) - def option(self, path, index=None): + def __call__(self, path, index=None): validate = not self.force_unrestraint - settings = self.config.cfgimpl_get_settings() - setting_properties = settings.get_context_properties() if validate: - s_properties = setting_properties + s_properties = self.setting_properties else: s_properties = None opt = self.config.unwrap_from_path(path, @@ -435,26 +467,74 @@ class TiramisuAPI(object): path, index, self.config, - setting_properties, + self.setting_properties, self.force_permissive, self.force_unrestraint) +class TiramisuContextConfig(TiramisuContext): + def make_dict(self): + return self.config.make_dict(self.setting_properties) + + +class TiramisuConfigDispatcher(TiramisuContextConfig): + def __init__(self, + config, + force_permissive, + force_unrestraint): + self.setting_properties = config.cfgimpl_get_settings().get_context_properties() + super(TiramisuConfigDispatcher, self).__init__(config, + force_permissive, + force_unrestraint, + self.setting_properties) + + def __call__(self, path): + if path is None: + subconfig = self.config + else: + subconfig = self.config.getconfig(path) + return TiramisuAPI(subconfig, + force_permissive=self.force_permissive, + force_unrestraint=self.force_unrestraint) + + +class TiramisuAPI(object): + icon = '\u2937' + tmpl_help = ' {} {}: {}' + + def __init__(self, + config, + force_permissive=False, + force_unrestraint=False): + self._config = config + self.force_permissive = force_permissive + self.force_unrestraint = force_unrestraint + def __getattr__(self, subfunc): if subfunc == 'forcepermissive': - return TiramisuAPI(self.config, + return TiramisuAPI(self._config, force_permissive=True, force_unrestraint=self.force_unrestraint) elif subfunc == 'unrestraint': - return TiramisuAPI(self.config, + return TiramisuAPI(self._config, force_permissive=self.force_permissive, force_unrestraint=True) elif subfunc == 'help': return self._help() elif subfunc == 'owner': - return TiramisuContextOwner(self.config) + return TiramisuContextOwner(self._config, + self.force_permissive, + self.force_unrestraint) + elif subfunc == 'config': + return TiramisuConfigDispatcher(self._config, + force_permissive=self.force_permissive, + force_unrestraint=self.force_unrestraint) + elif subfunc == 'option': + return TiramisuOptionDispatcher(self._config, + force_permissive=self.force_permissive, + force_unrestraint=self.force_unrestraint) else: - raise APIError(_('please specify a valid sub function')) + raise APIError(_('please specify a valid sub function ({})').format(subfunc)) def _help(self): txt = ['[forcepermissive]'] @@ -465,11 +545,11 @@ class TiramisuAPI(object): return '\n'.join(txt) def read_only(self): - self.config.read_write() + self._config.read_write() def read_write(self): - settings = self.config.cfgimpl_get_settings() - self.config.read_write() + settings = self._config.cfgimpl_get_settings() + self._config.read_write() # #FIXME ? settings.set_context_permissive(frozenset(['hidden'])) #/FIXME ? diff --git a/tiramisu/config.py b/tiramisu/config.py index 0d0acd6..7a24619 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -182,8 +182,7 @@ class SubConfig(object): def __iter__(self, force_permissive=False): """Pythonesque way of parsing group's ordered options. iteration only on Options (not OptionDescriptions)""" - setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings( - )._getproperties(read_write=True) + setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings().get_context_properties() for child in self.cfgimpl_get_description()._impl_getchildren( context=self._cfgimpl_get_context()): if not child.impl_is_optiondescription(): @@ -215,7 +214,9 @@ class SubConfig(object): except PropertiesOptionError: # pragma: optional cover pass # option with properties - def iter_groups(self, group_type=None, force_permissive=False): + def iter_groups(self, + group_type=None, + force_permissive=False): """iteration on groups objects only. All groups are returned if `group_type` is `None`, otherwise the groups can be filtered by categories (families, or whatever). @@ -228,7 +229,7 @@ class SubConfig(object): groups.GroupType): # pragma: optional cover raise TypeError(_("unknown group_type: {0}").format(group_type)) context = self._cfgimpl_get_context() - setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=True) + setting_properties = context.cfgimpl_get_settings().get_context_properties() for child in self.cfgimpl_get_description()._impl_getchildren( context=context): if child.impl_is_optiondescription(): @@ -303,7 +304,7 @@ class SubConfig(object): value, force_permissive=False, index=None, - setting_properties=undefined, + setting_properties=None, _commit=True): if name.startswith('_impl_'): @@ -311,7 +312,7 @@ class SubConfig(object): name, value) context = self._cfgimpl_get_context() - if setting_properties is undefined: + if setting_properties is None: setting_properties = context.cfgimpl_get_settings().get_context_properties() if '.' in name: # pragma: optional cover self, name = self.cfgimpl_get_home_by_path(name, @@ -321,7 +322,7 @@ class SubConfig(object): context=context) if isinstance(child, (OptionDescription, SynDynOptionDescription)): raise TypeError(_("can't assign to an OptionDescription")) # pragma: optional cover - elif child._is_symlinkoption() and \ + elif child.impl_is_symlinkoption() and \ not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover raise TypeError(_("can't assign to a SymlinkOption")) else: @@ -344,11 +345,11 @@ class SubConfig(object): name, index=None, force_permissive=False, - setting_properties=undefined, + setting_properties=None, validate=True, not_raises=False): context = self._cfgimpl_get_context() - if setting_properties is undefined: + if setting_properties is None: setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=True) if '.' in name: # pragma: optional cover self, name = self.cfgimpl_get_home_by_path(name, @@ -358,7 +359,7 @@ class SubConfig(object): context=context) if isinstance(child, (OptionDescription, SynDynOptionDescription)): raise TypeError(_("can't delete an OptionDescription")) # pragma: optional cover - elif child._is_symlinkoption() and \ + elif child.impl_is_symlinkoption() and \ not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover raise TypeError(_("can't delete a SymlinkOption")) else: @@ -438,16 +439,14 @@ class SubConfig(object): option = self.cfgimpl_get_description().__getattr__(name, context=context) subpath = self._get_subpath(name) - if isinstance(option, DynSymLinkOption): - cfg = self.cfgimpl_get_values().get_cached_value(option, - path=subpath, - validate=validate, - validate_properties=validate_properties, - force_permissive=force_permissive, - setting_properties=setting_properties, - index=index) - elif option._is_symlinkoption(): # pragma: no dynoptiondescription cover - path = context.cfgimpl_get_description().impl_get_path_by_opt(option._impl_getopt()) + if setting_properties: + self.cfgimpl_get_settings().validate_properties(option, + subpath, + setting_properties, + index=index, + force_permissive=force_permissive) + if option.impl_is_symlinkoption() and not isinstance(option, DynSymLinkOption): + path = context.cfgimpl_get_description().impl_get_path_by_opt(option.impl_getopt()) cfg = context.getattr(path, validate=validate, validate_properties=validate_properties, @@ -455,13 +454,6 @@ class SubConfig(object): setting_properties=setting_properties, index=index) elif option.impl_is_optiondescription(): - if setting_properties: - self.cfgimpl_get_settings().validate_properties(option, - True, - False, - path=subpath, - force_permissive=force_permissive, - setting_properties=setting_properties) if returns_option is True: return option return SubConfig(option, @@ -471,30 +463,37 @@ class SubConfig(object): force_permissive, subpath) else: - if validate: - self.cfgimpl_get_description().impl_validate(context, - force_permissive, - setting_properties) if option.impl_is_master_slaves('slave') and index is not None and \ index >= self._impl_length: raise IndexError(_('index ({}) is higher than the master length ({}) for "{}"' '').format(index, self._impl_length, subpath)) - cfg = self.cfgimpl_get_values().get_cached_value(option, - path=subpath, - validate=validate, - validate_properties=validate_properties, - force_permissive=force_permissive, - setting_properties=setting_properties, - index=index) + if validate: + self.cfgimpl_get_description().impl_validate(context, + force_permissive, + setting_properties) + + if not returns_option: + cfg = self.cfgimpl_get_values().get_cached_value(option, + path=subpath, + validate=validate, + setting_properties=setting_properties, + force_permissive=force_permissive, + index=index) if returns_option is True: return option else: return cfg - def find(self, bytype=None, byname=None, byvalue=undefined, type_='option', - check_properties=True, force_permissive=False): + def find(self, + setting_properties, + bytype=None, + byname=None, + byvalue=undefined, + type_='option', + check_properties=True, + force_permissive=False): """ finds a list of options recursively in the config @@ -503,15 +502,24 @@ class SubConfig(object): :param byvalue: filter by the option's value :returns: list of matching Option objects """ - return self._cfgimpl_get_context()._find(bytype, byname, byvalue, + return self._cfgimpl_get_context()._find(bytype, + byname, + byvalue, + setting_properties=setting_properties, first=False, type_=type_, _subpath=self.cfgimpl_get_path(False), check_properties=check_properties, force_permissive=force_permissive) - def find_first(self, bytype=None, byname=None, byvalue=undefined, - type_='option', raise_if_not_found=True, check_properties=True, + def find_first(self, + setting_properties, + bytype=None, + byname=None, + byvalue=undefined, + type_='option', + raise_if_not_found=True, + check_properties=True, force_permissive=False): """ finds an option recursively in the config @@ -521,28 +529,42 @@ class SubConfig(object): :param byvalue: filter by the option's value :returns: list of matching Option objects """ - return self._cfgimpl_get_context()._find( - bytype, byname, byvalue, first=True, type_=type_, - _subpath=self.cfgimpl_get_path(False), raise_if_not_found=raise_if_not_found, - check_properties=check_properties, - force_permissive=force_permissive) + return self._cfgimpl_get_context()._find(bytype, + byname, + byvalue, + setting_properties=setting_properties, + first=True, + type_=type_, + _subpath=self.cfgimpl_get_path(False), + raise_if_not_found=raise_if_not_found, + check_properties=check_properties, + force_permissive=force_permissive) - def _find(self, bytype, byname, byvalue, first, type_='option', - _subpath=None, check_properties=True, raise_if_not_found=True, - force_permissive=False, only_path=undefined, - only_option=undefined, setting_properties=undefined): + def _find(self, + bytype, + byname, + byvalue, + first, + type_='option', + _subpath=None, + check_properties=True, + raise_if_not_found=True, + force_permissive=False, + only_path=undefined, + only_option=undefined, + setting_properties=None): """ convenience method for finding an option that lives only in the subtree :param first: return only one option if True, a list otherwise :return: find list or an exception if nothing has been found """ - def _filter_by_value(): if byvalue is undefined: return True try: - value = self.getattr(path, force_permissive=force_permissive, + value = self.getattr(path, + force_permissive=force_permissive, setting_properties=setting_properties) except PropertiesOptionError: return False @@ -563,22 +585,26 @@ class SubConfig(object): if only_path is not undefined: options = [(only_path, only_option)] else: - options = self.cfgimpl_get_description().impl_get_options_paths( - bytype, byname, _subpath, only_first, - self._cfgimpl_get_context()) + options = self.cfgimpl_get_description().impl_get_options_paths(bytype, + byname, + _subpath, + only_first, + self._cfgimpl_get_context()) for path, option in options: if not _filter_by_value(): continue #remove option with propertyerror, ... - if byvalue is undefined and check_properties: + if check_properties: try: - value = self.getattr(path, - force_permissive=force_permissive, - setting_properties=setting_properties) + self.unwrap_from_path(path, + setting_properties=setting_properties, + force_permissive=force_permissive) except PropertiesOptionError: continue if type_ == 'value': - retval = value + retval = self.getattr(path, + force_permissive=force_permissive, + setting_properties=setting_properties) elif type_ == 'path': retval = path elif type_ == 'option': @@ -587,9 +613,12 @@ class SubConfig(object): return retval else: find_results.append(retval) - return self._find_return_results(find_results, raise_if_not_found) + return self._find_return_results(find_results, + raise_if_not_found) - def _find_return_results(self, find_results, raise_if_not_found): + def _find_return_results(self, + find_results, + raise_if_not_found): if find_results == []: # pragma: optional cover if raise_if_not_found: raise AttributeError(_("no option found in config" @@ -598,12 +627,12 @@ class SubConfig(object): return find_results def make_dict(self, + setting_properties, flatten=False, _currpath=None, withoption=None, withvalue=undefined, force_permissive=False, - setting_properties=undefined, fullpath=False): """exports the whole config into a `dict`, for example: @@ -647,8 +676,6 @@ class SubConfig(object): if withoption is None and withvalue is not undefined: # pragma: optional cover raise ValueError(_("make_dict can't filtering with value without " "option")) - if setting_properties is undefined: - setting_properties = self.cfgimpl_get_settings()._getproperties(read_write=False) if withoption is not None: context = self._cfgimpl_get_context() for path in context._find(bytype=None, @@ -675,7 +702,11 @@ class SubConfig(object): 'should start with {1}' '').format(path, mypath)) path = path[len(tmypath):] - self._make_sub_dict(opt, path, pathsvalues, _currpath, flatten, + self._make_sub_dict(opt, + path, + pathsvalues, + _currpath, + flatten, force_permissive=force_permissive, setting_properties=setting_properties, fullpath=fullpath) @@ -683,7 +714,11 @@ class SubConfig(object): if withoption is None: for opt in self.cfgimpl_get_description().impl_getchildren(): path = opt.impl_getname() - self._make_sub_dict(opt, path, pathsvalues, _currpath, flatten, + self._make_sub_dict(opt, + path, + pathsvalues, + _currpath, + flatten, force_permissive=force_permissive, setting_properties=setting_properties, fullpath=fullpath) @@ -692,8 +727,15 @@ class SubConfig(object): return options return pathsvalues - def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten, - setting_properties, force_permissive=False, fullpath=False): + def _make_sub_dict(self, + opt, + path, + pathsvalues, + _currpath, + flatten, + setting_properties, + force_permissive=False, + fullpath=False): try: value = self.getattr(path, force_permissive=force_permissive, @@ -702,10 +744,10 @@ class SubConfig(object): pass else: if opt.impl_is_optiondescription(): - pathsvalues += value.make_dict(flatten, - _currpath + path.split('.'), + pathsvalues += value.make_dict(setting_properties, + flatten=flatten, + _currpath=_currpath + path.split('.'), force_permissive=force_permissive, - setting_properties=setting_properties, fullpath=fullpath) else: if flatten: @@ -721,11 +763,12 @@ class SubConfig(object): name = '.'.join(_currpath + [opt.impl_getname()]) pathsvalues.append((name, value)) - def cfgimpl_get_path(self, dyn=True): + def cfgimpl_get_path(self, + dyn=True): descr = self.cfgimpl_get_description() if not dyn and descr.impl_is_dynoptiondescription(): context_descr = self._cfgimpl_get_context().cfgimpl_get_description() - return context_descr.impl_get_path_by_opt(descr._impl_getopt()) + return context_descr.impl_get_path_by_opt(descr.impl_getopt()) return self._impl_path @@ -733,12 +776,14 @@ class _CommonConfig(SubConfig): "abstract base class for the Config, GroupConfig and the MetaConfig" __slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test') - def _impl_build_all_caches(self, force_store_values): + def _impl_build_all_caches(self, + force_store_values): descr = self.cfgimpl_get_description() if not descr.impl_already_build_caches(): descr._build_cache_option() descr._build_cache(self) - descr.impl_build_force_store_values(self, force_store_values) + descr.impl_build_force_store_values(self, + force_store_values) def read_only(self): "read only is a global config's setting, see `settings.py`" @@ -748,7 +793,10 @@ class _CommonConfig(SubConfig): "read write is a global config's setting, see `settings.py`" self.cfgimpl_get_settings().read_write() - def getowner(self, opt, index=None, force_permissive=False): + def getowner(self, + opt, + index=None, + force_permissive=False): """convenience method to retrieve an option's owner from the config itself """ @@ -757,12 +805,13 @@ class _CommonConfig(SubConfig): not isinstance(opt, DynSymLinkOption): # pragma: optional cover raise TypeError(_('opt in getowner must be an option not {0}' '').format(type(opt))) - return self.cfgimpl_get_values().getowner(opt, index=index, + return self.cfgimpl_get_values().getowner(opt, + index=index, force_permissive=force_permissive) def unwrap_from_path(self, path, - setting_properties=undefined, + setting_properties=None, force_permissive=False, index=None, validate=True, @@ -788,11 +837,9 @@ class _CommonConfig(SubConfig): if index is None and option.impl_is_master_slaves('slave'): subpath = self._get_subpath(path) self.cfgimpl_get_settings().validate_properties(option, - True, - False, - path=subpath, - force_permissive=force_permissive, - setting_properties=setting_properties) + subpath, + setting_properties, + force_permissive=force_permissive) return option else: return self.getattr(path, @@ -833,14 +880,21 @@ class _CommonConfig(SubConfig): raise NotImplementedError() def _gen_fake_values(self): - fake_config = Config(self._impl_descr, persistent=False, + fake_config = Config(self._impl_descr, + persistent=False, force_values=get_default_values_storages(), force_settings=self.cfgimpl_get_settings()) fake_config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation(fake=True)) return fake_config - def duplicate(self, force_values=None, force_settings=None): - config = Config(self._impl_descr, _duplicate=True, force_values=force_values, + def duplicate(self, + session_id=None, + force_values=None, + force_settings=None): + config = Config(self._impl_descr, + _duplicate=True, + session_id=session_id, + force_values=force_values, force_settings=force_settings) config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation()) config.cfgimpl_get_settings()._p_.set_modified_properties(self.cfgimpl_get_settings( @@ -1057,31 +1111,19 @@ class GroupConfig(_CommonConfig): def __str__(self): ret = '' for child in self._impl_children: - ret += '({0})\n'.format(child._impl_name) + ret += "({0})\n".format(child._impl_name) if self._impl_descr is not None: ret += super(GroupConfig, self).__str__() return ret __repr__ = __str__ - def getattr(self, - name, - setting_properties, - force_permissive=False, - validate=True, - validate_properties=True, - index=None, - returns_option=False): + def getconfig(self, + name): for child in self._impl_children: if name == child.impl_getname(): return child - return super(GroupConfig, self).getattr(name, - setting_properties, - force_permissive, - validate, - validate_properties=validate_properties, - index=index, - returns_option=returns_option) + raise ConfigError(_('unknown config {}').format(name)) class MetaConfig(GroupConfig): @@ -1174,12 +1216,9 @@ class MetaConfig(GroupConfig): if childret is not None: # pragma: no cover ret.append(childret) - setret = self.setattr(path, - value, - _commit=_commit, - not_raises=True) - if setret is not None: - ret.append(setret) + self.setattr(path, + value, + _commit=_commit) return ret def reset(self, path): diff --git a/tiramisu/error.py b/tiramisu/error.py index 0b138ae..ef02c5b 100644 --- a/tiramisu/error.py +++ b/tiramisu/error.py @@ -55,7 +55,12 @@ def display_list(lst, separator='and'): # Exceptions for an Option class PropertiesOptionError(AttributeError): "attempt to access to an option with a property that is not allowed" - def __init__(self, msg, proptype, settings=None, datas=None, option_type=None): + def __init__(self, + msg, + proptype, + settings=None, + datas=None, + option_type=None): self.proptype = proptype self._settings = settings self._datas = datas @@ -72,30 +77,32 @@ class PropertiesOptionError(AttributeError): req = {} else: req = self._settings.apply_requires(**self._datas) - if req != {} or self._orig_opt is not None: - if req != {}: - only_one = len(req) == 1 - msg = [] - for action, msg_ in req.items(): - msg.append('{0} ({1})'.format(action, display_list(msg_))) - else: - only_one = len(self.proptype) == 1 - msg = self.proptype - if only_one: - prop_msg = _('property') - else: - prop_msg = _('properties') - msg = display_list(msg) - if self._orig_opt: - return str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format(self._type, - self._orig_opt.impl_get_display_name(), - self._datas['opt'].impl_get_display_name(), - prop_msg, - msg)) - else: - return str(_('cannot access to {0} "{1}" because has {2} {3}').format(self._type, self._datas['opt'].impl_get_display_name(), prop_msg, msg)) + #if req != {} or self._orig_opt is not None: + if req != {}: + only_one = len(req) == 1 + msg = [] + for action, msg_ in req.items(): + msg.append('{0} ({1})'.format(action, display_list(msg_))) else: - return super(PropertiesOptionError, self).__str__() + only_one = len(self.proptype) == 1 + msg = list(self.proptype) + if only_one: + prop_msg = _('property') + else: + prop_msg = _('properties') + msg = display_list(msg) + if self._orig_opt: + return str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}' + '').format(self._type, + self._orig_opt.impl_get_display_name(), + self._datas['opt'].impl_get_display_name(), + prop_msg, + msg)) + return str(_('cannot access to {0} "{1}" because has {2} {3}' + '').format(self._type, + self._datas['opt'].impl_get_display_name(), + prop_msg, + msg)) #____________________________________________________________ diff --git a/tiramisu/option/baseoption.py b/tiramisu/option/baseoption.py index 6001672..7562406 100644 --- a/tiramisu/option/baseoption.py +++ b/tiramisu/option/baseoption.py @@ -58,9 +58,10 @@ def validate_callback(callback, callback_params, type_, callbackoption): """ def _validate_option(option): #validate option - if hasattr(option, '_is_symlinkoption'): - if option._is_symlinkoption(): - cur_opt = option._impl_getopt() + #FIXME etrange ... + if hasattr(option, 'impl_is_symlinkoption'): + if option.impl_is_symlinkoption(): + cur_opt = option.impl_getopt() else: cur_opt = option else: @@ -423,7 +424,7 @@ class BaseOption(Base): obj._pp_.delcache(path) resetted_opts.add(opt) - def _is_symlinkoption(self): + def impl_is_symlinkoption(self): return False @@ -442,7 +443,8 @@ def validate_requires_arg(new_option, multi, requires, name): """ def get_option(require): option = require['option'] - if not hasattr(option, '_is_symlinkoption'): + #FIXME etrange ... + if not hasattr(option, 'impl_is_symlinkoption'): raise ValueError(_('malformed requirements ' 'must be an option in option {0}').format(name)) if not multi and option.impl_is_multi(): @@ -574,9 +576,11 @@ def validate_requires_arg(new_option, multi, requires, name): class SymLinkOption(OnlyOption): - def __init__(self, name, opt): + def __init__(self, + name, + opt): if not isinstance(opt, OnlyOption) or \ - opt._is_symlinkoption(): + opt.impl_is_symlinkoption(): raise ValueError(_('malformed symlinkoption ' 'must be an option ' 'for symlink {0}').format(name)) @@ -591,36 +595,36 @@ class SymLinkOption(OnlyOption): """ return self_is_dep is True - def _is_symlinkoption(self): + def impl_is_symlinkoption(self): return True def __getattr__(self, name, context=undefined): - return getattr(self._impl_getopt(), name) + return getattr(self.impl_getopt(), name) - def _impl_getopt(self): + def impl_getopt(self): return self._opt def impl_get_information(self, key, default=undefined): - return self._impl_getopt().impl_get_information(key, default) + return self.impl_getopt().impl_get_information(key, default) def impl_is_readonly(self): return True def impl_getproperties(self): - return self._impl_getopt().impl_getproperties() + return self.impl_getopt().impl_getproperties() def impl_get_callback(self): - return self._impl_getopt().impl_get_callback() + return self.impl_getopt().impl_get_callback() def impl_has_callback(self): "to know if a callback has been defined or not" - return self._impl_getopt().impl_has_callback() + return self.impl_getopt().impl_has_callback() def impl_is_multi(self): - return self._impl_getopt().impl_is_multi() + return self.impl_getopt().impl_is_multi() def _is_subdyn(self): - return getattr(self._impl_getopt(), '_subdyn', None) is not None + return getattr(self.impl_getopt(), '_subdyn', None) is not None def _get_consistencies(self): return () @@ -632,28 +636,34 @@ class SymLinkOption(OnlyOption): class DynSymLinkOption(object): __slots__ = ('_dyn', '_opt', '_name') - def __init__(self, name, opt, dyn): + def __init__(self, + name, + opt, + dyn): self._name = name self._dyn = dyn self._opt = opt - def __getattr__(self, name, context=undefined): - return getattr(self._impl_getopt(), name) + def __getattr__(self, + name, + context=undefined): + return getattr(self.impl_getopt(), name) def impl_getname(self): return self._name def impl_get_display_name(self): - return self._impl_getopt().impl_get_display_name(dyn_name=self.impl_getname()) + return self.impl_getopt().impl_get_display_name(dyn_name=self.impl_getname()) - def _impl_getopt(self): + def impl_getopt(self): return self._opt def impl_getsuffix(self): - return self._dyn.split('.')[-1][len(self._impl_getopt().impl_getname()):] + return self._dyn.split('.')[-1][len(self.impl_getopt().impl_getname()):] - def impl_getpath(self, context): - path = self._impl_getopt().impl_getpath(context) + def impl_getpath(self, + context): + path = self.impl_getopt().impl_getpath(context) base_path = '.'.join(path.split('.')[:-2]) if self.impl_is_master_slaves() and base_path is not '': base_path = base_path + self.impl_getsuffix() @@ -672,14 +682,16 @@ class DynSymLinkOption(object): display_warnings=True, multi=None, setting_properties=undefined): - return self._impl_getopt().impl_validate(value, context, validate, - force_index, - current_opt=self, - is_multi=is_multi, - display_error=display_error, - display_warnings=display_warnings, - multi=multi, - setting_properties=setting_properties) + return self.impl_getopt().impl_validate(value, + context, + validate, + force_index, + current_opt=self, + is_multi=is_multi, + display_error=display_error, + display_warnings=display_warnings, + multi=multi, + setting_properties=setting_properties) def impl_is_dynsymlinkoption(self): return True diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index aa0535f..76207c0 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -605,7 +605,7 @@ class Option(OnlyOption): return #consistencies is something like [('_cons_not_equal', (opt1, opt2))] if isinstance(option, DynSymLinkOption): - consistencies = descr._cache_consistencies.get(option._impl_getopt()) + consistencies = descr._cache_consistencies.get(option.impl_getopt()) else: consistencies = descr._cache_consistencies.get(option) else: @@ -618,7 +618,7 @@ class Option(OnlyOption): #all_cons_opts[0] is the option where func is set if isinstance(option, DynSymLinkOption): subpath = '.'.join(option._dyn.split('.')[:-1]) - namelen = len(option._impl_getopt().impl_getname()) + namelen = len(option.impl_getopt().impl_getname()) suffix = option.impl_getname()[namelen:] opts = [] for opt in all_cons_opts: @@ -640,7 +640,11 @@ class Option(OnlyOption): if err: return err - def _cons_not_equal(self, current_opt, opts, vals, warnings_only): + def _cons_not_equal(self, + current_opt, + opts, + vals, + warnings_only): equal = set() is_current = False for idx_inf, val_inf in enumerate(vals): @@ -669,11 +673,17 @@ class Option(OnlyOption): equal_name.append(opt.impl_get_display_name()) return ValueError(msg.format(display_list(list(equal_name)))) - def _second_level_validation(self, value, warnings_only): + def _second_level_validation(self, + value, + warnings_only): pass - def _impl_to_dyn(self, name, path): - return DynSymLinkOption(name, self, dyn=path) + def _impl_to_dyn(self, + name, + path): + return DynSymLinkOption(name, + self, + dyn=path) def impl_getdefault_multi(self): "accessing the default value for a multi" @@ -683,7 +693,9 @@ class Option(OnlyOption): default_value = None return getattr(self, '_default_multi', default_value) - def _validate_callback(self, callback, callback_params): + def _validate_callback(self, + callback, + callback_params): """callback_params: * None * {'': ((option, permissive),), 'ip': ((None,), (option, permissive)) @@ -712,7 +724,8 @@ class Option(OnlyOption): default = list(default) return default - def _get_extra(self, key): + def _get_extra(self, + key): extra = self._extra if isinstance(extra, tuple): return extra[1][extra[0].index(key)] @@ -751,14 +764,13 @@ class Option(OnlyOption): class RegexpOption(Option): __slots__ = tuple() - def _validate(self, value, context=undefined, current_opt=undefined): + def _validate(self, + value, + context=undefined, + current_opt=undefined): err = self._impl_valid_unicode(value) if err: return err match = self._regexp.search(value) if not match: return ValueError() - - -#FIXME compatibility -_RegexpOption = RegexpOption diff --git a/tiramisu/option/optiondescription.py b/tiramisu/option/optiondescription.py index 917782c..f9a75bf 100644 --- a/tiramisu/option/optiondescription.py +++ b/tiramisu/option/optiondescription.py @@ -43,8 +43,12 @@ del(sys) class CacheOptionDescription(BaseOption): __slots__ = ('_cache_paths', '_cache_consistencies', '_cache_force_store_values') - def _build_cache(self, config, path='', _consistencies=None, - cache_option=None, force_store_values=None, + def _build_cache(self, + config, + path='', + _consistencies=None, + cache_option=None, + force_store_values=None, _dependencies=None): """validate duplicate option and set option has readonly option """ @@ -69,13 +73,16 @@ class CacheOptionDescription(BaseOption): subpath = path + '.' + option.impl_getname() if isinstance(option, OptionDescription): option._set_readonly() - option._build_cache(config, subpath, _consistencies, - cache_option, force_store_values, - _dependencies) + option._build_cache(config, + subpath, + _consistencies, + cache_option, + force_store_values, + _dependencies) else: option._set_readonly() is_multi = option.impl_is_multi() - if not option._is_symlinkoption() and 'force_store_value' in option.impl_getproperties(): + if not option.impl_is_symlinkoption() and 'force_store_value' in option.impl_getproperties(): force_store_values.append((subpath, option)) for func, all_cons_opts, params in option._get_consistencies(): option._valid_consistencies(all_cons_opts[1:], init=False) @@ -150,7 +157,9 @@ class CacheOptionDescription(BaseOption): def impl_already_build_caches(self): return getattr(self, '_cache_paths', None) is not None - def impl_build_force_store_values(self, config, force_store_values): + def impl_build_force_store_values(self, + config, + force_store_values): session = config._impl_values._p_.getsession() value_set = False for subpath, option in self._cache_force_store_values: @@ -174,8 +183,10 @@ class CacheOptionDescription(BaseOption): if value_set: config._impl_values._p_.commit() - def _build_cache_option(self, _currpath=None, cache_path=None, - cache_option=None): + def _build_cache_option(self, + _currpath=None, + cache_path=None, + cache_option=None): if self.impl_is_readonly() or (_currpath is None and getattr(self, '_cache_paths', None) is not None): # cache already set @@ -195,8 +206,9 @@ class CacheOptionDescription(BaseOption): cache_path.append(path) if option.impl_is_optiondescription(): _currpath.append(attr) - option._build_cache_option(_currpath, cache_path, - cache_option) + option._build_cache_option(_currpath, + cache_path, + cache_option) _currpath.pop() if save: _setattr = object.__setattr__ @@ -236,8 +248,8 @@ class OptionDescriptionWalk(CacheOptionDescription): option): name = option.impl_getname() if option._is_subdyn(): + found = False if byname.startswith(name): - found = False subdyn = option._subdyn() for suffix in subdyn._impl_get_suffixes( context): @@ -249,8 +261,8 @@ class OptionDescriptionWalk(CacheOptionDescription): option = option._impl_to_dyn(name + suffix, path) break - if not found: - return False + if not found: + return False else: if not byname == name: return False @@ -312,12 +324,18 @@ class OptionDescriptionWalk(CacheOptionDescription): return find_results return find_results - def _impl_st_getchildren(self, context, only_dyn=False): + def _impl_st_getchildren(self, + context, + only_dyn=False): for child in self._children[1]: if only_dyn is False or child.impl_is_dynoptiondescription(): yield(child) - def _getattr(self, name, suffix=undefined, context=undefined, dyn=True): + def _getattr(self, + name, + suffix=undefined, + context=undefined, + dyn=True): error = False if suffix is not undefined: if undefined in [suffix, context]: # pragma: no cover @@ -337,7 +355,8 @@ class OptionDescriptionWalk(CacheOptionDescription): else: return child else: - child = self._impl_search_dynchild(name, context=context) + child = self._impl_search_dynchild(name, + context=context) if child != []: return child error = True @@ -346,27 +365,35 @@ class OptionDescriptionWalk(CacheOptionDescription): 'in OptionDescription {1}' '').format(name, self.impl_getname())) - def impl_getpaths(self, include_groups=False, _currpath=None): + def impl_getpaths(self, + include_groups=False, + _currpath=None): """returns a list of all paths in self, recursively _currpath should not be provided (helps with recursion) """ - return _impl_getpaths(self, include_groups, _currpath) + return _impl_getpaths(self, + include_groups, + _currpath) - def impl_get_opt_by_path(self, path): + def impl_get_opt_by_path(self, + path): if getattr(self, '_cache_paths', None) is None: raise ConfigError(_('use impl_get_opt_by_path only with root OptionDescription')) if path not in self._cache_paths[1]: raise AttributeError(_('no option for path {0}').format(path)) return self._cache_paths[0][self._cache_paths[1].index(path)] - def impl_get_path_by_opt(self, opt): + def impl_get_path_by_opt(self, + opt): if getattr(self, '_cache_paths', None) is None: raise ConfigError(_('use impl_get_path_by_opt only with root OptionDescription')) if opt not in self._cache_paths[0]: raise AttributeError(_('no option {0} found').format(opt)) return self._cache_paths[1][self._cache_paths[0].index(opt)] - def _impl_getchildren(self, dyn=True, context=undefined): + def _impl_getchildren(self, + dyn=True, + context=undefined): for child in self._impl_st_getchildren(context): cname = child.impl_getname() if dyn and child.impl_is_dynoptiondescription(): @@ -380,32 +407,47 @@ class OptionDescriptionWalk(CacheOptionDescription): def impl_getchildren(self): return list(self._impl_getchildren()) - def __getattr__(self, name, context=undefined): - if name.startswith('_'): # or name.startswith('impl_'): - return object.__getattribute__(self, name) + def __getattr__(self, + name, + context=undefined): + if name.startswith('_'): + return object.__getattribute__(self, + name) if '.' in name: path = name.split('.')[0] subpath = '.'.join(name.split('.')[1:]) - return self.__getattr__(path, context=context).__getattr__(subpath, context=context) - return self._getattr(name, context=context) + return self.__getattr__(path, context=context).__getattr__(subpath, + context=context) + return self._getattr(name, + context=context) - def _impl_search_dynchild(self, name, context): + def _impl_search_dynchild(self, + name, + context): ret = [] - for child in self._impl_st_getchildren(context, only_dyn=True): + for child in self._impl_st_getchildren(context, + only_dyn=True): cname = child.impl_getname() if name.startswith(cname): for value in child._impl_get_suffixes(context): if name == cname + value: - return SynDynOptionDescription(child, name, value) + return SynDynOptionDescription(child, + name, + value) return ret - def _impl_get_dynchild(self, child, suffix): + def _impl_get_dynchild(self, + child, + suffix): name = child.impl_getname() + suffix path = self.impl_getname() + suffix + '.' + name if isinstance(child, OptionDescription): - return SynDynOptionDescription(child, name, suffix) + return SynDynOptionDescription(child, + name, + suffix) else: - return child._impl_to_dyn(name, path) + return child._impl_to_dyn(name, + path) class OptionDescription(OptionDescriptionWalk): @@ -414,12 +456,18 @@ class OptionDescription(OptionDescriptionWalk): """ __slots__ = ('_group_type',) - def __init__(self, name, doc, children, requires=None, properties=None): + def __init__(self, + name, + doc, + children, + requires=None, + properties=None): """ :param children: a list of options (including optiondescriptions) """ - super(OptionDescription, self).__init__(name, doc=doc, + super(OptionDescription, self).__init__(name, + doc=doc, requires=requires, properties=properties) child_names = [] @@ -453,12 +501,15 @@ class OptionDescription(OptionDescriptionWalk): def impl_getdoc(self): return self.impl_get_information('doc') - def impl_validate(self, *args, **kwargs): + def impl_validate(self, + *args, + **kwargs): """usefull for OptionDescription""" pass # ____________________________________________________________ - def impl_set_group_type(self, group_type): + def impl_set_group_type(self, + group_type): """sets a given group object to an OptionDescription :param group_type: an instance of `GroupType` or `MasterGroupType` @@ -474,7 +525,7 @@ class OptionDescription(OptionDescriptionWalk): raise Exception('please use MasterSlaves object instead of OptionDescription') children = self.impl_getchildren() for child in children: - if child._is_symlinkoption(): # pragma: optional cover + if child.impl_is_symlinkoption(): # pragma: optional cover raise ValueError(_("master group {0} shall not have " "a symlinkoption").format(self.impl_getname())) if not isinstance(child, Option): # pragma: optional cover @@ -540,7 +591,7 @@ class DynOptionDescription(OptionDescription): 'dynoptiondescription')) for chld in child._impl_getchildren(): chld._impl_setsubdyn(self) - if child._is_symlinkoption(): + if child.impl_is_symlinkoption(): raise ConfigError(_('cannot set symlinkoption in a ' 'dynoptiondescription')) child._impl_setsubdyn(self) @@ -586,7 +637,7 @@ class SynDynOptionDescription(object): return self._impl_getchildren() def impl_getpath(self, context): - path = self._impl_getopt().impl_getpath(context).split('.') + path = self.impl_getopt().impl_getpath(context).split('.') path[-1] += self._suffix path.append(self._name) return '.'.join(path) @@ -594,7 +645,7 @@ class SynDynOptionDescription(object): def impl_getpaths(self, include_groups=False, _currpath=None): return _impl_getpaths(self, include_groups, _currpath) - def _impl_getopt(self): + def impl_getopt(self): return self._opt @@ -624,7 +675,7 @@ class MasterSlaves(OptionDescription): slaves.append(child) child._add_dependency(self) for idx, child in enumerate(children): - if child._is_symlinkoption(): # pragma: optional cover + if child.impl_is_symlinkoption(): # pragma: optional cover raise ValueError(_("master group {0} shall not have " "a symlinkoption").format(self.impl_getname())) if not isinstance(child, Option): # pragma: optional cover diff --git a/tiramisu/option/usernameoption.py b/tiramisu/option/usernameoption.py index bbf860f..6adcd54 100644 --- a/tiramisu/option/usernameoption.py +++ b/tiramisu/option/usernameoption.py @@ -21,10 +21,10 @@ import re from ..i18n import _ -from .option import _RegexpOption +from .option import RegexpOption -class UsernameOption(_RegexpOption): +class UsernameOption(RegexpOption): __slots__ = tuple() #regexp build with 'man 8 adduser' informations _regexp = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$") diff --git a/tiramisu/setting.py b/tiramisu/setting.py index ffff3f3..8c310cf 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -208,6 +208,12 @@ owners.user = owners.Owner('user') """forced special owner when value is forced""" owners.forced = owners.Owner('forced') +"""meta + special owner when value comes from metaconfig""" +owners.meta = owners.Owner('meta') + + +forbidden_owners = (owners.default, owners.forced, owners.meta) # ____________________________________________________________ @@ -298,8 +304,16 @@ class Settings(object): ntime, index) if not is_cached: - props = self._p_.getproperties(path, - opt.impl_getproperties()) + meta = self._getcontext().cfgimpl_get_meta() + if meta is None: + props = self._p_.getproperties(path, + opt.impl_getproperties()) + else: + props = meta.cfgimpl_get_settings().getproperties(opt, + path, + setting_properties, + index=index, + apply_requires=False) if apply_requires: requires = self.apply_requires(opt, path, @@ -326,7 +340,10 @@ class Settings(object): def getpermissive(self, path): - return self._pp_.getpermissive(path) + meta = self._getcontext().cfgimpl_get_meta() + if meta is None: + return self._pp_.getpermissive(path) + return meta.cfgimpl_get_settings().getpermissive(path) def apply_requires(self, opt, @@ -481,13 +498,11 @@ class Settings(object): opt, path, properties): -# force=False): """save properties for specified path (never save properties if same has option properties) """ if self._getcontext().cfgimpl_get_meta() is not None: - raise ConfigError(_('cannot change global property with metaconfig')) - #if not force: + raise ConfigError(_('cannot change property with metaconfig')) forbidden_properties = forbidden_set_properties & properties if forbidden_properties: raise ConfigError(_('cannot add those properties: {0}').format( @@ -516,6 +531,8 @@ class Settings(object): it is better (faster) to set the path parameter instead of passing a :class:`tiramisu.option.Option()` object. """ + if self._getcontext().cfgimpl_get_meta() is not None: + raise ConfigError(_('cannot change permissive with metaconfig')) if not isinstance(permissives, frozenset): raise TypeError(_('permissive must be a frozenset')) forbidden_permissives = forbidden_set_permissives & permissives @@ -529,7 +546,12 @@ class Settings(object): #____________________________________________________________ # reset methods - def reset(self, opt=None, _path=None, all_properties=False): + def reset(self, + opt=None, + _path=None, + all_properties=False): + if self._getcontext().cfgimpl_get_meta() is not None: + raise ConfigError(_('cannot change property with metaconfig')) if all_properties and (_path or opt): # pragma: optional cover raise ValueError(_('opt and all_properties must not be set ' 'together in reset')) @@ -547,105 +569,63 @@ class Settings(object): def validate_properties(self, opt_or_descr, - is_descr, - check_frozen, path, - value=None, - force_permissive=False, - setting_properties=undefined, - self_properties=undefined, + setting_properties, index=None, - debug=False): + force_permissive=False): """ validation upon the properties related to `opt_or_descr` :param opt_or_descr: an option or an option description object :param force_permissive: behaves as if the permissive property was present - :param is_descr: we have to know if we are in an option description, - just because the mandatory property - doesn't exist here - - :param check_frozen: in the validation process, an option is to be modified, - the behavior can be different - (typically with the `frozen` property) """ # opt properties - if self_properties is not undefined: - if not isinstance(self_properties, frozenset): - raise Exception('pouet') - properties = self_properties - else: - properties = self.getproperties(opt_or_descr, - path, - setting_properties=setting_properties, - index=index) + properties = self.getproperties(opt_or_descr, + path, + setting_properties=setting_properties, + index=index) # calc properties - properties &= setting_properties - if not is_descr: + properties &= setting_properties - set(['frozen']) + if not opt_or_descr.impl_is_optiondescription(): #mandatory - if 'mandatory' in properties and \ - not self._getcontext().cfgimpl_get_values().isempty(opt_or_descr, - value, - index=index): - properties.remove('mandatory') - elif 'empty' in properties and \ - 'empty' in setting_properties and \ - self._getcontext().cfgimpl_get_values().isempty(opt_or_descr, - value, - force_allow_empty_list=True, - index=index): - properties.add('mandatory') - # should return 'frozen' only when tried to modify a value - if check_frozen and 'everything_frozen' in setting_properties: - properties.add('frozen') - elif 'frozen' in properties and not check_frozen: - properties.remove('frozen') - if 'empty' in properties: - properties.remove('empty') + if 'mandatory' in properties or 'empty' in properties: + value = 'pouet' + if self.validate_mandatory(opt_or_descr, index, value, properties): + properties += set(['mandatory']) - set(['empty']) + else: + properties -= set(['mandatory', 'empty']) + opt_type = 'option' + else: + opt_type = 'optiondescription' # remove permissive properties - if properties != frozenset() and (force_permissive is True or - 'permissive' in setting_properties): + if force_permissive is True and properties: # remove global permissive if need properties -= self.get_context_permissive() # at this point an option should not remain in properties if properties != frozenset(): - props = list(properties) datas = {'opt': opt_or_descr, 'path': path, 'setting_properties': setting_properties, 'index': index, 'debug': True} - if is_descr: - opt_type = 'optiondescription' - else: - opt_type = 'option' - if 'frozen' in properties: - raise PropertiesOptionError(_('cannot change the value for ' - 'option "{0}" this option is' - ' frozen').format( - opt_or_descr.impl_getname()), - props, - self, - datas, - opt_type) - else: - if len(props) == 1: - prop_msg = _('property') - else: - prop_msg = _('properties') - raise PropertiesOptionError(_('cannot access to {0} "{1}" ' - 'because has {2} {3}' - '').format(opt_type, - opt_or_descr.impl_get_display_name(), - prop_msg, - display_list(props)), - props, - self, - datas, - opt_type) + raise PropertiesOptionError(None, + properties, + self, + datas, + opt_type) + + def validate_mandatory(self, opt, index, value, properties): + values = self._getcontext().cfgimpl_get_values() + return 'mandatory' in properties and values.isempty(opt, + value, + index=index) or \ + 'empty' in properties and values.isempty(opt, + value, + force_allow_empty_list=True, + index=index) #____________________________________________________________ # read only/read write diff --git a/tiramisu/storage/dictionary/storage.py b/tiramisu/storage/dictionary/storage.py index e619e08..872a76c 100644 --- a/tiramisu/storage/dictionary/storage.py +++ b/tiramisu/storage/dictionary/storage.py @@ -44,7 +44,7 @@ class Storage(object): def __init__(self, session_id, persistent, test=False): if not test and session_id in _list_sessions: # pragma: optional cover - raise ConflictError(_('session already used')) + raise ConflictError(_('session "{}" already used').format(session_id)) if persistent: # pragma: optional cover raise ValueError(_('a dictionary cannot be persistent')) self.session_id = session_id diff --git a/tiramisu/storage/dictionary/value.py b/tiramisu/storage/dictionary/value.py index a0bfea5..7b54c2c 100644 --- a/tiramisu/storage/dictionary/value.py +++ b/tiramisu/storage/dictionary/value.py @@ -90,7 +90,14 @@ class Values(Cache): """if path has a value return: boolean """ - return path in self._values[0] + has_path = path in self._values[0] + if index is None: + return has_path + elif has_path: + path_idx = self._values[0].index(path) + indexes = self._values[1][path_idx] + return index in indexes + return False def reduce_index(self, path, index): """ @@ -199,29 +206,15 @@ class Values(Cache): path, default, index=None, - only_default=False, with_value=False): """get owner for a path return: owner object """ - if index is None: - if only_default: - if path in self._values[0]: - owner = undefined - else: - owner = default - else: - owner = self._getvalue(path, - 3, - index) - if owner is undefined: - owner = default - else: - owner = self._getvalue(path, - 3, - index) - if owner is undefined: - owner = default + owner = self._getvalue(path, + 3, + index) + if owner is undefined: + owner = default if with_value: return owner, self._getvalue(path, 2, diff --git a/tiramisu/storage/util.py b/tiramisu/storage/util.py index 5cf1fc7..89c5a73 100644 --- a/tiramisu/storage/util.py +++ b/tiramisu/storage/util.py @@ -38,7 +38,7 @@ class Cache(object): if DEBUG: global FIXME FIXME += 1 - print('ca set cache', path, val, POUET(self), FIXME) + print('ca set cache', path, val, POUET(self), FIXME, id(self)) #if path is not None and (path.startswith('od.st.') or path.startswith('od.dod.')): # raise Exception('mais ... mais ... mais') #if FIXME == 111: @@ -51,7 +51,7 @@ class Cache(object): if DEBUG: global FIXME FIXME += 1 - print('ca trouve dans le cache', path, value, POUET(self), FIXME) + print('ca trouve dans le cache', path, value, POUET(self), FIXME, id(self)) #if path is not None and (path.startswith('od.st.') or path.startswith('od.dod.')): # raise Exception('mais ... mais ... mais') #if FIXME == 45: @@ -65,7 +65,7 @@ class Cache(object): if DEBUG: global FIXME FIXME += 1 - print('ca del cache', path, POUET(self), FIXME) + print('ca del cache', path, POUET(self), FIXME, id(self)) #if path is not None and (path.startswith('od.st.') or path.startswith('od.dod.')): # raise Exception('mais ... mais ... mais') #if FIXME == 23: @@ -79,7 +79,7 @@ class Cache(object): :param path: the path's option """ if DEBUG: - print('ca cherche dans le cache', path, POUET(self)) + print('ca cherche dans le cache', path, POUET(self), id(self)) return path in self._cache and index in self._cache[path] def reset_expired_cache(self, exp): @@ -96,7 +96,7 @@ class Cache(object): def reset_all_cache(self): "empty the cache" if DEBUG: - print('bzzzzzzzzzzzz delete tout le cache', POUET(self)) + print('bzzzzzzzzzzzz delete tout le cache', POUET(self), id(self)) self._cache.clear() def get_cached(self): diff --git a/tiramisu/value.py b/tiramisu/value.py index b4bda24..7192fc4 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -19,7 +19,7 @@ from time import time import sys import weakref from .error import ConfigError, SlaveError, PropertiesOptionError -from .setting import owners, expires_time, undefined +from .setting import owners, expires_time, undefined, forbidden_owners from .autolib import carry_out_calculation from .i18n import _ from .option import DynSymLinkOption, Option @@ -66,13 +66,10 @@ class Values(object): validate=True, force_permissive=False, trusted_cached_properties=True, - validate_properties=True, setting_properties=undefined, self_properties=undefined, index=None, - check_frozen=False, - display_warnings=True, - _orig_context=undefined): + display_warnings=True): context = self._getcontext() settings = context.cfgimpl_get_settings() if path is None: @@ -83,8 +80,7 @@ class Values(object): path, setting_properties=setting_properties, index=index) - if 'cache' in setting_properties and self._p_.hascache(path, index) and \ - _orig_context is undefined: + if 'cache' in setting_properties and self._p_.hascache(path, index): if 'expire' in setting_properties: ntime = int(time()) is_cached, value = self._p_.getcache(path, @@ -93,36 +89,18 @@ class Values(object): if index: value = value[index] if is_cached: - if not trusted_cached_properties: - # revalidate properties (because of not default properties) - settings.validate_properties(opt, - False, - False, - value=value, - path=path, - force_permissive=force_permissive, - setting_properties=setting_properties, - self_properties=self_properties, - index=index) return value - if _orig_context is not undefined: - _context = _orig_context - else: - _context = context val = self.get_validated_value(opt, path, validate, - force_permissive, - validate_properties, setting_properties, self_properties, index=index, - check_frozen=check_frozen, display_warnings=display_warnings, - _orig_context=_context) + force_permissive=force_permissive) if index is None and 'cache' in setting_properties and \ - validate and validate_properties and force_permissive is False \ - and trusted_cached_properties is True and _orig_context is undefined: + validate and force_permissive is False \ + and trusted_cached_properties is True: if 'expire' in setting_properties: if ntime is None: ntime = int(time()) @@ -134,27 +112,24 @@ class Values(object): opt, path, validate, - force_permissive, - validate_properties, setting_properties, - self_properties, + self_properties=None, index=None, - check_frozen=False, display_warnings=True, - _orig_context=undefined): + force_permissive=False): """same has getitem but don't touch the cache index is None for slave value, if value returned is not a list, just return [] """ context = self._getcontext() - setting = context.cfgimpl_get_settings() config_error = None try: value = self.getvalue(opt, path, - self_properties, index, + setting_properties, + self_properties, validate, - _orig_context) + force_permissive=force_permissive) except ConfigError as value: value_error = True # For calculating properties, we need value (ie for mandatory @@ -181,23 +156,6 @@ class Values(object): if err: config_error = err value = None - - if validate_properties: - if config_error is not None: - # should not raise PropertiesOptionError if option is - # mandatory - val_props = undefined - else: - val_props = value - setting.validate_properties(opt, - False, - check_frozen, - value=val_props, - path=path, - force_permissive=force_permissive, - setting_properties=setting_properties, - self_properties=self_properties, - index=index) if not value_error and validate and display_warnings: opt.impl_validate(value, context, @@ -213,10 +171,11 @@ class Values(object): def getvalue(self, opt, path, - self_properties, index, + setting_properties, + self_properties, validate, - _orig_context): + force_permissive=False): """actually retrieves the value :param opt: the `option.Option()` object @@ -231,7 +190,6 @@ class Values(object): _index = index owner, value = self._p_.getowner(path, owners.default, - only_default=True, index=_index, with_value=True) is_default = owner == owners.default @@ -247,11 +205,13 @@ class Values(object): path, index, validate, - _orig_context) + setting_properties, + force_permissive=force_permissive) def getdefaultvalue(self, opt, path, + setting_properties=undefined, index=None): """get default value: - get meta config value or @@ -267,43 +227,45 @@ class Values(object): return self._getdefaultvalue(opt, path, index, - True, - self._getcontext()) + True) def _getdefaultvalue(self, opt, path, index, validate, - _orig_context): + setting_properties, + force_permissive=False): + context = self._getcontext() def _reset_cache(): # calculated value could be a new value, so reset cache - _orig_context.cfgimpl_reset_cache(opt=opt, - path=path) + context.cfgimpl_reset_cache(opt=opt, + path=path) - #FIXME with_meta should be calculated here... - with_meta = True - if with_meta: - meta = self._getcontext().cfgimpl_get_meta() - if meta is not None: - # retrieved value from meta config - try: - value = meta.cfgimpl_get_values().get_cached_value(opt, - path, - index=index, - _orig_context=_orig_context) - except PropertiesOptionError: - # if properties error, return an other default value - # unexpected error, should not happened - pass - else: - return value + if self._is_meta(opt, + path, + index, + setting_properties, + force_permissive=force_permissive): + meta = context.cfgimpl_get_meta() + # retrieved value from meta config + try: + value = meta.getattr(path, + index=index, + setting_properties=setting_properties, + force_permissive=force_permissive) + except PropertiesOptionError: + # if properties error, return an other default value + # unexpected error, should not happened + pass + else: + return value if opt.impl_has_callback(): # if value has callback, calculate value callback, callback_params = opt.impl_get_callback() value = carry_out_calculation(opt, - context=_orig_context, + context=context, callback=callback, callback_params=callback_params, index=index, @@ -444,15 +406,37 @@ class Values(object): index): context = self._getcontext() + settings = context.cfgimpl_get_settings() # First validate properties with this value - context.cfgimpl_get_settings().validate_properties(opt, - False, - True, - value=value, - path=path, - force_permissive=force_permissive, - setting_properties=setting_properties, - index=index) + properties = settings.getproperties(opt, + path, + setting_properties=setting_properties, + index=index) + if 'everything_frozen' in setting_properties or 'frozen' in properties: + datas = {'opt': opt, + 'path': path, + 'setting_properties': setting_properties, + 'index': index, + 'debug': True} + raise PropertiesOptionError(None, + ['frozen'], + settings, + datas, + 'option') + if settings.validate_mandatory(opt, + index, + value, + properties): + datas = {'opt': opt, + 'path': path, + 'setting_properties': setting_properties, + 'index': index, + 'debug': True} + raise PropertiesOptionError(None, + ['mandatory'], + settings, + datas, + 'option') # Value must be valid for option opt.impl_validate(value, context, @@ -488,17 +472,32 @@ class Values(object): def _is_meta(self, opt, path, + index, setting_properties, - force_permissive=False): - context = self._getcontext() - if context.cfgimpl_get_meta() is None: + force_permissive=False, + force_owner_is_default=False): + + if not force_owner_is_default and self._p_.hasvalue(path, + index=index): + # has already a value, so not meta return False - return self.is_default_owner(opt, - path, - setting_properties, - validate_meta=False, - index=None, - force_permissive=force_permissive) + context = self._getcontext() + meta = context.cfgimpl_get_meta() + if meta is None: + return False + if opt.impl_is_master_slaves('slave'): + master = opt.impl_get_master_slaves().getmaster(opt) + masterp = master.impl_getpath(context) + # slave could be a "meta" only if master hasn't value + if self._p_.hasvalue(masterp, + index=index): + return False + return not meta.cfgimpl_get_values().is_default_owner(opt, + path, + setting_properties, + index=index, + force_permissive=force_permissive) + #______________________________________________________________________ # owner @@ -517,9 +516,9 @@ class Values(object): was present :returns: a `setting.owners.Owner` object """ - if opt._is_symlinkoption() and \ + if opt.impl_is_symlinkoption() and \ not isinstance(opt, DynSymLinkOption): - opt = opt._impl_getopt() + opt = opt.impl_getopt() return self._getowner(opt, path, setting_properties, @@ -537,6 +536,9 @@ class Values(object): index=None): """get owner of an option """ + #FIXME: validate_meta ne marche que si == False ou undefined ! + if validate_meta is not False and validate_meta is not undefined: + raise Exception('poeut') if not isinstance(opt, Option) and not isinstance(opt, DynSymLinkOption): raise ConfigError(_('owner only avalaible for an option')) @@ -547,30 +549,26 @@ class Values(object): setting_properties) if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties: return owners.default - owner = self._p_.getowner(path, - owners.default, - only_default=only_default, - index=index) - if validate_meta is undefined: - if opt.impl_is_master_slaves('slave'): - master = opt.impl_get_master_slaves().getmaster(opt) - masterp = master.impl_getpath(context) - validate_meta = self._is_meta(master, - masterp, - setting_properties, - force_permissive=force_permissive) + if only_default: + if self._p_.hasvalue(path, + index): + owner = undefined else: - validate_meta = True - if validate_meta and owner is owners.default: - meta = context.cfgimpl_get_meta() - if meta is not None: - owner = meta.cfgimpl_get_values()._getowner(opt, - path, - setting_properties, - force_permissive=force_permissive, - self_properties=self_properties, - only_default=only_default, - index=index) + owner = owners.default + else: + owner = self._p_.getowner(path, + owners.default, + index=index) + if owner is owners.default and validate_meta is not False: + if validate_meta is undefined: + validate_meta = self._is_meta(opt, + path, + index, + setting_properties, + force_permissive=force_permissive, + force_owner_is_default=True) + if validate_meta: + owner = owners.meta return owner def setowner(self, @@ -584,7 +582,10 @@ class Values(object): :param owner: a valid owner, that is a `setting.owners.Owner` object """ if not isinstance(owner, owners.Owner): - raise TypeError(_("invalid generic owner {0}").format(str(owner))) + raise TypeError(_("invalid owner {0}").format(str(owner))) + + if owner in forbidden_owners: + raise ConfigError(_('set owner "{0}" is forbidden').format(str(owner))) if not self._p_.hasvalue(path): raise ConfigError(_('no value for {0} cannot change owner to {1}' @@ -595,7 +596,7 @@ class Values(object): opt, path, setting_properties, - validate_meta=True, + validate_meta=undefined, self_properties=undefined, index=None, force_permissive=False): @@ -631,13 +632,12 @@ class Values(object): path, setting_properties, validate=False) - ret = fake_value.get_cached_value(opt, - path, - setting_properties=setting_properties, - check_frozen=True, - force_permissive=force_permissive) - if isinstance(ret, Exception): - raise ret + #FIXME ce n'est pas deja fait dans le reset ? + #sinon c'est un validate_properties qu'il faut faire ... + #fake_value.get_cached_value(opt, + # path, + # setting_properties=setting_properties, + # force_permissive=force_permissive) if opt.impl_is_master_slaves('master'): opt.impl_get_master_slaves().reset(opt, self, @@ -653,7 +653,7 @@ class Values(object): path, None, validate, - context) + setting_properties) self._setvalue(opt, path, value, @@ -687,7 +687,6 @@ class Values(object): path, index=index, setting_properties=setting_properties, - check_frozen=True, force_permissive=force_permissive) self._p_.resetvalue_index(path, index) @@ -702,7 +701,6 @@ class Values(object): current_value = self.get_cached_value(opt, path, setting_properties=setting_properties, - check_frozen=True, force_permissive=force_permissive) current_value.pop(index) self.setvalue(opt, @@ -772,13 +770,14 @@ class Values(object): path = '.'.join(currpath + [name]) if opt.impl_is_optiondescription(): + #FIXME ? if not settings.validate_properties(opt, True, False, path=path, force_permissive=True, setting_properties=setting_properties): for path in _mandatory_warnings(opt, currpath + [name]): yield path else: - if opt._is_symlinkoption() and \ + if opt.impl_is_symlinkoption() and \ not isinstance(opt, DynSymLinkOption): continue self_properties = settings.getproperties(opt,