From 6538231817efa36de5c2ec68d9f78dd325887f9e Mon Sep 17 00:00:00 2001 From: gwen Date: Tue, 4 Dec 2012 15:18:13 +0100 Subject: [PATCH] pop and append in multi values --- tiramisu/config.py | 4 +-- tiramisu/option.py | 71 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/tiramisu/config.py b/tiramisu/config.py index 13fb6e9..3f725c9 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -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): """ diff --git a/tiramisu/option.py b/tiramisu/option.py index 007bf84..96625b9 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -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) # ____________________________________________________________ #