option's name shall not have an api's method name
authorgwen <gremond@cadoles.com>
Mon, 25 Feb 2013 10:33:20 +0000 (11:33 +0100)
committergwen <gremond@cadoles.com>
Mon, 25 Feb 2013 10:33:20 +0000 (11:33 +0100)
test/test_option_with_special_name.py
test/test_parsing_group.py
tiramisu/config.py
tiramisu/value.py

index 9488149..9adaf33 100644 (file)
@@ -43,3 +43,21 @@ def test_root_config_answers_ok():
     settings.enable_property('hiddend') #cfgimpl_hide()
     assert cfg.dummy == False
     assert cfg.boolop  == True
+
+def test_optname_shall_not_start_with_numbers():
+    "if you hide the root config, the options in this namespace behave normally"
+    gcdummy = BoolOption('123dummy', 'dummy', default=False)
+    boolop = BoolOption('boolop', 'Test boolean option op', default=True)
+    descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
+    cfg = Config(descr)
+    # FIXME devrait lever une exception NameError
+    settings = cfg.cfgimpl_get_settings()
+    settings.enable_property('hiddend') #cfgimpl_hide()
+#    assert cfg.123dummy == False
+    assert cfg.boolop  == True
+
+def test_option_has_an_api_name():
+    gcdummy = BoolOption('cfgimpl_get_settings', 'dummy', default=False)
+    boolop = BoolOption('boolop', 'Test boolean option op', default=True)
+    descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
+    raises(NameError, "cfg = Config(descr)")
index 84eb57d..9148194 100644 (file)
@@ -2,7 +2,7 @@
 import autopath
 from tiramisu.config import *
 from tiramisu.option import *
-from tiramisu.setting import groups
+from tiramisu.setting import groups, owners
 
 from py.test import raises
 
@@ -121,3 +121,37 @@ def test_group_always_has_multis():
     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau")
     group = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
     raises(ConfigError, "group.set_group_type(groups.master)")
+
+#____________________________________________________________
+
+def test_values_with_master_and_slaves():
+    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
+    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
+    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+    interface1.set_group_type(groups.master)
+    maconfig = OptionDescription('toto', '', [interface1])
+    cfg = Config(maconfig)
+    opt = cfg.unwrap_from_path("ip_admin_eth0.ip_admin_eth0")
+    owner = cfg._cfgimpl_context._cfgimpl_settings.getowner()
+    assert interface1.get_group_type() == groups.master
+    assert opt.getowner(cfg) == owners.default
+    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
+    assert  cfg.ip_admin_eth0.ip_admin_eth0 == ["192.168.230.145"]
+    assert opt.getowner(cfg) == owner
+
+def test_reset_values_with_master_and_slaves():
+    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
+    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
+    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+    interface1.set_group_type(groups.master)
+    maconfig = OptionDescription('toto', '', [interface1])
+    cfg = Config(maconfig)
+    opt = cfg.unwrap_from_path("ip_admin_eth0.ip_admin_eth0")
+    owner = cfg._cfgimpl_context._cfgimpl_settings.getowner()
+    assert interface1.get_group_type() == groups.master
+    assert opt.getowner(cfg) == owners.default
+    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
+    assert opt.getowner(cfg) == owner
+    cfg._cfgimpl_context._cfgimpl_values.reset(opt)
+    assert opt.getowner(cfg) == owners.default
+    assert  cfg.ip_admin_eth0.ip_admin_eth0 == []
index 961d5dc..ab2b04d 100644 (file)
@@ -21,6 +21,7 @@
 # the whole pypy projet is under MIT licence
 # ____________________________________________________________
 from copy import copy
+from inspect import getmembers, ismethod
 from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
     AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound,
     MandatoryError, MethodCallError, NoValueReturned)
@@ -65,6 +66,10 @@ class Config(object):
         "warnings are a great idea, let's make up a better use of it"
         self._cfgimpl_warnings = []
         self._cfgimpl_toplevel = self._cfgimpl_get_toplevel()
+        # some api members shall not be used as option's names !
+        methods = getmembers(self, ismethod)
+        self._cfgimpl_slots = [key for key, value in methods \
+                              if not key.startswith("_")]
         self._cfgimpl_build()
 
     def cfgimpl_get_settings(self):
@@ -96,17 +101,22 @@ class Config(object):
         if self._cfgimpl_descr.group_type == groups.master:
             mastername = self._cfgimpl_descr._name
             masteropt = getattr(self._cfgimpl_descr, mastername)
-            self._cfgimpl_values.masters[masteropt] = []
+            self._cfgimpl_context._cfgimpl_values.masters[masteropt] = []
 
         for child in self._cfgimpl_descr._children:
             if isinstance(child, OptionDescription):
                 self._validate_duplicates(child._children)
                 self._cfgimpl_subconfigs[child] = Config(child, parent=self,
                                                 context=self._cfgimpl_context)
+            else:
+                if child._name in self._cfgimpl_slots:
+                    raise NameError("invalid name for the option:"
+                                    " {0}".format(child._name))
+
             if (self._cfgimpl_descr.group_type == groups.master and
                     child != masteropt):
-                self._cfgimpl_values.slaves[child] = masteropt
-                self._cfgimpl_values.masters[masteropt].append(child)
+                self._cfgimpl_context._cfgimpl_values.slaves[child] = masteropt
+                self._cfgimpl_context._cfgimpl_values.masters[masteropt].append(child)
 
     # ____________________________________________________________
     # attribute methods
@@ -120,6 +130,9 @@ class Config(object):
             return setattr(homeconfig, name, value)
         if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
             self._validate(name, getattr(self._cfgimpl_descr, name))
+        if name in self._cfgimpl_slots:
+            raise NameError("invalid name for the option:"
+                            " {0}".format(name))
         self.setoption(name, value)
 
     def _validate(self, name, opt_or_descr, permissive=False):
index 07236d5..74adc5b 100644 (file)
@@ -20,7 +20,7 @@
 # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
 # the whole pypy projet is under MIT licence
 # ____________________________________________________________
-from tiramisu.error import NoValueReturned, MandatoryError
+from tiramisu.error import NoValueReturned, MandatoryError, MultiTypeError
 from tiramisu.setting import owners, multitypes
 
 class Values(object):
@@ -138,16 +138,16 @@ class Values(object):
     def __setitem__(self, opt, value):
         if opt in self.masters:
             masterlen = len(value)
-            for slave in masters[opt]:
+            for slave in self.masters[opt]:
                 if len(self._get_value(slave)) != masterlen:
                     raise MultiTypeError("invalid len for the slave: {0}"
-                    "which has {1} as master".format(slave._name,
-                                                     master._name))
+                    " which has {1} as master".format(slave._name,
+                                                      opt._name))
         elif opt in self.slaves:
             if len(self._get_value(self.slaves[opt])) != len(value):
                    raise MultiTypeError("invalid len for the slave: {0}"
-                    "which has {1} as master".format(slave._name,
-                                                     master._name))
+                    " which has {1} as master".format(opt._name,
+                                                      self.slaves[opt]._name))
         self.setitem(opt, value)
 
     def setitem(self, opt, value):