separate value in slave

This commit is contained in:
2015-11-19 22:25:00 +01:00
parent a248508498
commit 54ca54e505
16 changed files with 409 additions and 416 deletions

View File

@ -18,7 +18,8 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
"enables us to carry out a calculation and return an option's value"
from tiramisu.error import PropertiesOptionError, ConfigError, ContextError
from tiramisu.error import PropertiesOptionError, ConfigError, ContextError, \
SlaveError
from tiramisu.i18n import _
from tiramisu.setting import undefined
# ____________________________________________________________
@ -237,6 +238,9 @@ def carry_out_calculation(option, context, callback, callback_params,
ret = calculate(callback, args, kwargs)
if callback_params != {}:
if isinstance(ret, list) and index is not undefined:
if option.impl_is_master_slaves('slave'):
raise SlaveError(_("callback cannot return a list for a "
"slave option ({0})").format(path))
if len(ret) < index + 1:
ret = None
else:

View File

@ -518,7 +518,7 @@ class _CommonConfig(SubConfig):
"read write is a global config's setting, see `settings.py`"
self.cfgimpl_get_settings().read_write()
def getowner(self, opt, force_permissive=False):
def getowner(self, opt, index=None, force_permissive=False):
"""convenience method to retrieve an option's owner
from the config itself
"""
@ -527,7 +527,7 @@ 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,
return self.cfgimpl_get_values().getowner(opt, index=index,
force_permissive=force_permissive)
def unwrap_from_path(self, path, force_permissive=False):
@ -608,12 +608,12 @@ class _CommonConfig(SubConfig):
fake_config = Config(self._impl_descr, persistent=False,
force_values=get_storages_validation(),
force_settings=self.cfgimpl_get_settings())
fake_config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_.get_modified_values()
fake_config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
return fake_config
def duplicate(self):
config = Config(self._impl_descr)
config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_.get_modified_values()
config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
config.cfgimpl_get_settings()._p_._properties = self.cfgimpl_get_settings()._p_.get_modified_properties()
config.cfgimpl_get_settings()._p_._permissives = self.cfgimpl_get_settings()._p_.get_modified_permissives()
return config

View File

@ -98,7 +98,8 @@ class Base(StorageBase):
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
properties=None, warnings_only=False, extra=None, allow_empty_list=undefined):
properties=None, warnings_only=False, extra=None,
allow_empty_list=undefined):
if not valid_name(name): # pragma: optional cover
raise ValueError(_("invalid name: {0} for option").format(name))
if requires is not None:
@ -108,7 +109,7 @@ class Base(StorageBase):
calc_properties = frozenset()
requires = undefined
if not multi and default_multi is not None: # pragma: optional cover
raise ValueError(_("a default_multi is set whereas multi is False"
raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
if multi is True:
_multi = 0
@ -133,7 +134,8 @@ class Base(StorageBase):
'requirement {0}'.format(
list(set_forbidden_properties)))
StorageBase.__init__(self, name, _multi, warnings_only, doc, extra,
calc_properties, requires, properties, allow_empty_list)
calc_properties, requires, properties,
allow_empty_list)
if multi is not False and default is None:
default = []
self.impl_validate(default)

View File

