# 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)
-
- def setoption(self, value, key=None, who=None):
- if who is None:
- who = settings.owner
+ """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 _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)
# ____________________________________________________________
#