reorganise Base and Option
authorEmmanuel Garette <egarette@cadoles.com>
Mon, 24 Jul 2017 16:27:24 +0000 (18:27 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Mon, 24 Jul 2017 16:27:24 +0000 (18:27 +0200)
test/test_metaconfig.py
test/test_parsing_group.py
tiramisu/option/baseoption.py
tiramisu/option/optiondescription.py

index ebbc891..c9d5959 100644 (file)
@@ -654,8 +654,8 @@ def test_meta_properties_meta_set_value():
     ip_admin_eth0 = NetworkOption('ip_admin_eth0', "ip", multi=True, default=['192.168.1.1'])
     netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "mask", multi=True, properties=('disabled',))
     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
-    conf1 = Config(interface1, session_id='conf1')
-    conf2 = Config(interface1, session_id='conf2')
+    conf1 = Config(interface1, session_id='conf20')
+    conf2 = Config(interface1, session_id='conf21')
     meta = MetaConfig([conf1, conf2])
     meta.read_write()
     assert conf1.make_dict() == {'ip_admin_eth0': ['192.168.1.1']}
@@ -694,26 +694,26 @@ def test_meta_reset():
     netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',))
     interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
     interface1.impl_set_group_type(groups.master)
-    conf1 = Config(interface1, session_id='conf1')
-    conf1.read_write()
-    conf2 = Config(interface1, session_id='conf2')
-    conf2.read_write()
-    meta = MetaConfig([conf1, conf2])
+    conf22 = Config(interface1, session_id='conf22')
+    conf22.read_write()
+    conf23 = Config(interface1, session_id='conf23')
+    conf23.read_write()
+    meta = MetaConfig([conf22, conf23])
     meta.read_write()
     meta.cfgimpl_get_settings().setowner(owners.meta)
     assert meta.ip_admin_eth0 == []
-    assert meta.conf1.ip_admin_eth0 == []
-    assert meta.conf2.ip_admin_eth0 == []
+    assert meta.conf22.ip_admin_eth0 == []
+    assert meta.conf23.ip_admin_eth0 == []
     errors = meta.set_value('ip_admin_eth0', ['192.168.1.1'])
     assert len(errors) == 0
     assert meta.ip_admin_eth0 == ['192.168.1.1']
-    assert meta.conf1.ip_admin_eth0 == ['192.168.1.1']
-    assert meta.conf2.ip_admin_eth0 == ['192.168.1.1']
-    meta.conf1.ip_admin_eth0 = ['192.168.1.2']
+    assert meta.conf22.ip_admin_eth0 == ['192.168.1.1']
+    assert meta.conf23.ip_admin_eth0 == ['192.168.1.1']
+    meta.conf22.ip_admin_eth0 = ['192.168.1.2']
     assert meta.ip_admin_eth0 == ['192.168.1.1']
-    assert meta.conf1.ip_admin_eth0 == ['192.168.1.2']
-    assert meta.conf2.ip_admin_eth0 == ['192.168.1.1']
+    assert meta.conf22.ip_admin_eth0 == ['192.168.1.2']
+    assert meta.conf23.ip_admin_eth0 == ['192.168.1.1']
     meta.reset('ip_admin_eth0')
     assert meta.ip_admin_eth0 == []
-    assert meta.conf1.ip_admin_eth0 == []
-    assert meta.conf2.ip_admin_eth0 == []
+    assert meta.conf22.ip_admin_eth0 == []
+    assert meta.conf23.ip_admin_eth0 == []
index d6a9d9c..352ba93 100644 (file)
@@ -468,6 +468,26 @@ def test_values_with_master_and_slaves_slave():
     assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
 
 
+def test_values_with_master_and_slaves_pop():
+    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.impl_set_group_type(groups.master)
+    maconfig = OptionDescription('toto', '', [interface1])
+    cfg = Config(maconfig)
+    cfg.read_write()
+    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
+    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
+    cfg.ip_admin_eth0.netmask_admin_eth0 = ['255.255.255.0']
+    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.146")
+    cfg.ip_admin_eth0.netmask_admin_eth0[1] = '255.255.0.0'
+    assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.230.145', '192.168.230.146']
+    assert cfg.ip_admin_eth0.netmask_admin_eth0 == ['255.255.255.0', '255.255.0.0']
+    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)
+    assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.230.146']
+    assert cfg.ip_admin_eth0.netmask_admin_eth0 == ['255.255.0.0']
+
+
 def test_values_with_master_and_slaves_master():
     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)