@ -48,6 +48,10 @@ class MasterSlaves(object):
if child.impl_getname() == name:
self.master = child
else:
if child.impl_getdefault() != []:
raise ValueError(_("not allowed default value for option {0} "
"in group {1}").format(child.impl_getname(),
name))
slaves.append(child)
if self.master is None: # pragma: optional cover
raise ValueError(_('master group with wrong'
@ -107,7 +111,7 @@ class MasterSlaves(object):
def pop(self, opt, values, index):
for slave in self.getslaves(opt):
if not values.is_default_owner(slave, validate_properties=False,
validate_meta=False):
validate_meta=False, index=index):
values._get_cached_item(slave, validate=False,
validate_properties=False
).pop(index, force=True)
@ -139,17 +143,19 @@ class MasterSlaves(object):
for slave in self.getslaves(opt):
try:
slave_path = slave.impl_getpath(values._getcontext())
if c_slave_path == slave_path:
slave_value = c_slave_value
else:
slave_value = values._get_validated_value(slave,
slave_path,
False,
False,
None, False,
None,
self_properties=self_properties)
slavelen = len(slave_value)
slavelen = values._p_.get_max_length(slave_path)
#if c_slave_path == slave_path:
# slave_value = c_slave_value
#else:
# slave_value = values._get_validated_value(slave,
# slave_path,
# False,
# False,
# None, False,
# None,
# self_properties=self_properties,
# masterlen=masterlen)
#slavelen = len(slave_value)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
except ConfigError: # pragma: optional cover
pass
@ -186,39 +192,44 @@ class MasterSlaves(object):
undefined, force_permissive,
master=master)
master_is_meta = values._is_meta(opt, masterp)
value = values._get_validated_value(opt, path, validate,
force_permissive,
force_properties,
validate_properties,
None, # not undefined
with_meta=master_is_meta,
self_properties=self_properties)
#value = values._get_validated_value(opt, path, validate,
# force_permissive,
# force_properties,
# validate_properties,
# None, # not undefined
# with_meta=master_is_meta,
# self_properties=self_properties)
#if slave, had values until master's one
path = opt.impl_getpath(context)
valuelen = len(value)
if validate:
self.validate_slave_length(masterlen, valuelen,
opt.impl_getname(), opt)
if valuelen < masterlen:
for num in range(0, masterlen - valuelen):
index = valuelen + num
value.append(values._get_validated_value(opt, path, True,
False, None,
validate_properties=False,
with_meta=master_is_meta,
index=index,
self_properties=self_properties),
setitem=False,
force=True,
validate=validate)
if validate_properties:
context.cfgimpl_get_settings().validate_properties(opt, False,
False,
value=value,
path=path,
force_permissive=force_permissive,
force_properties=force_properties,
setting_properties=setting_properties)
#path = opt.impl_getpath(context)
#valuelen = len(value)
#if validate:
# self.validate_slave_length(masterlen, valuelen,
# opt.impl_getname(), opt)
#if valuelen < masterlen:
#FIXME voir si pas de plus grande valeur !
value = values._get_multi(opt, path)
for index in range(0, masterlen):
#index = valuelen + num
value.append(values._get_validated_value(opt, path, validate,
force_permissive, force_properties,
validate_properties,
with_meta=master_is_meta,
index=index,
self_properties=self_properties,
masterlen=masterlen),
setitem=False,
force=True,
validate=validate)
#FIXME hu?
if validate_properties:
context.cfgimpl_get_settings().validate_properties(opt, False,
False,
value=value,
path=path,
force_permissive=force_permissive,
force_properties=force_properties,
setting_properties=setting_properties)
return value
def setitem(self, values, opt, value, path):
@ -228,14 +239,17 @@ class MasterSlaves(object):
base_path = '.'.join(path.split('.')[:-1]) + '.'
for slave in self.getslaves(opt):
slave_path = base_path + slave.impl_getname()
slave_value = values._get_validated_value(slave,
slave_path,
False,
False,
None, False,
None) # not undefined
slavelen = len(slave_value)
slavelen = values._p_.get_max_length(slave_path)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
#slave_value = values._get_validated_value(slave,
# slave_path,
# False,
# False,
# None, False,
# None,
# masterlen=masterlen) # not undefined
#slavelen = len(slave_value)
#self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
else:
self.validate_slave_length(self.get_length(values, opt,
slave_path=path), len(value),

View File

@ -433,7 +433,8 @@ class Settings(object):
value=None, force_permissive=False,
force_properties=None,
setting_properties=undefined,
self_properties=undefined):
self_properties=undefined,
index=None):
"""
validation upon the properties related to `opt_or_descr`
@ -480,7 +481,7 @@ class Settings(object):
else:
if 'mandatory' in properties and \
not self._getcontext().cfgimpl_get_values()._isempty(
opt_or_descr, value):
opt_or_descr, value, index=index):
properties.remove('mandatory')
elif opt_or_descr.impl_is_multi() and \
not is_write and 'empty' in forced_properties and \

View File

@ -47,7 +47,7 @@ class StorageBase(object):
'_master_slaves',
'_choice_values',
'_choice_values_params',
#autre
#other
'_state_master_slaves',
'_state_callback',
'_state_callback_params',

View File

@ -15,8 +15,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
from copy import copy
from ..util import Cache
from tiramisu.setting import undefined
class Values(Cache):
@ -25,52 +25,167 @@ class Values(Cache):
def __init__(self, storage):
"""init plugin means create values storage
"""
self._values = {}
self._values = (tuple(), tuple(), tuple(), tuple())
self._informations = {}
# should init cache too
super(Values, self).__init__(storage)
# value
def setvalue(self, path, value, owner):
def setvalue(self, path, value, owner, index):
"""set value for a path
a specified value must be associated to an owner
"""
self._values[path] = (owner, value)
values = []
vidx = None
def getvalue(self, path):
def _setvalue_info(nb, idx, value, vidx):
lst = list(self._values[nb])
if idx is None:
if index is None or nb == 0:
lst.append(value)
else:
lst.append([value])
else:
if index is None or nb == 0:
lst[idx] = value
else:
if nb == 1:
try:
vidx = lst[idx].index(index)
except ValueError:
vidx = None
if vidx is None:
lst[idx].append(value)
elif nb != 1:
lst[idx][vidx] = value
values.append(tuple(lst))
return vidx
try:
idx = self._values[0].index(path)
except ValueError:
idx = None
vidx = _setvalue_info(0, idx, path, vidx)
vidx = _setvalue_info(1, idx, index, vidx)
vidx = _setvalue_info(2, idx, value, vidx)
_setvalue_info(3, idx, owner, vidx)
self._values = tuple(values)
def getvalue(self, path, index=None):
"""get value for a path
return: only value, not the owner
"""
return self._values[path][1]
return self._getvalue(path, 2, index)
def hasvalue(self, path):
def hasvalue(self, path, index=None):
"""if path has a value
return: boolean
"""
return path in self._values
return path in self._values[0]
def resetvalue(self, path):
"""remove value means delete value in storage
"""
del(self._values[path])
def _resetvalue(nb):
lst = list(self._values[nb])
lst.pop(idx)
values.append(tuple(lst))
values = []
idx = self._values[0].index(path)
_resetvalue(0)
_resetvalue(1)
_resetvalue(2)
_resetvalue(3)
self._values = tuple(values)
def get_modified_values(self):
"""return all values in a dictionary
example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
"""
return copy(self._values)
values = {}
for idx, path in enumerate(self._values[0]):
values[path] = (self._values[3][idx], self._values[2][idx])
return values
# owner
def setowner(self, path, owner):
def setowner(self, path, owner, index=None):
"""change owner for a path
"""
self._values[path] = (owner, self._values[path][1])
idx = self._values[0].index(path)
if isinstance(self._values[3][idx], list):
if index is None:
raise ValueError('list but no index')
owner = list(self._values[3][idx])[index] = owner
elif index is not None:
raise ValueError('index set but not a list')
lst = list(self._values[3])
lst[idx] = owner
values = list(self._values)
values[3] = tuple(lst)
self._values = tuple(values)
def getowner(self, path, default):
def get_max_length(self, path):
try:
idx = self._values[0].index(path)
except ValueError:
return 0
return max(self._values[1][idx]) + 1
def getowner(self, path, default, index=None, only_default=False):
"""get owner for a path
return: owner object
"""
return self._values.get(path, (default, None))[0]
if index is None:
if only_default:
if path in self._values[0]:
return None
else:
return default
val = self._getvalue(path, 3, index)
if val is None:
return default
return val
else:
value = self._getvalue(path, 3, index)
if value is None:
return default
else:
return value
def _getvalue(self, path, nb, index):
"""
_values == ((path1, path2), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2), ((idx1_1, idx1_2), None))
"""
try:
idx = self._values[0].index(path)
except ValueError:
value = None
else:
if isinstance(self._values[1][idx], list):
if index is None:
raise ValueError('list but no index')
elif index is not None:
raise ValueError('index set but not a list')
if self._values[1][idx] is None:
if index is None:
value = self._values[nb][idx]
else:
value = self._values[nb][idx][index]
else:
if index is not None:
try:
subidx = self._values[1][idx].index(index)
value = self._values[nb][idx][subidx]
except ValueError:
value = None
else:
value = []
for i in xrange(0, max(self._values[1][idx])):
if i in self._values[1][idx]:
value.append(self._values[nb][idx][self._values[1][idx].index(i)])
else:
value.append(undefined)
return value
def set_information(self, key, value):
"""updates the information's attribute

