pop and append in multi values

This commit is contained in:
gwen 2012-12-04 15:18:13 +01:00
parent 4393da13ab
commit 6538231817
2 changed files with 59 additions and 16 deletions

View file

@ -74,7 +74,7 @@ class Config(object):
if isinstance(child, Option):
if child.is_multi():
childdef = Multi(copy(child.getdefault()), config=self,
child=child)
opt=child)
self._cfgimpl_values[child._name] = childdef
self._cfgimpl_previous_values[child._name] = list(childdef)
else:
@ -203,7 +203,7 @@ class Config(object):
_result.append(default_multi)
else:
_result = result
return Multi(_result, value.config, value.child)
return Multi(_result, value.config, opt=value.opt)
def _getattr(self, name, permissive=False):
"""

View file

@ -40,38 +40,81 @@ for act1, act2 in requires_actions:
# multi types
class Multi(list):
"container that support items for the values of list (multi) options"
def __init__(self, lst, config, child):
"""multi options values container
that support item notation for the values of multi options"""
def __init__(self, lst, config, opt):
"""
:lst: the Multi wraps a list value
:param config: the parent config
:param opt: the option object that have this Multi value
"""
self.config = config
self.child = child
self.opt = opt
super(Multi, self).__init__(lst)
def __setitem__(self, key, value):
return self.setoption(value, key)
return self._setvalue(value, key, who=settings.owner)
def append(self, value):
self.setoption(value)
"""the list value can be updated (appened)
only if the option is a master"""
try:
master = self.config._cfgimpl_descr.get_master_name()
if master != self.opt._name:
raise IndexError("in a group with a master, you mustn't add "
"a value in a slave's Multi value")
for name, multi in self.config:
if master == multi.opt._name:
multi._setvalue(value, who=settings.owner)
else:
default_value = multi.opt.getdefault_multi()
multi._setvalue(default_value)
except TypeError:
self._setvalue(value, who=settings.owner)
def setoption(self, value, key=None, who=None):
if who is None:
who = settings.owner
def _setvalue(self, value, key=None, who=None):
if value != None:
if not self.child._validate(value):
if not self.opt._validate(value):
raise ConfigError("invalid value {0} "
"for option {1}".format(str(value), self.child._name))
"for option {1}".format(str(value), self.opt._name))
oldvalue = list(self)
if key is None:
ret = super(Multi, self).append(value)
else:
ret = super(Multi, self).__setitem__(key, value)
self.child.setowner(self.config, who)
self.config._cfgimpl_previous_values[self.child._name] = oldvalue
if who != None:
self.opt.setowner(self.config, who)
self.config._cfgimpl_previous_values[self.opt._name] = oldvalue
return ret
def pop(self, key):
"""the list value can be updated (poped)
only if the option is a master
"""
try:
master = self.config._cfgimpl_descr.get_master_name()
if master != self.opt._name:
raise IndexError("in a group with a master, you mustn't remove "
"a value in a slave's Multi value")
for name, multi in self.config:
if master == multi.opt._name:
multi._pop(key)
else:
change_who = False
# the value owner has to be updated because
# the default value doesn't have the same length
# of the new value
if len(multi.opt.getdefault()) >= len(multi):
change_who = True
multi._pop(key, change_who=change_who)
except TypeError:
self._pop(key)
def _pop(self, key, change_who=True):
oldvalue = list(self)
self.child.setowner(self.config, settings.owner)
self.config._cfgimpl_previous_values[self.child._name] = oldvalue
if change_who:
self.opt.setowner(self.config, settings.owner)
self.config._cfgimpl_previous_values[self.opt._name] = oldvalue
return super(Multi, self).pop(key)
# ____________________________________________________________
#