non mandatory api
authorgwen <gremond@cadoles.com>
Tue, 11 Sep 2012 13:18:38 +0000 (15:18 +0200)
committergwen <gremond@cadoles.com>
Tue, 11 Sep 2012 13:18:38 +0000 (15:18 +0200)
tiramisu/basetype.py
tiramisu/config.py
tiramisu/option.py

index 712fe1b..02d3550 100644 (file)
@@ -32,9 +32,8 @@ class BaseType(object):
         if not propname in self.properties:
             self.properties.append(propname)
     def del_property(self, propname):
-        if not self.has_property(propname):
-            raise TypeError("option has no property " + propname)
-        self.properties.remove(propname)
+        if self.has_property(propname):
+            self.properties.remove(propname)
  
 class HiddenBaseType(BaseType):
     def hide(self):
index e9dcb79..b6b5b46 100644 (file)
@@ -169,6 +169,16 @@ class Config(object):
         rootconfig = self._cfgimpl_get_toplevel()
         if 'disabled' in rootconfig._cfgimpl_properties:
             rootconfig._cfgimpl_properties.remove('disabled')
+
+    def cfgimpl_non_mandatory(self):
+        if self._cfgimpl_parent != None:
+            raise MethodCallError("this method root_mandatory machin() shall not be"
+                                           "used with non-root Confit() object") 
+        rootconfig = self._cfgimpl_get_toplevel()
+        if 'mandatory' in rootconfig._cfgimpl_properties:
+            rootconfig._cfgimpl_properties.remove('mandatory')
+
+
     # ____________________________________________________________
     def __setattr__(self, name, value):
         if '.' in name:
@@ -195,16 +205,25 @@ class Config(object):
             if self._cfgimpl_toplevel._cfgimpl_has_properties() and \
                     opt_or_descr.has_properties():
                 raise PropertiesOptionError("trying to access"
-                        " to an option named: {0}".format(name), 
+                        " to an option named: {0} with properties"
+                        " {1}".format(name, opt_or_descr.properties), 
                         opt_or_descr.properties)
             if self._cfgimpl_toplevel._cfgimpl_has_properties() and \
                     self._cfgimpl_descr.has_properties():
                 raise PropertiesOptionError("trying to access"
                         " to an option's group named: {0}"
-                        " for option named: {1}".format(
-                            self._cfgimpl_descr._name, name), 
+                        " for option named: {1} with properties {2}".format(
+                            self._cfgimpl_descr._name, name,
+                            opt_or_descr.properties), 
                         self._cfgimpl_descr.properties)
 
+    def _is_empty(self, opt):
+        if (not opt.is_multi() and self._cfgimpl_values[opt._name] == None) or \
+            (opt.is_multi() and (self._cfgimpl_values[opt._name] == [] or \
+                None in self._cfgimpl_values[name])):
+            return True
+        return False
+
     def __getattr__(self, name):
         # attribute access by passing a path, 
         # for instance getattr(self, "creole.general.family.adresse_ip_eth0") 
@@ -265,8 +284,14 @@ class Config(object):
             homeconfig = self._cfgimpl_get_toplevel()
             mandatory = homeconfig._cfgimpl_mandatory
             if opt_or_descr.is_mandatory() and mandatory:
-                if self._cfgimpl_values[name] == None\
-                  and opt_or_descr.getdefault() == None:
+                if name == 'ip_ssh_eth0':
+                    print "c'est bien une mandataire2"
+                    print self._cfgimpl_values[name]
+                    print self._is_empty(opt_or_descr)
+                    print type(opt_or_descr)
+                    print opt_or_descr.is_empty_by_default()
+                if self._is_empty(opt_or_descr) and \
+                        opt_or_descr.is_empty_by_default():
                     raise MandatoryError("option: {0} is mandatory " 
                                           "and shall have a value".format(name))
             # frozen and force default
@@ -523,14 +548,15 @@ class Config(object):
         for path in self._cfgimpl_descr.getpaths(include_groups=include_groups):
             try: 
                 value = getattr(self, path)
+                
             except MandatoryError:
                 if mandatory or allpaths:
                     paths.append(path)
-            except Exception, e:
+            except PropertiesOptionError:
                 if allpaths:
                     paths.append(path) # hidden or disabled or mandatory option added
             else:
-                paths.append(path)
+                 paths.append(path)
         return paths 
         
 def make_dict(config, flatten=False):
@@ -552,9 +578,11 @@ def make_dict(config, flatten=False):
 def mandatory_warnings(config):
     mandatory = config._cfgimpl_get_toplevel()._cfgimpl_mandatory
     config._cfgimpl_get_toplevel()._cfgimpl_mandatory = True
-    for path in config.getpaths(mandatory=True):
+    for path in config._cfgimpl_descr.getpaths(include_groups=True):
         try:
             value = getattr(config, path)
         except MandatoryError:
             yield path
+        except PropertiesOptionError:
+            pass
     config._cfgimpl_get_toplevel()._cfgimpl_mandatory = mandatory
index fed7c5d..c9a2533 100644 (file)
@@ -120,7 +120,7 @@ class Option(HiddenBaseType, DisabledBaseType):
                                          "for option {1}".format(str(default), name))
         self.default = default
         self.properties = [] # 'hidden', 'disabled'...
-        
+      
     def validate(self, value):
         if self.multi == False:
             # None allows the reset of the value
@@ -141,6 +141,12 @@ class Option(HiddenBaseType, DisabledBaseType):
     def getdefault(self):
         return self.default
 
+    def is_empty_by_default(self):
+        if ((not self.is_multi() and self.default == None) or
+            (self.is_multi() and self.default == []) or None in self.default):
+            return True
+        return False
+
     def force_default(self):
         self._force_default_on_freeze = True
 
@@ -194,9 +200,11 @@ class Option(HiddenBaseType, DisabledBaseType):
         if self.is_mandatory():
             # value shall not be '' for a mandatory option
             # so '' is considered as being None
-            if value == '':
+            if not self.is_multi() and value == '':
                 value = None
-            if config.is_mandatory() and ((self.is_multi() and value == []) or 
+            if self.is_multi() and '' in value:
+                value = Multi([{'': None}.get(i, i) for i in value], config, self)
+            if config.is_mandatory() and ((self.is_multi() and value == []) or \
                 (not self.is_multi() and value is None)):
                 raise MandatoryError('cannot override value to %s for '
               'option %s' % (value, name))
@@ -531,8 +539,8 @@ def apply_requires(opt, config):
                         if action not in available_actions:
                             raise RequiresError("malformed requirements"
                                            " for option: {0}".format(opt._name))
-                        # FIXME generic programming opt.property_launch(action, False)
                         getattr(opt, action)() #.hide() or show() or...
+                        # FIXME generic programming opt.property_launch(action, False)
                         matches = True
                 else: # option doesn't exist ! should not happen...
                     raise NotFoundError("required option not found: "