View File

@ -47,11 +47,20 @@ class Cache(object):
value = getattr(self, slot)
#value has owners object, need 'str()' it
if slot == '_values':
_value = {}
for key, values in value.items():
vals = list(values)
vals[0] = str(vals[0])
_value[key] = tuple(vals)
_value = []
_value.append(value[0])
_value.append(value[1])
str_owner = []
_value.append(value[2])
for owner in value[3]:
if isinstance(owner, list):
str_owners = []
for subowner in owner:
str_owners.append(str(subowner))
str_owner.append(str_owners)
else:
str_owner.append(str(owner))
_value.append(str_owner)
states[slot] = _value
else:
states[slot] = value
@ -60,19 +69,32 @@ class Cache(object):
return states
def __setstate__(self, states):
def convert_owner(owner):
try:
owner = getattr(owners, owner)
except AttributeError:
owners.addowner(owner)
owner = getattr(owners, owner)
return owner
for key, value in states.items():
#value has owners object, need to reconstruct it
if key == '_values':
_value = {}
for key_, values_ in value.items():
vals = list(values_)
try:
vals[0] = getattr(owners, vals[0])
except AttributeError:
owners.addowner(vals[0])
vals[0] = getattr(owners, vals[0])
_value[key_] = tuple(vals)
value = _value
_value = []
_value.append(value[0])
_value.append(value[1])
_value.append(value[2])
obj_owner = []
for owner in value[3]:
if isinstance(owner, list):
obj_owners = []
for subowner in owner:
obj_owners.append(convert_owner(subowner))
obj_owner.append(tuple(obj_owners))
else:
obj_owner.append(convert_owner(owner))
_value.append(tuple(obj_owner))
value = tuple(_value)
setattr(self, key, value)
def setcache(self, path, val, time):

