sqlalchemy
authorEmmanuel Garette <egarette@cadoles.com>
Thu, 30 Jan 2014 21:55:15 +0000 (22:55 +0100)
committerEmmanuel Garette <egarette@cadoles.com>
Thu, 30 Jan 2014 21:55:15 +0000 (22:55 +0100)
test/test_config.py
test/test_freeze.py
test/test_option_consistency.py
test/test_requires.py
tiramisu/autolib.py
tiramisu/option.py
tiramisu/setting.py
tiramisu/storage/sqlalchemy/option.py

index e9c470f..064ec8b 100644 (file)
@@ -85,7 +85,7 @@ def test_base_config_and_groups():
     assert nm.impl_getname() == 'name'
     gc = config.unwrap_from_path('gc')
     assert gc.impl_getname() == 'gc'
-    #nm = config.unwrap_fromimpl_getname()('name')
+    #nm = config.unwrap_from_name('name')
     #assert nm.impl_getname() == 'name'
 
 
index 67fe2f4..cda1406 100644 (file)
@@ -146,10 +146,10 @@ def test_force_store_value():
     assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user'
 
 
-#def test_force_store_value_ro():
-#    descr = make_description_freeze()
-#    conf = Config(descr)
-#    conf.read_only()
-#    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default'
-#    conf.wantref
-#    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user'
+def test_force_store_value_ro():
+    descr = make_description_freeze()
+    conf = Config(descr)
+    conf.read_only()
+    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'default'
+    conf.wantref
+    assert conf.getowner(conf.unwrap_from_path('wantref')) == 'user'
index 5e85530..f7040e4 100644 (file)
@@ -102,8 +102,7 @@ def test_consistency_after_config():
     od2 = OptionDescription('od2', '', [b])
     od = OptionDescription('root', '', [od1, od2])
     Config(od)
-    #FIXME a cause du read_only
-    #raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
+    raises(AttributeError, "a.impl_add_consistency('not_equal', b)")
 
 
 def test_consistency_not_equal_symlink():
index 4f35cfd..4cf9372 100644 (file)
@@ -503,19 +503,19 @@ def test_requires_multi_disabled_inverse_2():
         assert props == ['disabled']
 
 
-#def test_requires_requirement_append():
-#    a = BoolOption('activate_service', '', True)
-#    b = IPOption('ip_address_service', '',
-#                 requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
-#    od = OptionDescription('service', '', [a, b])
-#    c = Config(od)
-#    c.read_write()
-#    str(c.cfgimpl_get_settings())
-#    str(c.cfgimpl_get_settings()[b])
-#    raises(ValueError, 'c.cfgimpl_get_settings()[b].append("disabled")')
-#    c.activate_service = False
-#    # disabled is now set, test to remove disabled before store in storage
-#    c.cfgimpl_get_settings()[b].append("test")
+def test_requires_requirement_append():
+    a = BoolOption('activate_service', '', True)
+    b = IPOption('ip_address_service', '',
+                 requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
+    od = OptionDescription('service', '', [a, b])
+    c = Config(od)
+    c.read_write()
+    str(c.cfgimpl_get_settings())
+    str(c.cfgimpl_get_settings()[b])
+    raises(ValueError, 'c.cfgimpl_get_settings()[b].append("disabled")')
+    c.activate_service = False
+    # disabled is now set, test to remove disabled before store in storage
+    c.cfgimpl_get_settings()[b].append("test")
 
 
 def test_requires_different_inverse():
index 726d53f..ef5bce5 100644 (file)
@@ -29,8 +29,7 @@ def carry_out_calculation(option, config, callback, callback_params,
                           index=None, max_len=None):
     """a function that carries out a calculation for an option's value
 
-    :param name: the option name (`opt.impl_getname()`)
-    :param name: the option
+    :param option: the option
     :param config: the context config in order to have
                    the whole options available
     :param callback: the name of the callback function
index 7aa6ad5..e793ee5 100644 (file)
 # ____________________________________________________________
 import re
 import sys
-from copy import copy  # , deepcopy
+from copy import copy
 from types import FunctionType
 from IPy import IP
 import warnings
-#from pickle import loads, dumps
 
 from tiramisu.error import ConfigError, ConflictError, ValueWarning
 from tiramisu.setting import groups, multitypes
@@ -335,43 +334,45 @@ class Option(BaseOption):
                                      warnings_only, choice_values,
                                      choice_open_values)
 
-    #def __setattr__(self, name, value):
-    #    """set once and only once some attributes in the option,
-    #    like `_name`. `_name` cannot be changed one the option and
-    #    pushed in the :class:`tiramisu.option.OptionDescription`.
-
-    #    if the attribute `_readonly` is set to `True`, the option is
-    #    "frozen" (which has noting to do with the high level "freeze"
-    #    propertie or "read_only" property)
-    #    """
-    #    #FIXME ne devrait pas pouvoir redefinir _option
-    #    if not name == '_option':
-    #        is_readonly = False
-    #        # never change _name
-    #        if name == '_name':
-    #            try:
-    #                self._name
-    #                #so _name is already set
-    #                is_readonly = True
-    #            except:
-    #                pass
-    #        elif name != '_readonly':
-    #            try:
-    #                if self._readonly is True:
-    #                    is_readonly = True
-    #            except AttributeError:
-    #                self._readonly = False
-    #        if is_readonly:
-    #            raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
-    #                                   " read-only").format(
-    #                                       self.__class__.__name__,
-    #                                       self._name,
-    #                                       name))
-    #    object.__setattr__(self, name, value)
+    def impl_is_readonly(self):
+        try:
+            if self._readonly is True:
+                return True
+        except AttributeError:
+            pass
+        return False
 
-    #def impl_getproperties(self):
-    #    for prop in self._properties:
-    #        yield(prop.name)
+    def __setattr__(self, name, value):
+        """set once and only once some attributes in the option,
+        like `_name`. `_name` cannot be changed one the option and
+        pushed in the :class:`tiramisu.option.OptionDescription`.
+
+        if the attribute `_readonly` is set to `True`, the option is
+        "frozen" (which has noting to do with the high level "freeze"
+        propertie or "read_only" property)
+        """
+        #FIXME ne devrait pas pouvoir redefinir _option
+        #FIXME c'est une merde pour sqlachemy surement un cache ...
+        if not name == '_option' and not isinstance(value, tuple):
+            is_readonly = False
+            # never change _name
+            if name == '_name':
+                try:
+                    if self._name is not None:
+                        #so _name is already set
+                        is_readonly = True
+                #FIXME je n'aime pas ce except ...
+                except:
+                    pass
+            elif name != '_readonly':
+                is_readonly = self.impl_is_readonly()
+            if is_readonly:
+                raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
+                                       " read-only").format(
+                                           self.__class__.__name__,
+                                           self._name,
+                                           name))
+        super(Option, self).__setattr__(name, value)
 
     def impl_getrequires(self):
         return self._requires
