Merge branch 'master' into orm
[tiramisu.git] / tiramisu / option.py
index ec231c9..b4db8a8 100644 (file)
@@ -47,9 +47,7 @@ forbidden_names = ('iter_all', 'iter_group', 'find', 'find_first',
 
 def valid_name(name):
     "an option's name is a str and does not start with 'impl' or 'cfgimpl'"
-    try:
-        name = str(name)
-    except:
+    if not isinstance(name, str):
         return False
     if re.match(name_regexp, name) is None and not name.startswith('_') \
             and name not in forbidden_names \
@@ -636,7 +634,7 @@ class Option(BaseOption):
                 else:
                     validator_params = (FakeCallbackParam('', (FakeCallbackParamOption(value=val),)),)
                 # Raise ValueError if not valid
-                carry_out_calculation(self.impl_getname(), config=context,
+                carry_out_calculation(self, config=context,
                                       callback=self._validator,
                                       callback_params=validator_params)
 
@@ -674,17 +672,13 @@ class Option(BaseOption):
             do_validation(value, force_index)
         else:
             if not isinstance(value, list):
-                raise ValueError(_("which must be a list").format(value,
-                                                                  self.impl_getname()))
+                raise ValueError(_("invalid value {0} for option {1} which must be a list").format(value, self.impl_getname()))
             for index, val in enumerate(value):
                 do_validation(val, index)
 
-    def impl_getdefault(self, default_multi=False):
+    def impl_getdefault(self):
         "accessing the default value"
-        if not default_multi or not self.impl_is_multi():
-            return self._default
-        else:
-            return self.getdefault_multi()
+        return self._default
 
     def impl_getdefault_multi(self):
         "accessing the default value for a multi"
@@ -940,7 +934,7 @@ class StrOption(Option):
 
 
 if sys.version_info[0] >= 3:
-    #UnicodeOption is same has StrOption in python 3+
+    #UnicodeOption is same as StrOption in python 3+
     class UnicodeOption(StrOption):
         __slots__ = tuple()
         pass
@@ -1022,6 +1016,12 @@ class IPOption(Option):
                                        warnings_only=warnings_only)
 
     def _validate(self, value):
+        # sometimes an ip term starts with a zero
+        # but this does not fit in some case, for example bind does not like it
+        for val in value.split('.'):
+            if val.startswith("0") and len(val) > 1:
+                raise ValueError(_('invalid IP'))
+        # 'standard' validation
         try:
             IP('{0}/32'.format(value))
         except ValueError:
@@ -1533,7 +1533,6 @@ class OptionDescription(BaseOption):
             self._optiondescription_group_type = group_type
             if isinstance(group_type, groups.MasterGroupType):
                 #if master (same name has group) is set
-                identical_master_child_name = False
                 #for collect all slaves
                 slaves = []
                 master = None
@@ -1549,8 +1548,7 @@ class OptionDescription(BaseOption):
                                          "in group {1}"
                                          ": this option is not a multi"
                                          "").format(child.impl_getname(), self.impl_getname()))
-                    if child.impl_getname() == self.impl_getname():
-                        identical_master_child_name = True
+                    if child._name == self.impl_getname():
                         child._multitype = multitypes.master
                         master = child
                     else:
@@ -1559,14 +1557,18 @@ class OptionDescription(BaseOption):
                     raise ValueError(_('master group with wrong'
                                        ' master name for {0}'
                                        ).format(self.impl_getname()))
+                if master._callback is not None and master._callback[1] is not None:
+                    for key, callbacks in master._callback[1].items():
+                        for callbk in callbacks:
+                            if isinstance(callbk, tuple):
+                                if callbk[0] in slaves:
+                                    raise ValueError(_("callback of master's option shall "
+                                                       "not refered a slave's ones"))
                 master._master_slaves = tuple(slaves)
                 for child in self.impl_getchildren():
                     if child != master:
                         child._master_slaves = master
                         child._multitype = multitypes.slave
-                if not identical_master_child_name:
-                    raise ValueError(_("no child has same nom has master group"
-                                       " for: {0}").format(self.impl_getname()))
         else:
             raise ValueError(_('group_type: {0}'
                                ' not allowed').format(group_type))