index 7e1f78c..4db060d 100644 (file)
@@ -118,59 +118,26 @@ def validate_callback(callback, callback_params, type_, callbackoption):
 #____________________________________________________________
 #
 class Base(object):
+    """Base use by all *Option* classes (Option, OptionDescription, SymLinkOption, ...)
+    """
     __slots__ = ('_name',
                  '_informations',
-                 '_extra',
-                 '_warnings_only',
-                 '_allow_empty_list',
-                 #multi
-                 '_multi',
-                 '_unique',
-                 #value
-                 '_default',
-                 '_default_multi',
                  #calcul
                  '_subdyn',
                  '_requires',
                  '_properties',
                  '_calc_properties',
-                 '_val_call',
                  #
                  '_consistencies',
-                 '_master_slaves',
-                 '_choice_values',
-                 '_choice_values_params',
                  #other
                  '_has_dependency',
                  '_dependencies',
                  '__weakref__'
                 )
 
-    def __init__(self, name, doc, default=None, default_multi=None,
-                 requires=None, multi=False, unique=undefined, callback=None,
-                 callback_params=None, validator=None, validator_params=None,
-                 properties=None, warnings_only=False, extra=None,
-                 allow_empty_list=undefined):
+    def __init__(self, name, doc, requires=None, properties=None, is_multi=False):
         if not valid_name(name):
             raise ValueError(_("invalid name: {0} for option").format(name))
-        if not multi and default_multi is not None:
-            raise ValueError(_("default_multi is set whereas multi is False"
-                               " in option: {0}").format(name))
-        if multi is True:
-            is_multi = True
-            _multi = 0
-        elif multi is False:
-            is_multi = False
-            _multi = 1
-        elif multi is submulti:
-            is_multi = True
-            _multi = submulti
-        else:
-            raise ValueError(_('invalid multi value'))
-        if unique != undefined and not isinstance(unique, bool):
-            raise ValueError(_('unique must be a boolean'))
-        if not is_multi and unique is True:
-            raise ValueError(_('unique must be set only with multi value'))
         if requires is not None:
             calc_properties, requires = validate_requires_arg(self, is_multi,
                                                               requires, name)
@@ -184,17 +151,6 @@ class Base(object):
                               ' must be a tuple').format(
                                   type(properties),
                                   name))
-        if validator is not None:
-            if multi:  # and validator_params is None:
-                validator_params = self._build_validator_params(validator, validator_params)
-
-            validate_callback(validator, validator_params, 'validator', self)
-            if validator_params is None:
-                val_call = (validator,)
-            else:
-                val_call = (validator, validator_params)
-            self._val_call = (val_call, None)
-            self._set_has_dependency()
         if calc_properties != frozenset([]) and properties is not tuple():
             set_forbidden_properties = calc_properties & set(properties)
             if set_forbidden_properties != frozenset():
@@ -205,46 +161,13 @@ class Base(object):
         _setattr(self, '_name', name)
         if sys.version_info[0] < 3 and isinstance(doc, str):
             doc = doc.decode('utf8')
-        if extra is not None:
-            _setattr(self, '_extra', extra)
         _setattr(self, '_informations', {'doc': doc})
-        if _multi != 1:
-            _setattr(self, '_multi', _multi)
-        if warnings_only is True:
-            _setattr(self, '_warnings_only', warnings_only)
         if calc_properties is not undefined:
             _setattr(self, '_calc_properties', calc_properties)
         if requires is not undefined:
             _setattr(self, '_requires', requires)
         if properties is not undefined:
             _setattr(self, '_properties', properties)
-        if multi is not False and default is None:
-            default = []
-        if allow_empty_list is not undefined:
-            _setattr(self, '_allow_empty_list', allow_empty_list)
-        if unique is not undefined:
-            _setattr(self, '_unique', unique)
-        err = self.impl_validate(default, is_multi=is_multi)
-        if err:
-            raise err
-        if (is_multi and default != []) or \
-                (not is_multi and default is not None):
-            if is_multi:
-                default = tuple(default)
-            _setattr(self, '_default', default)
-
-        if is_multi and default_multi is not None:
-            err = self._validate(default_multi)
-            if err:
-                raise ValueError(_("invalid default_multi value {0} "
-                                   "for option {1}: {2}").format(
-                                       str(default_multi),
-                                       self.impl_getname(), str(err)))
-            _setattr(self, '_default_multi', default_multi)
-
-        ##callback is False in optiondescription
-        if callback is not False:
-            self.impl_set_callback(callback, callback_params, _init=True)
 
     def _build_validator_params(self, validator, validator_params):
         if sys.version_info[0] < 3:
