diff --git a/tiramisu/config.py b/tiramisu/config.py index 72f78e2..e6e976c 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -161,11 +161,10 @@ class Config(object): def _get_master_len(self, slave_name): try: - parent_cfg = self - if parent_cfg is None: + master_name = self._cfgimpl_descr.get_master_name() + if master_name == slave_name: return None - master_name = parent_cfg._cfgimpl_descr.get_master_name() - master_value = parent_cfg._cfgimpl_values[master_name] + master_value = self._cfgimpl_values[master_name] return len(master_value) except TypeError, err: # in this case we just don't care about the len @@ -176,10 +175,11 @@ class Config(object): if master_len == None: return True if master_len != len(slave_value): + master_name = self._cfgimpl_descr.get_master_name() raise ValueError("invalid len for the group of" " the option {0}".format(slave_name)) - def fill_multi(self, name, result, default_multi=None): + def fill_multi(self, name, result, use_default_multi=False, default_multi=None): """fills a multi option with default and calculated values """ value = self._cfgimpl_values[name] @@ -191,7 +191,8 @@ class Config(object): _result = [] for i in range(master_len): _result.append(result) - elif default_multi != None: + elif use_default_multi != False: + _result = result if master_len != None: slave_len = len(result) if slave_len > master_len: @@ -267,7 +268,9 @@ class Config(object): if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze(): value = opt_or_descr.getdefault() if opt_or_descr.is_multi(): - value = self.fill_multi(name, result, opt_or_descr.getdefault_multi()) + value = self.fill_multi(name, value, + use_default_multi=True, + default_multi=opt_or_descr.getdefault_multi()) self._cfgimpl_values[name] = value opt_or_descr.setowner(self, 'default') self._test_mandatory(name, opt_or_descr) @@ -314,12 +317,18 @@ class Config(object): if who == None: who = settings.owner if child.is_multi(): - if type(value) != Multi: - if type(value) == list: - value = Multi(value, self, child) - else: - raise ConfigError("invalid value for option:" - " {0} that is set to multi".format(name)) + if who != 'default': + if type(value) != Multi: + if type(value) == list: + value = Multi(value, self, child) + else: + raise ConfigError("invalid value for option:" + " {0} that is set to multi".format(name)) + else: + value = self.fill_multi(name, child.getdefault(), + use_default_multi=True, + default_multi=child.getdefault_multi()) + self._valid_len(name, value) child.setoption(self, value, who) child.setowner(self, who) else: diff --git a/tiramisu/option.py b/tiramisu/option.py index d49013d..0bc2a98 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -50,12 +50,21 @@ class Multi(list): """ self.config = config self.opt = opt - super(Multi, self).__init__(lst) + if self.opt.is_master(config): + super(Multi, self).__init__(lst) + for l in lst: + try: + self.append(l, add_master=False) + except Exception, err: + print err + else: + self.config._valid_len(self.opt._name, lst) + super(Multi, self).__init__(lst) def __setitem__(self, key, value): return self._setvalue(value, key, who=settings.owner) - def append(self, value): + def append(self, value, add_master=True): """the list value can be updated (appened) only if the option is a master""" try: @@ -70,7 +79,10 @@ class Multi(list): multis.append(multi) for multi in multis: if master == multi.opt._name: - ret = multi._setvalue(value, who=settings.owner) + if add_master: + ret = multi._setvalue(value, who=settings.owner) + else: + ret = value else: default_value = multi.opt.getdefault_multi() multi._setvalue(default_value) @@ -350,6 +362,13 @@ class Option(HiddenBaseType, DisabledBaseType): def getkey(self, value): return value + + def is_master(self, config): + try: + self.master = config._cfgimpl_descr.get_master_name() + except TypeError: + return False + return self.master is not None and self.master == self._name # ____________________________________________________________ "freeze utility" def freeze(self): @@ -539,6 +558,7 @@ class OptionDescription(HiddenBaseType, DisabledBaseType): raise TypeError('get_master_name() shall not be called in case of ' 'non-master OptionDescription') return self.master + # ____________________________________________________________ "actions API" def hide(self):