@@ -443,8 +444,6 @@ class Option(BaseOption):
             if self._validator is not None:
                 if self._validator_params is not None:
                     validator_params = {}
-                    #FIXME toujours utile ce deepcopy ?
-                    #validator_params = deepcopy(self._validator_params)
                     for val_param, values in self._validator_params.items():
                         validator_params[val_param] = values
                     #FIXME ... ca sert à quoi ...
@@ -550,6 +549,11 @@ class Option(BaseOption):
         :param other_opts: options used to validate value
         :type other_opts: `list` of `tiramisu.option.Option`
         """
+        if self.impl_is_readonly():
+            raise AttributeError(_("'{0}' ({1}) cannont add consistency, option is"
+                                   " read-only").format(
+                                       self.__class__.__name__,
+                                       self._name))
         for opt in other_opts:
             if not isinstance(opt, Option):
                 raise ConfigError(_('consistency should be set with an option'))
@@ -1010,7 +1014,7 @@ class DomainnameOption(Option):
     domainname:
     fqdn: with tld, not supported yet
     """
-    #__slots__ = ('_dom_type', '_allow_ip', '_allow_without_dot', '_domain_re')
+    #__slots__ = ('_type', '_allow_ip', '_allow_without_dot', '_domain_re')
 
     def __init__(self, name, doc, default=None, default_multi=None,
                  requires=None, multi=False, callback=None,
@@ -1167,7 +1171,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
         self._cache_paths = None
         self._cache_consistencies = None
         # the group_type is useful for filtering OptionDescriptions in a config
-        self._optiondescription_group_type = groups.default
+        self._group_type = groups.default
 
     #def impl_getproperties(self):
     #    #FIXME
@@ -1317,12 +1321,12 @@ class OptionDescription(BaseOption, StorageOptionDescription):
         :param group_type: an instance of `GroupType` or `MasterGroupType`
                               that lives in `setting.groups`
         """
-        if self._optiondescription_group_type != groups.default:
+        if self._group_type != groups.default:
             raise TypeError(_('cannot change group_type if already set '
-                            '(old {0}, new {1})').format(self._optiondescription_group_type,
+                            '(old {0}, new {1})').format(self._group_type,
                                                          group_type))
         if isinstance(group_type, groups.GroupType):
-            self._optiondescription_group_type = group_type
+            self._group_type = group_type
             if isinstance(group_type, groups.MasterGroupType):
                 #if master (same name has group) is set
                 #for collect all slaves
@@ -1367,7 +1371,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
                                ' not allowed').format(group_type))
 
     def impl_get_group_type(self):
-        return getattr(groups, self._optiondescription_group_type)
+        return getattr(groups, self._group_type)
 
     def _valid_consistency(self, option, value, context, index):
         if self._cache_consistencies is None:
@@ -1396,7 +1400,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
             self.impl_build_cache()
             descr = self
         super(OptionDescription, self)._impl_getstate(descr)
-        self._state_group_type = str(self._optiondescription_group_type)
+        self._state_group_type = str(self._group_type)
         for option in self.impl_getchildren():
             option._impl_getstate(descr)
 
@@ -1426,7 +1430,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
             self._cache_consistencies = None
             self.impl_build_cache(force_no_consistencies=True)
             descr = self
-        self._optiondescription_group_type = getattr(groups, self._state_group_type)
+        self._group_type = getattr(groups, self._state_group_type)
         del(self._state_group_type)
         super(OptionDescription, self)._impl_setstate(descr)
         for option in self.impl_getchildren():
@@ -1450,7 +1454,7 @@ def validate_requires_arg(requires, name):
                      the description of the requires dictionary
     """
     if requires is None:
-        return None
+        return None, None
     ret_requires = {}
     config_action = {}
 
index 4d7da51..e483041 100644 (file)
@@ -268,7 +268,7 @@ class Property(object):
         :type propname: string
         """
         if self._opt is not None and self._opt.impl_getrequires() is not None \
-                and propname in self._opt.impl_getrequires():
+                and propname in self._opt._calc_properties:
             raise ValueError(_('cannot append {0} property for option {1}: '
                                'this property is calculated').format(
                                    propname, self._opt.impl_getname()))
index dc0bc7d..82339d1 100644 (file)
@@ -275,7 +275,7 @@ class _Base(SqlAlchemyBase):
         'polymorphic_on': _type
     }
     #FIXME devrait etre une table
-    _optiondescription_group_type = Column(String)
+    _group_type = Column(String)
 
     def __init__(self):
         self.commit()