From 6921e05c0ea875c74f84831e314e43e634b9b476 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Sat, 24 Mar 2018 22:37:48 +0100 Subject: [PATCH] corrections in dynoption/masterslaves --- test/api/test_multi.py | 206 --------------------- test/{api => auto}/__init__.py | 0 test/{api => auto}/autopath.py | 0 test/{api => auto}/test_owner.py | 0 test/test_option_validator.py | 18 +- test/test_parsing_group.py | 27 +++ tiramisu/api.py | 10 +- tiramisu/config.py | 20 +- tiramisu/error.py | 2 +- tiramisu/option/masterslave.py | 2 +- tiramisu/option/option.py | 4 +- tiramisu/option/optiondescription.py | 14 +- tiramisu/option/syndynoptiondescription.py | 18 +- tiramisu/setting.py | 2 - tiramisu/storage/dictionary/value.py | 12 +- tiramisu/storage/util.py | 33 +--- tiramisu/value.py | 46 +++-- 17 files changed, 115 insertions(+), 299 deletions(-) delete mode 100644 test/api/test_multi.py rename test/{api => auto}/__init__.py (100%) rename test/{api => auto}/autopath.py (100%) rename test/{api => auto}/test_owner.py (100%) diff --git a/test/api/test_multi.py b/test/api/test_multi.py deleted file mode 100644 index 9695a0b..0000000 --- a/test/api/test_multi.py +++ /dev/null @@ -1,206 +0,0 @@ -"""test consistencies about multi and submulti""" -from py.test import raises -from .autopath import do_autopath -do_autopath() -from tiramisu.setting import groups -from tiramisu import Config, StrOption, IntOption, OptionDescription, MasterSlaves, getapi, \ - submulti, undefined -from tiramisu.error import PropertiesOptionError - - -def return_val(val=None): - if val is None: - return 'val' - else: - return val - - -def return_list(value=None): - return ['val', 'val'] - - -def return_list2(value=None): - return [['val', 'val']] - - -def test_multi_unique(): - int_ = IntOption('int', '', multi=True, unique=True) - od_ = OptionDescription('od', '', [int_]) - cfg = Config(od_) - api = getapi(cfg) - assert api.option('int').value.get() == [] - value = [0] - api.option('int').value.set(value) - assert api.option('int').value.get() == value - value.append(1) - assert api.option('int').value.get() == [0] - raises(ValueError, "api.option('int').value.set([0, 0])") - raises(ValueError, "api.option('int').value.set([1, 0, 2, 3, 4, 5, 6, 0, 7])") - - -def test_multi_none(): - str_ = StrOption('str', '', multi=True) - od_ = OptionDescription('od', '', [str_]) - cfg = Config(od_) - cfg.read_only() - api = getapi(cfg) - assert api.option('str').value.get() == [] - cfg.read_write() - api.option('str').value.set([None]) - assert api.option('str').value.get() == [None] - cfg.read_only() - raises(PropertiesOptionError, "api.option('str').value.get()") - cfg.read_write() - api.option('str').value.set(['']) - assert api.option('str').value.get() == [''] - cfg.read_only() - raises(PropertiesOptionError, "api.option('str').value.get()") - - -# ______________ submulti ______________ - -def test_append_submulti(): - multi = StrOption('multi', '', multi=submulti) - multi2 = StrOption('multi2', '', default_multi=['yes'], multi=submulti) - multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) - od_ = OptionDescription('od', '', [multi, multi2, multi3]) - cfg = Config(od_) - api = getapi(cfg) - #FIXME - owner = cfg.cfgimpl_get_settings().getowner() - assert api.option('multi').value.get() == [] - assert api.option('multi').value.get() == [] - assert api.option('multi').owner.isdefault() - api.option('multi').value.set([undefined]) - assert api.option('multi').owner.get() == owner - value = api.option('multi').value.get() - assert value == [[]] - value.append(['no']) - assert api.option('multi').value.get() == [[]] - api.option('multi').value.set(value) - assert api.option('multi').value.get() == [[], ['no']] - # - assert api.option('multi2').value.get() == [] - assert api.option('multi2').owner.isdefault() - api.option('multi2').value.set([undefined]) - assert api.option('multi2').owner.get() == owner - assert api.option('multi2').value.get() == [['yes']] - api.option('multi2').value.set([['yes'], ['no']]) - assert api.option('multi2').value.get() == [['yes'], ['no']] - # - assert api.option('multi3').value.get() == [['yes']] - assert api.option('multi3').owner.isdefault() - api.option('multi3').value.set([['yes'], undefined]) - assert api.option('multi3').owner.get() == owner - assert api.option('multi3').value.get() == [['yes'], []] - api.option('multi3').value.set([['yes'], [], ['no']]) - assert api.option('multi3').value.get() == [['yes'], [], ['no']] - - -def test_append_unvalide_submulti(): - multi = StrOption('multi', '', multi=submulti) - multi2 = StrOption('multi2', '', default_multi=['yes'], multi=submulti) - multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti) - od_ = OptionDescription('od', '', [multi, multi2, multi3]) - cfg = Config(od_) - api = getapi(cfg) - assert api.option('multi').value.get() == [] - assert api.option('multi').owner.isdefault() - raises(ValueError, "api.option('multi').value.set([1])") - assert api.option('multi').value.get() == [] - assert api.option('multi').owner.isdefault() - # - assert api.option('multi2').value.get() == [] - raises(ValueError, "api.option('multi2').value.set('no')") - assert api.option('multi2').owner.isdefault() - assert api.option('multi2').value.get() == [] - # - assert api.option('multi3').value.get() == [['yes']] - assert api.option('multi3').owner.isdefault() - - -def test_submulti_unique(): - int_ = IntOption('int', '', multi=submulti, unique=True) - od_ = OptionDescription('od', '', [int_]) - cfg = Config(od_) - api = getapi(cfg) - assert api.option('int').value.get() == [] - api.option('int').value.set([[0]]) - assert api.option('int').value.get() == [[0]] - raises(ValueError, "api.option('int').value.set([[0, 0]])") - api.option('int').value.set([[0], [0]]) - raises(ValueError, "api.option('int').value.set([[0], [1, 0, 2, 3, 4, 5, 6, 0, 7]])") - - -def test_callback_reset(): - multi = StrOption('multi', '', multi=submulti, callback=return_val) - od_ = OptionDescription('od', '', [multi]) - cfg = Config(od_) - cfg.read_write() - api = getapi(cfg) - #FIXME - owner = cfg.cfgimpl_get_settings().getowner() - assert api.option('multi').value.get() == [['val']] - assert api.option('multi').owner.isdefault() - api.option('multi').value.set([['val'], undefined]) - assert api.option('multi').owner.get() == owner - assert api.option('multi').value.get() == [['val'], ['val']] - api.option('multi').value.reset() - assert api.option('multi').owner.isdefault() - assert api.option('multi').value.get() == [['val']] - api.option('multi').value.set([['val1']]) - assert api.option('multi').owner.get() == owner - assert api.option('multi').value.get() == [['val1']] - - -def test_callback_submulti_list(): - multi = StrOption('multi', '', multi=submulti, callback=return_list) - od_ = OptionDescription('od', '', [multi]) - cfg = Config(od_) - cfg.read_write() - api = getapi(cfg) - owner = cfg.cfgimpl_get_settings().getowner() - assert api.option('multi').value.get() == [['val', 'val']] - assert api.option('multi').owner.isdefault() - api.option('multi').value.set([['val', 'val'], undefined]) - assert api.option('multi').owner.get() == owner - assert api.option('multi').value.get() == [['val', 'val'], ['val', 'val']] - api.option('multi').value.set([['val', 'val'], undefined, undefined]) - assert api.option('multi').value.get() == [['val', 'val'], ['val', 'val'], ['val', 'val']] - api.option('multi').value.reset() - assert api.option('multi').owner.isdefault() - - -def test_callback_submulti_list_list(): - multi = StrOption('multi', '', multi=submulti, callback=return_list2) - od = OptionDescription('od', '', [multi]) - cfg = Config(od) - cfg.read_write() - api = getapi(cfg) - owner = api.owner.get() - assert owner == 'user' - assert api.option('multi').value.get() == [['val', 'val']] - assert api.option('multi').owner.isdefault() - api.option('multi').value.set([['val', 'val'], undefined]) - assert api.option('multi').owner.get() == owner - assert api.option('multi').value.get() == [['val', 'val'], []] - api.option('multi').value.reset() - assert api.option('multi').owner.isdefault() - - -#FIXME -#def test_multi_submulti_meta(): -# multi = StrOption('multi', '', multi=submulti) -# od = OptionDescription('od', '', [multi]) -# conf1 = Config(od, session_id='conf1') -# conf1.read_write() -# conf2 = Config(od, session_id='conf2') -# conf2.read_write() -# meta = MetaConfig([conf1, conf2]) -# meta.read_write() -# meta.multi = [['val']] -# assert meta.multi == [['val']] -# multi = conf1.multi[0] -# multi.append() -# assert conf1.multi == [['val', None]] -# assert meta.multi == [['val']] diff --git a/test/api/__init__.py b/test/auto/__init__.py similarity index 100% rename from test/api/__init__.py rename to test/auto/__init__.py diff --git a/test/api/autopath.py b/test/auto/autopath.py similarity index 100% rename from test/api/autopath.py rename to test/auto/autopath.py diff --git a/test/api/test_owner.py b/test/auto/test_owner.py similarity index 100% rename from test/api/test_owner.py rename to test/auto/test_owner.py diff --git a/test/test_option_validator.py b/test/test_option_validator.py index bfb3422..8289d42 100644 --- a/test/test_option_validator.py +++ b/test/test_option_validator.py @@ -343,7 +343,7 @@ def test_validator_warning(): with warnings.catch_warnings(record=True) as w: api.option('opt2').value.set('val') assert len(w) == 1 - assert w[0].message.opt == opt2 + assert w[0].message.opt() == opt2 assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error return_false') # with warnings.catch_warnings(record=True) as w: @@ -353,7 +353,7 @@ def test_validator_warning(): with warnings.catch_warnings(record=True) as w: api.option('opt3').value.set(['val', 'val1']) assert len(w) == 1 - assert w[0].message.opt == opt3 + assert w[0].message.opt() == opt3 assert str(w[0].message) == msg_err.format('val1', opt3._display_name, 'opt3', 'test error') # with warnings.catch_warnings(record=True) as w: @@ -364,9 +364,9 @@ def test_validator_warning(): api.option('opt2').value.set('val') api.option('opt3').value.set(['val', 'val1', 'val']) assert len(w) == 2 - assert w[0].message.opt == opt2 + assert w[0].message.opt() == opt2 assert str(w[0].message) == msg_err.format('val', opt2._display_name, 'opt2', 'test error return_false') - assert w[1].message.opt == opt3 + assert w[1].message.opt() == opt3 assert str(w[1].message) == msg_err.format('val1', opt3._display_name, 'opt3', 'test error') @@ -420,27 +420,27 @@ def test_validator_warning_master_slave(): with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('val1') assert len(w) == 1 - assert w[0].message.opt == netmask_admin_eth0 + assert w[0].message.opt() == netmask_admin_eth0 assert str(w[0].message) == msg_err.format('val1', netmask_admin_eth0._display_name, display_name_netmask, 'test error') # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val']) assert len(w) == 1 - assert w[0].message.opt == ip_admin_eth0 + assert w[0].message.opt() == ip_admin_eth0 assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val', 'val1', 'val1']) #FIXME #assert len(w) == 1 - assert w[0].message.opt == ip_admin_eth0 + assert w[0].message.opt() == ip_admin_eth0 assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') # with warnings.catch_warnings(record=True) as w: api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val', 'val1']) #FIXME #assert len(w) == 1 - assert w[0].message.opt == ip_admin_eth0 + assert w[0].message.opt() == ip_admin_eth0 assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') # warnings.resetwarnings() @@ -448,7 +448,7 @@ def test_validator_warning_master_slave(): api.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val1', 'val']) #FIXME #assert len(w) == 1 - assert w[0].message.opt == ip_admin_eth0 + assert w[0].message.opt() == ip_admin_eth0 assert str(w[0].message) == msg_err.format('val', ip_admin_eth0._display_name, display_name_ip, 'test error return_false') diff --git a/test/test_parsing_group.py b/test/test_parsing_group.py index 09de269..75ac710 100644 --- a/test/test_parsing_group.py +++ b/test/test_parsing_group.py @@ -222,6 +222,33 @@ def test_groups_with_master_hidden_in_config2(): assert api.forcepermissive.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None +def test_groups_with_master_reset_empty(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od_ = OptionDescription('root', '', [interface1]) + api = getapi(Config(od_)) + api.property.read_write() + api.option('ip_admin_eth0.ip_admin_eth0').value.reset() + raises(SlaveError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset()") + api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset() + + +def test_groups_with_master_reset_out_of_range(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True) + interface1 = MasterSlaves('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + od_ = OptionDescription('root', '', [interface1]) + api = getapi(Config(od_)) + api.property.read_write() + api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.1']) + api.forcepermissive.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.0') + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.reset() + raises(SlaveError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.reset()") + raises(IndexError, "api.option('ip_admin_eth0.ip_admin_eth0').value.pop(1)") + + def test_groups_with_master_hidden_in_config3(): #if master is hidden, slave are hidden too ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True, properties=('hidden',)) diff --git a/tiramisu/api.py b/tiramisu/api.py index 61de93b..74622b6 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -33,7 +33,7 @@ except: COUNT_TIME = False -COUNT_TIME = {} +#COUNT_TIME = {} def count(func): @@ -120,9 +120,11 @@ class CommonTiramisuOption(CommonTiramisu): def _test_slave_index(self): option = self._get_option() - if not option.impl_is_optiondescription() and self.index is None and \ - option.impl_is_master_slaves('slave'): - raise APIError('index must be set with a slave option') + if not option.impl_is_optiondescription(): + if self.index is None and option.impl_is_master_slaves('slave'): + raise APIError('index must be set with a slave option') + elif self.index is not None and not option.impl_is_master_slaves('slave'): + raise APIError('index must be set only with a slave option') def _unrestraint_not_allowed(self, force_unrestraint): if force_unrestraint: diff --git a/tiramisu/config.py b/tiramisu/config.py index 5ff07b0..ab98a34 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -83,7 +83,7 @@ class SubConfig(object): self._impl_length = len(value) def cfgimpl_get_length(self): - return getattr(self, '_impl_length') + return self._impl_length def reset_one_option_cache(self, values, @@ -334,9 +334,6 @@ class SubConfig(object): name, index, config_bag): - - - context = self._cfgimpl_get_context() if '.' in name: # pragma: optional cover self, name = self.cfgimpl_get_home_by_path(name, config_bag) @@ -358,6 +355,12 @@ class SubConfig(object): index, config_bag) elif option.impl_is_master_slaves('slave'): + length = self.cfgimpl_get_length() + if index >= length: + raise SlaveError(_('index "{}" is higher than the master length "{}" ' + 'for option "{}"').format(index, + length, + option.impl_get_display_name())) values.reset_slave(subpath, index, config_bag) @@ -387,7 +390,6 @@ class SubConfig(object): otherwise """ if '.' in name: - # raise Exception('je suis desole ...') self, name = self.cfgimpl_get_home_by_path(name, config_bag) @@ -425,7 +427,7 @@ class SubConfig(object): if option.impl_is_master_slaves('slave'): if index is None and not iter_slave: - raise IndexError(_('index is mandatory for the slave "{}"' + raise SlaveError(_('index is mandatory for the slave "{}"' '').format(subpath)) length = self.cfgimpl_get_length() if index is not None and index >= length: @@ -441,7 +443,7 @@ class SubConfig(object): length, subpath)) elif index: - raise IndexError(_('index is forbidden for the not slave "{}"' + raise SlaveError(_('index is forbidden for the not slave "{}"' '').format(subpath)) if option.impl_is_master_slaves('slave') and index is None: value = [] @@ -649,8 +651,8 @@ 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")) + context = self._cfgimpl_get_context() if withoption is not None: - context = self._cfgimpl_get_context() for path in context._find(bytype=None, byname=withoption, byvalue=withvalue, @@ -685,7 +687,7 @@ class SubConfig(object): fullpath=fullpath) #withoption can be set to None below ! if withoption is None: - for opt in self.cfgimpl_get_description().impl_getchildren(config_bag): + for opt in self.cfgimpl_get_description().impl_getchildren(config_bag, context): sconfig_bag = config_bag.copy('nooption') sconfig_bag.option = opt path = opt.impl_getname() diff --git a/tiramisu/error.py b/tiramisu/error.py index aa2d073..aad4d1a 100644 --- a/tiramisu/error.py +++ b/tiramisu/error.py @@ -159,7 +159,7 @@ class ValueWarning(UserWarning): # pragma: optional cover >>> with warnings.catch_warnings(record=True) as w: ... c.s = 'val' ... - >>> w[0].message.opt == s + >>> w[0].message.opt() == s True >>> print(str(w[0].message)) invalid value val for option s: pouet diff --git a/tiramisu/option/masterslave.py b/tiramisu/option/masterslave.py index 9f3fa02..cee4a10 100644 --- a/tiramisu/option/masterslave.py +++ b/tiramisu/option/masterslave.py @@ -175,5 +175,5 @@ class MasterSlaves(OptionDescription): raise SlaveError(_('cannot reduce length of the master "{}"' '').format(option.impl_get_display_name())) - def impl_is_master_slaves(self): + def impl_is_master_slaves(self, *args, **kwargs): return True diff --git a/tiramisu/option/option.py b/tiramisu/option/option.py index 4541cf8..7463669 100644 --- a/tiramisu/option/option.py +++ b/tiramisu/option/option.py @@ -340,7 +340,7 @@ class Option(OnlyOption): if check_error: raise ValueError(msg) else: - warnings.warn_explicit(ValueWarning(msg, self), + warnings.warn_explicit(ValueWarning(msg, weakref.ref(self)), ValueWarning, self.__class__.__name__, 0) @@ -646,7 +646,7 @@ class Option(OnlyOption): self._display_name, current_opt.impl_get_display_name(), err) - warnings.warn_explicit(ValueWarning(msg, self), + warnings.warn_explicit(ValueWarning(msg, weakref.ref(self)), ValueWarning, self.__class__.__name__, 0) else: diff --git a/tiramisu/option/optiondescription.py b/tiramisu/option/optiondescription.py index 5953dc0..7966580 100644 --- a/tiramisu/option/optiondescription.py +++ b/tiramisu/option/optiondescription.py @@ -381,15 +381,23 @@ class OptionDescriptionWalk(CacheOptionDescription): def impl_getchildren(self, config_bag, + context=None, dyn=True): + cname = None for child in self._impl_st_getchildren(): - cname = child.impl_getname() if dyn and child.impl_is_dynoptiondescription(): + if context is None: + raise ConfigError(_('need context')) + if cname is None: + if context.cfgimpl_get_description() == self: + cname = '' + else: + cname = self.impl_getpath(context) sconfig_bag = config_bag.copy('nooption') sconfig_bag.option = child for value in child._impl_get_suffixes(sconfig_bag): yield SynDynOptionDescription(child, - cname + value, + cname, value) else: yield child @@ -478,7 +486,7 @@ class OptionDescription(OptionDescriptionWalk): # the group_type is useful for filtering OptionDescriptions in a config self._group_type = groups.default - def impl_is_master_slaves(self): + def impl_is_master_slaves(self, *args, **kwargs): return False def impl_getdoc(self): diff --git a/tiramisu/option/syndynoptiondescription.py b/tiramisu/option/syndynoptiondescription.py index 757c028..cbf53d5 100644 --- a/tiramisu/option/syndynoptiondescription.py +++ b/tiramisu/option/syndynoptiondescription.py @@ -68,10 +68,11 @@ class SynDynOptionDescription(object): config_bag, dyn=True): children = [] + subpath = self.impl_getpath() for child in self._opt.impl_getchildren(config_bag): yield(self._opt._impl_get_dynchild(child, self._suffix, - self._subpath)) + subpath)) def impl_getpath(self): subpath = self._subpath @@ -93,13 +94,8 @@ class SynDynOptionDescription(object): self._suffix) def pop(self, - values, - index, - setting_properties, - force_permissive, - slaves=undefined): - self._opt.pop(values, - index, - setting_properties, - force_permissive, - slaves=self.getslaves()) + *args, + **kwargs): + self._opt.pop(*args, + slaves=self.getslaves(), + **kwargs) diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 6f50311..6115163 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -567,7 +567,6 @@ class Settings(object): if self._getcontext().cfgimpl_get_meta() is not None: raise ConfigError(_('cannot change property with metaconfig')) if path is not None and config_bag.option.impl_getrequires() is not None: - print(properties, getattr(config_bag.option, '_calc_properties', static_set)) not_allowed_props = properties & getattr(config_bag.option, '_calc_properties', static_set) if not_allowed_props: if len(not_allowed_props) == 1: @@ -608,7 +607,6 @@ class Settings(object): raise ConfigError(_('cannot add this property: "{0}"').format( ' '.join(property_))) - print('add', property_) self_properties = config_bag.properties if self_properties is None: index = None diff --git a/tiramisu/storage/dictionary/value.py b/tiramisu/storage/dictionary/value.py index 8e4d7e3..e8ae20e 100644 --- a/tiramisu/storage/dictionary/value.py +++ b/tiramisu/storage/dictionary/value.py @@ -76,7 +76,7 @@ class Values(Cache): a specified value must be associated to an owner """ if DEBUG: - print('setvalue', path, value, index) + print('setvalue', path, value, owner, index, id(self)) values = [] vidx = None @@ -100,7 +100,7 @@ class Values(Cache): if path.startswith('subod.subodval'): raise Exception('arf ...') if DEBUG: - print('hasvalue', path, index, has_path) + print('hasvalue', path, index, has_path, id(self)) if index is None: return has_path elif has_path: @@ -114,7 +114,7 @@ class Values(Cache): _values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2)) """ if DEBUG: - print('reduce_index', path, index) + print('reduce_index', path, index, id(self)) path_idx = self._values[0].index(path) indexes = self._values[1][path_idx] if index in indexes: @@ -129,7 +129,7 @@ class Values(Cache): def resetvalue_index(self, path, index): if DEBUG: - print('resetvalue_index', path, index) + print('resetvalue_index', path, index, id(self)) def _resetvalue(nb): values_idx = list(values[nb]) del(values_idx[path_idx]) @@ -162,7 +162,7 @@ class Values(Cache): """remove value means delete value in storage """ if DEBUG: - print('resetvalue', path) + print('resetvalue', path, id(self)) def _resetvalue(nb): lst = list(self._values[nb]) lst.pop(idx) @@ -232,7 +232,7 @@ class Values(Cache): if owner is undefined: owner = default if DEBUG: - print('getvalue', path, index, value) + print('getvalue', path, index, value, owner, id(self)) if with_value: return owner, value else: diff --git a/tiramisu/storage/util.py b/tiramisu/storage/util.py index 88ada3c..7d36d9d 100644 --- a/tiramisu/storage/util.py +++ b/tiramisu/storage/util.py @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ____________________________________________________________ -FIXME = 0 def POUET(obj): return(obj.__class__.__name__.lower()) @@ -35,41 +34,23 @@ class Cache(object): """add val in cache for a specified path if slave, add index """ - if DEBUG: - global FIXME - FIXME += 1 - 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: - # raise Exception('rah') + if DEBUG and path == 'odmaster.third': + print('ca set cache', path, val, POUET(self), id(self)) self._cache.setdefault(path, {})[index] = (val, time) def getcache(self, path, exp, index): value, created = self._cache[path][index] if created is None or exp <= created: - if DEBUG: - global FIXME - FIXME += 1 - 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: - # raise Exception('rah') + if DEBUG and path == 'odmaster.third': + print('ca trouve dans le cache', path, value, POUET(self), id(self), index, exp) return True, value return False, None # pragma: no cover def delcache(self, path): """remove cache for a specified path """ - if DEBUG: - global FIXME - FIXME += 1 - 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: - # raise Exception('rah') + if DEBUG and path == 'odmaster.third': + print('ca del cache', path, POUET(self), id(self)) if path in self._cache: del self._cache[path] @@ -78,7 +59,7 @@ class Cache(object): :param path: the path's option """ - if DEBUG: + if DEBUG and path == 'odmaster.third': print('ca cherche dans le cache', path, POUET(self), id(self)) return path in self._cache and index in self._cache[path] diff --git a/tiramisu/value.py b/tiramisu/value.py index 77207d4..9253ae2 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -601,23 +601,26 @@ class Values(object): index, config_bag): - context = self._getcontext() - if config_bag.validate and 'validator' in config_bag.setting_properties: - fake_context = context._gen_fake_values() - fake_value = fake_context.cfgimpl_get_values() - sconfig_bag = config_bag.copy() - sconfig_bag.validate = False - fake_value.reset_slave(path, - index, - sconfig_bag) - value = fake_value._getdefaultvalue(path, - index, - config_bag) - fake_value.setvalue_validation(path, - index, - value, - config_bag) - self._p_.resetvalue_index(path, index) + if self._p_.hasvalue(path, index=index): + context = self._getcontext() + if config_bag.validate and 'validator' in config_bag.setting_properties: + fake_context = context._gen_fake_values() + fake_value = fake_context.cfgimpl_get_values() + sconfig_bag = config_bag.copy() + sconfig_bag.validate = False + fake_value.reset_slave(path, + index, + sconfig_bag) + value = fake_value._getdefaultvalue(path, + index, + config_bag) + fake_value.setvalue_validation(path, + index, + value, + config_bag) + self._p_.resetvalue_index(path, index) + context.cfgimpl_reset_cache(opt=config_bag.option, + path=path) def reset_master(self, subconfig, @@ -628,6 +631,12 @@ class Values(object): current_value = self.get_cached_value(path, None, config_bag) + length = len(current_value) + if index >= length: + raise IndexError(_('index "{}" is higher than the length "{}" ' + 'for option "{}"').format(index, + length, + config_bag.option.impl_get_display_name())) current_value.pop(index) self.setvalue(path, None, @@ -638,7 +647,6 @@ class Values(object): index, config_bag) - def setowner_validation(self, path, index, @@ -709,7 +717,7 @@ class Values(object): lenmaster = None optmaster = None pathmaster = None - for option in description.impl_getchildren(config_bag): + for option in description.impl_getchildren(config_bag, context): sconfig_bag = config_bag.copy('nooption') sconfig_bag.option = option name = option.impl_getname()