diff --git a/tiramisu/config.py b/tiramisu/config.py index 05aee2b..f22e622 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -215,15 +215,14 @@ class SubConfig(object): self.setattr(name, value, force_permissive=force_permissive, not_raises=not_raises) - def setattr(self, name, value, force_permissive=False, not_raises=False): + def setattr(self, name, value, force_permissive=False, not_raises=False, index=None): if name.startswith('_impl_'): - object.__setattr__(self, name, value) - return + return object.__setattr__(self, name, value) if '.' in name: # pragma: optional cover homeconfig, name = self.cfgimpl_get_home_by_path(name, force_permissive=force_permissive) return homeconfig.setattr(name, value, force_permissive, - not_raises) + not_raises, index=index) context = self._cfgimpl_get_context() child = self.cfgimpl_get_description().__getattr__(name, context=context) @@ -233,12 +232,12 @@ class SubConfig(object): not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover path = context.cfgimpl_get_description().impl_get_path_by_opt( child._impl_getopt()) - context.setattr(path, value, force_permissive, not_raises) + context.setattr(path, value, force_permissive, not_raises, index=index) else: subpath = self._get_subpath(name) self.cfgimpl_get_values().setitem(child, value, subpath, force_permissive=force_permissive, - not_raises=not_raises) + not_raises=not_raises, index=index) def __delattr__(self, name): context = self._cfgimpl_get_context() diff --git a/tiramisu/option/masterslave.py b/tiramisu/option/masterslave.py index b0f6b46..b40b8c8 100644 --- a/tiramisu/option/masterslave.py +++ b/tiramisu/option/masterslave.py @@ -235,22 +235,20 @@ class MasterSlaves(object): multi = value return multi - def validate(self, values, opt, value, path, session): + def validate(self, values, opt, index, path, session, setitem): if self.is_master(opt): - masterlen = len(value) #for regen slave path base_path = '.'.join(path.split('.')[:-1]) + '.' for slave in self.getslaves(opt): slave_path = base_path + slave.impl_getname() slavelen = values._p_.get_max_length(slave_path, session) - self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt) + self.validate_slave_length(index, slavelen, slave.impl_getname(), opt) else: val_len = self.get_length(values, opt, session, slave_path=path) if isinstance(val_len, Exception): return val_len - self.validate_slave_length(val_len, - len(value), - opt.impl_getname(), opt, setitem=True) + self.validate_slave_length(val_len, index, + opt.impl_getname(), opt, setitem=setitem) def get_length(self, values, opt, session, validate=True, slave_path=undefined, slave_value=undefined, force_permissive=False, master=None, diff --git a/tiramisu/value.py b/tiramisu/value.py index f8b516d..9514844 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -23,6 +23,7 @@ from .setting import owners, expires_time, undefined from .autolib import carry_out_calculation from .i18n import _ from .option import SymLinkOption, DynSymLinkOption, Option +i_i = 0 class Values(object): @@ -398,7 +399,7 @@ class Values(object): raise ConfigError(_('you should only set value with config')) def setitem(self, opt, value, path, force_permissive=False, - check_frozen=True, not_raises=False): + check_frozen=True, not_raises=False, index=None): # check_frozen is, for example, used with "force_store_value" # user didn't change value, so not write # valid opt @@ -408,19 +409,20 @@ class Values(object): session = context.cfgimpl_get_values()._p_.getsession() fake_context = context._gen_fake_values(session) fake_values = fake_context.cfgimpl_get_values() - fake_values._setvalue(opt, path, value) + fake_values._setvalue(opt, path, value, index=index) props = fake_values.validate(opt, value, path, check_frozen=check_frozen, force_permissive=force_permissive, setting_properties=setting_properties, - session=session, not_raises=not_raises) + session=session, not_raises=not_raises, + index=index) if props and not_raises: return - err = opt.impl_validate(value, fake_context, display_warnings=False) + err = opt.impl_validate(value, fake_context, display_warnings=False, force_index=index) if err: raise err opt.impl_validate(value, fake_context, display_error=False) - self._setvalue(opt, path, value) + self._setvalue(opt, path, value, index=index) def _setvalue(self, opt, path, value, force_owner=undefined, index=None): context = self._getcontext() @@ -431,16 +433,19 @@ class Values(object): owner = force_owner # in storage, value must not be a multi if isinstance(value, Multi): - value = list(value) - if opt.impl_is_submulti(): - for idx, val in enumerate(value): - if isinstance(val, SubMulti): - value[idx] = list(val) + if not opt.impl_is_master_slaves('slave') or index is None: + value = list(value) + if opt.impl_is_submulti(): + for idx, val in enumerate(value): + if isinstance(val, SubMulti): + value[idx] = list(val) + else: + value = value[index] session = self._p_.getsession() #FIXME pourquoi là et pas dans masterslaves ?? if opt.impl_is_master_slaves('slave'): if index is not None: - self._p_.setvalue(path, value[index], owner, index, session) + self._p_.setvalue(path, value, owner, index, session) else: self._p_.resetvalue(path, session) for idx, val in enumerate(value): @@ -451,11 +456,17 @@ class Values(object): def validate(self, opt, value, path, check_frozen=True, force_permissive=False, setting_properties=undefined, valid_masterslave=True, - not_raises=False, session=None): + not_raises=False, session=None, index=None): if valid_masterslave and opt.impl_is_master_slaves(): if session is None: session = self._p_.getsession() - val = opt.impl_get_master_slaves().validate(self, opt, value, path, session) + if index is not None: + len_value = index + setitem = False + else: + len_value = len(value) + setitem = True + val = opt.impl_get_master_slaves().validate(self, opt, len_value, path, session, setitem=setitem) if isinstance(val, Exception): return val props = self._getcontext().cfgimpl_get_settings().validate_properties(opt, @@ -464,7 +475,8 @@ class Values(object): value=value, path=path, force_permissive=force_permissive, - setting_properties=setting_properties) + setting_properties=setting_properties, + index=index) if props: if not_raises: return props @@ -815,9 +827,7 @@ class Multi(list): if 'validator' in setting_properties: session = context.cfgimpl_get_values()._p_.getsession() fake_context = context._gen_fake_values(session) - fake_multi = fake_context.cfgimpl_get_values()._get_cached_value( - self.opt, path=self.path, validate=False, - force_permissive=force_permissive) + fake_multi = Multi(list(self), weakref.ref(fake_context), self.opt, self.path) if isinstance(fake_multi, Exception): raise fake_multi fake_multi.append(value, validate=False, force=True, @@ -864,8 +874,7 @@ class Multi(list): if 'validator' in setting_properties and validate and value is not None: session = context.cfgimpl_get_values()._p_.getsession() fake_context = context._gen_fake_values(session) - fake_multi = fake_context.cfgimpl_get_values()._get_cached_value( - self.opt, path=self.path, validate=False) + fake_multi = Multi(list(self), weakref.ref(fake_context), self.opt, self.path) fake_multi.insert(index, value, validate=False) self._validate(value, fake_context, index, True) super(Multi, self).insert(index, value) @@ -882,8 +891,7 @@ class Multi(list): if 'validator' in setting_properties and validate: session = context.cfgimpl_get_values()._p_.getsession() fake_context = context._gen_fake_values(session) - fake_multi = fake_context.cfgimpl_get_values()._get_cached_value( - self.opt, path=self.path, validate=False) + fake_multi = Multi(list(self), weakref.ref(fake_context), self.opt, self.path) if index is None: fake_multi.extend(iterable, validate=False) self._validate(fake_multi, fake_context, index)