Multi()'s and append
authorgwen <gremond@cadoles.com>
Wed, 5 Dec 2012 09:54:32 +0000 (10:54 +0100)
committergwen <gremond@cadoles.com>
Wed, 5 Dec 2012 09:54:32 +0000 (10:54 +0100)
tiramisu/config.py
tiramisu/option.py

index 72f78e2..e6e976c 100644 (file)
@@ -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:
index d49013d..0bc2a98 100644 (file)
@@ -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):