View File

@ -54,33 +54,10 @@ class Values(object):
raise ConfigError(_('the context does not exist anymore'))
return context
def _getvalue(self, opt, path, is_default, index=undefined,
with_meta=True, self_properties=undefined):
"""actually retrieves the value
def _get_multi(self, opt, path):
return Multi([], self.context, opt, path)
:param opt: the `option.Option()` object
:returns: the option's value (or the default value if not set)
"""
if opt.impl_is_optiondescription(): # pragma: optional cover
raise ValueError(_('optiondescription has no value'))
if self_properties is undefined:
self_properties = self._getcontext().cfgimpl_get_settings()._getproperties(
opt, path, read_write=False)
force_default = 'frozen' in self_properties and \
'force_default_on_freeze' in self_properties
if not is_default and not force_default:
value = self._p_.getvalue(path)
if index is not undefined:
try:
return value[index]
except IndexError:
#value is smaller than expected
#so return default value
pass
else:
return value
#so default value
def _getdefaultvalue(self, opt, path, with_meta, index):
# if value has callback and is not set
if opt.impl_has_callback():
callback, callback_params = opt.impl_get_callback()
@ -126,6 +103,56 @@ class Values(object):
value = opt.impl_getdefault_multi()
return value
def _getvalue(self, opt, path, is_default, index=undefined,
with_meta=True, self_properties=undefined,
masterlen=undefined):
"""actually retrieves the value
:param opt: the `option.Option()` object
:returns: the option's value (or the default value if not set)
"""
if opt.impl_is_optiondescription(): # pragma: optional cover
raise ValueError(_('optiondescription has no value'))
if self_properties is undefined:
self_properties = self._getcontext().cfgimpl_get_settings()._getproperties(
opt, path, read_write=False)
force_default = 'frozen' in self_properties and \
'force_default_on_freeze' in self_properties
if not is_default and not force_default:
if opt.impl_is_master_slaves('slave'):
#if masterlen is not undefined:
if index is undefined:
value = []
vals = self._p_.getvalue(path)
length = max(masterlen, len(vals))
for idx in xrange(0, length):
try:
if vals[idx] is undefined:
value.append(self._getdefaultvalue(opt, path, with_meta, idx))
else:
value.append(vals[idx])
except IndexError:
try:
value.append(self._getdefaultvalue(opt, path, with_meta, idx))
except IndexError:
value.append(None)
else:
value = self._p_.getvalue(path, index)
return value
else:
value = self._p_.getvalue(path)
if index is not undefined:
try:
return value[index]
except IndexError:
#value is smaller than expected
#so return default value
pass
else:
return value
return self._getdefaultvalue(opt, path, with_meta, index)
def get_modified_values(self):
context = self._getcontext()
if context._impl_descr is not None:
@ -175,13 +202,13 @@ class Values(object):
if hasvalue:
self._p_.resetvalue(path)
def _isempty(self, opt, value, force_allow_empty_list=False):
def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
"convenience method to know if an option is empty"
if value is undefined:
return False
else:
empty = opt._empty
if opt.impl_is_multi():
if index in [None, undefined] and opt.impl_is_multi():
if force_allow_empty_list:
allow_empty_list = True
else:
@ -273,7 +300,7 @@ class Values(object):
force_properties, validate_properties,
index=undefined, submulti_index=undefined,
with_meta=True, setting_properties=undefined,
self_properties=undefined):
self_properties=undefined, masterlen=undefined):
"""same has getitem but don't touch the cache
index is None for slave value, if value returned is not a list, just return []
"""
@ -286,7 +313,8 @@ class Values(object):
is_default = self._is_default_owner(opt, path,
validate_properties=False,
validate_meta=False,
self_properties=self_properties)
self_properties=self_properties,
index=index)
try:
if index is None:
gv_index = undefined
@ -294,7 +322,8 @@ class Values(object):
gv_index = index
value = self._getvalue(opt, path, is_default, index=gv_index,
with_meta=with_meta,
self_properties=self_properties)
self_properties=self_properties,
masterlen=masterlen)
config_error = None
except ConfigError as err:
# For calculating properties, we need value (ie for mandatory
@ -309,8 +338,7 @@ class Values(object):
# value is not set, for 'undefined' (cannot set None because of
# mandatory property)
value = undefined
if config_error is None:
else:
if index is undefined:
force_index = None
else:
@ -358,7 +386,8 @@ class Values(object):
force_permissive=force_permissive,
force_properties=force_properties,
setting_properties=setting_properties,
self_properties=self_properties)
self_properties=self_properties,
index=index)
if config_error is not None:
raise config_error
return value
@ -394,7 +423,7 @@ class Values(object):
def _setvalue(self, opt, path, value, force_permissive=False,
is_write=True, validate_properties=True,
setting_properties=undefined):
setting_properties=undefined, index=None):
context = self._getcontext()
context.cfgimpl_reset_cache()
if validate_properties:
@ -410,7 +439,15 @@ class Values(object):
if isinstance(val, SubMulti):
value[idx] = list(val)
owner = context.cfgimpl_get_settings().getowner()
self._p_.setvalue(path, value, owner)
if opt.impl_is_master_slaves('slave') and index is None:
try:
self._p_.resetvalue(path)
except ValueError:
pass
for idx, val in enumerate(value):
self._p_.setvalue(path, val, owner, idx)
else:
self._p_.setvalue(path, value, owner, index)
def _is_meta(self, opt, path):
context = self._getcontext()
@ -418,13 +455,13 @@ class Values(object):
self_properties = setting._getproperties(opt, path, read_write=False)
if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties:
return False
if self._p_.getowner(path, owners.default) is not owners.default:
if self._p_.getowner(path, owners.default, only_default=True) is not owners.default:
return False
if context.cfgimpl_get_meta() is not None:
return True
return False
def getowner(self, opt, force_permissive=False):
def getowner(self, opt, index=None, force_permissive=False):
"""
retrieves the option's owner
@ -437,11 +474,12 @@ class Values(object):
not isinstance(opt, DynSymLinkOption):
opt = opt._impl_getopt()
path = opt.impl_getpath(self._getcontext())
return self._getowner(opt, path, force_permissive=force_permissive)
return self._getowner(opt, path, index=index, force_permissive=force_permissive)
def _getowner(self, opt, path, validate_properties=True,
force_permissive=False, validate_meta=undefined,
self_properties=undefined):
self_properties=undefined, only_default=False,
index=None):
"""get owner of an option
"""
if not isinstance(opt, Option) and not isinstance(opt,
@ -456,7 +494,7 @@ class Values(object):
if validate_properties:
self._getitem(opt, path, True, force_permissive, None, True,
self_properties=self_properties)
owner = self._p_.getowner(path, 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)
@ -467,7 +505,11 @@ class Values(object):
if validate_meta:
meta = context.cfgimpl_get_meta()
if owner is owners.default and meta is not None:
owner = meta.cfgimpl_get_values()._getowner(opt, path)
owner = meta.cfgimpl_get_values()._getowner(opt, path,
validate_properties=validate_properties,
force_permissive=force_permissive,
self_properties=self_properties,
only_default=only_default, index=index)
return owner
def setowner(self, opt, owner):
@ -481,9 +523,6 @@ class Values(object):
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
path = opt.impl_getpath(self._getcontext())
self._setowner(opt, path, owner)
def _setowner(self, opt, path, owner):
if not self._p_.hasvalue(path): # pragma: optional cover
raise ConfigError(_('no value for {0} cannot change owner to {1}'
'').format(path, owner))
@ -495,7 +534,7 @@ class Values(object):
self._p_.setowner(path, owner)
def is_default_owner(self, opt, validate_properties=True,
validate_meta=True):
validate_meta=True, index=None):
"""
:param config: *must* be only the **parent** config
(not the toplevel config)
@ -504,14 +543,18 @@ class Values(object):
path = opt.impl_getpath(self._getcontext())
return self._is_default_owner(opt, path,
validate_properties=validate_properties,
validate_meta=validate_meta)
validate_meta=validate_meta, index=index)
def _is_default_owner(self, opt, path, validate_properties=True,
validate_meta=True, self_properties=undefined):
return self._getowner(opt, path, validate_properties,
validate_meta=validate_meta,
self_properties=self_properties) == \
owners.default
validate_meta=True, self_properties=undefined,
index=None):
if not opt.impl_is_master_slaves('slave'):
index = None
d = self._getowner(opt, path, validate_properties,
validate_meta=validate_meta,
self_properties=self_properties, only_default=True,
index=index)
return d == owners.default
def reset_cache(self, only_expired):
"""
@ -640,7 +683,6 @@ class Values(object):
# ____________________________________________________________
# multi types
class Multi(list):
"""multi options values container
that support item notation for the values of multi options"""
@ -708,7 +750,7 @@ class Multi(list):
self._validate(value, fake_context, index, True)
#assume not checking mandatory property
super(Multi, self).__setitem__(index, value)
context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, setting_properties=setting_properties)
self._store()
#def __repr__(self, *args, **kwargs):
# return super(Multi, self).__repr__(*args, **kwargs)
@ -750,7 +792,7 @@ class Multi(list):
value.submulti = weakref.ref(self)
super(Multi, self).append(value)
if setitem:
self._store(force)
self._store(force=force)
def sort(self, cmp=None, key=None, reverse=False):
if self.opt.impl_is_master_slaves():
@ -773,7 +815,6 @@ class Multi(list):
self._store()
def insert(self, index, value, validate=True):
#FIXME value should be undefined
if self.opt.impl_is_master_slaves():
raise SlaveError(_("cannot insert multi option {0} if master or "
"slave").format(self.opt.impl_getname()))
@ -833,7 +874,7 @@ class Multi(list):
context.cfgimpl_get_values(), index)
#set value without valid properties
ret = super(Multi, self).pop(index)
self._store(force)
self._store(force=force)
return ret
def _store(self, force=False):