@@ -290,10 +213,10 @@ class Base(object):
 
     def impl_set_callback(self, callback, callback_params=None, _init=False):
         if callback is None and callback_params is not None:
-                raise ValueError(_("params defined for a callback function but "
-                                   "no callback defined"
-                                   " yet for option {0}").format(
-                                       self.impl_getname()))
+            raise ValueError(_("params defined for a callback function but "
+                               "no callback defined"
+                               " yet for option {0}").format(
+                                   self.impl_getname()))
         if not _init and self.impl_get_callback()[0] is not None:
             raise ConfigError(_("a callback is already set for {0}, "
                                 "cannot set another one's").format(self.impl_getname()))
@@ -487,8 +410,92 @@ class Option(OnlyOption):
 
     Reminder: an Option object is **not** a container for the value.
     """
-    __slots__ = tuple()
+    __slots__ = ('_extra',
+                 '_warnings_only',
+                 '_allow_empty_list',
+                 #multi
+                 '_multi',
+                 '_unique',
+                 #value
+                 '_default',
+                 '_default_multi',
+                 #calcul
+                 '_val_call',
+                 #
+                 '_master_slaves',
+                 '_choice_values',
+                 '_choice_values_params',
+                )
     _empty = ''
+    def __init__(self, name, doc, default=None, default_multi=None,
+                 requires=None, multi=False, unique=undefined, callback=None,
+                 callback_params=None, validator=None, validator_params=None,
+                 properties=None, warnings_only=False, extra=None,
+                 allow_empty_list=undefined):
+
+        _setattr = object.__setattr__
+        if not multi and default_multi is not None:
+            raise ValueError(_("default_multi is set whereas multi is False"
+                               " in option: {0}").format(name))
+        if multi is True:
+            is_multi = True
+            _multi = 0
+        elif multi is False:
+            is_multi = False
+            _multi = 1
+        elif multi is submulti:
+            is_multi = True
+            _multi = submulti
+        else:
+            raise ValueError(_('invalid multi value'))
+        if _multi != 1:
+            _setattr(self, '_multi', _multi)
+        if multi is not False and default is None:
+            default = []
+        if validator is not None:
+            if multi:  # and validator_params is None:
+                validator_params = self._build_validator_params(validator, validator_params)
+
+            validate_callback(validator, validator_params, 'validator', self)
+            if validator_params is None:
+                val_call = (validator,)
+            else:
+                val_call = (validator, validator_params)
+            self._val_call = (val_call, None)
+            self._set_has_dependency()
+        if extra is not None:
+            _setattr(self, '_extra', extra)
+        if unique != undefined and not isinstance(unique, bool):
+            raise ValueError(_('unique must be a boolean'))
+        if not is_multi and unique is True:
+            raise ValueError(_('unique must be set only with multi value'))
+        if warnings_only is True:
+            _setattr(self, '_warnings_only', warnings_only)
+        if allow_empty_list is not undefined:
+            _setattr(self, '_allow_empty_list', allow_empty_list)
+
+        super(Option, self).__init__(name, doc, requires=requires,
+                                     properties=properties, is_multi=is_multi)
+        if is_multi and default_multi is not None:
+            err = self._validate(default_multi)
+            if err:
+                raise ValueError(_("invalid default_multi value {0} "
+                                   "for option {1}: {2}").format(
+                                       str(default_multi),
+                                       self.impl_getname(), str(err)))
+            _setattr(self, '_default_multi', default_multi)
+        if unique is not undefined:
+            _setattr(self, '_unique', unique)
+        err = self.impl_validate(default, is_multi=is_multi)
+        if err:
+            raise err
+        if (is_multi and default != []) or \
+                (not is_multi and default is not None):
+            if is_multi:
+                default = tuple(default)
+            _setattr(self, '_default', default)
+
+        self.impl_set_callback(callback, callback_params, _init=True)
 
     def impl_is_multi(self):
         return getattr(self, '_multi', 1) != 1
index 9d7c176..9780828 100644 (file)
@@ -406,8 +406,7 @@ class OptionDescription(OptionDescriptionWalk):
         """
         super(OptionDescription, self).__init__(name, doc=doc,
                                                 requires=requires,
-                                                properties=properties,
-                                                callback=False)
+                                                properties=properties)
         child_names = []
         dynopt_names = []
         for child in children: