cache for properties is now in get_properties and not for validate_properties
authorEmmanuel Garette <egarette@cadoles.com>
Sat, 20 Apr 2013 09:25:14 +0000 (11:25 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Sat, 20 Apr 2013 09:25:14 +0000 (11:25 +0200)
test/test_mandatory.py
test/test_option_consistency.py
tiramisu/config.py
tiramisu/setting.py
tiramisu/value.py

index 1010256..52456eb 100644 (file)
@@ -12,7 +12,7 @@ def make_description():
     stroption1 = StrOption('str1', 'Test string option',
                            properties=('mandatory', ))
     stroption2 = UnicodeOption('unicode2', 'Test string option',
-                           properties=('mandatory', ))
+                               properties=('mandatory', ))
     stroption3 = StrOption('str3', 'Test string option', multi=True,
                            properties=('mandatory', ))
     descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
index c8699a4..88f3626 100644 (file)
@@ -162,7 +162,7 @@ def test_hidden_if_in():
     assert not setting.has_property('hidden', stroption)
     cfg.int = 1
     raises(PropertiesOptionError, "cfg.str")
-    raises(PropertiesOptionError, 'cfg.str= "uvw"')
+    raises(PropertiesOptionError, 'cfg.str="uvw"')
     assert setting.has_property('hidden', stroption)
 
 def test_hidden_if_in_with_group():
index 84e16e4..3402a0e 100644 (file)
@@ -72,8 +72,8 @@ class SubConfig(object):
             return
         self._setattr(name, value)
 
-    def cfgimpl_reset_cache(self):
-        self.cfgimpl_get_context().cfgimpl_reset_cache()
+    def cfgimpl_reset_cache(self, only_expired=False, only=('values', 'settings')):
+        self.cfgimpl_get_context().cfgimpl_reset_cache(only_expired, only)
 
     def _setattr(self, name, value, force_permissive=False):
         if '.' in name:
@@ -361,9 +361,11 @@ class Config(SubConfig):
     def _cfgimpl_build_all_paths(self):
         self._cfgimpl_descr.build_cache()
 
-    def cfgimpl_reset_cache(self, only_expired=False):
-        self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
-        self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
+    def cfgimpl_reset_cache(self, only_expired=False, only=('values', 'settings')):
+        if 'values' in only:
+            self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
+        if 'settings' in only:
+            self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
 
     def unwrap_from_path(self, path):
         """convenience method to extract and Option() object from the Config()
@@ -502,11 +504,12 @@ def mandatory_warnings(config):
 
     :returns: generator of mandatory Option's path
     """
-    config.cfgimpl_reset_cache()
+    #if value in cache, properties are not calculated
+    config.cfgimpl_reset_cache(only=('values',))
     for path in config.cfgimpl_get_description().getpaths(include_groups=True):
         try:
             config._getattr(path, force_properties=('mandatory',))
         except PropertiesOptionError, err:
             if err.proptype == ['mandatory']:
                 yield path
-    config.cfgimpl_reset_cache()
+    config.cfgimpl_reset_cache(only=('values',))
index 2f51706..97098b4 100644 (file)
@@ -157,23 +157,31 @@ class Setting(object):
 
     #____________________________________________________________
     # properties methods
-    def has_properties(self, opt=None, is_apply_req=True):
+    def has_properties(self, opt=None):
         "has properties means the Config's properties attribute is not empty"
-        return bool(len(self.get_properties(opt, is_apply_req)))
+        return bool(len(self.get_properties(opt)))
 
     def get_properties(self, opt=None, is_apply_req=True):
+        if opt is not None and opt in self._cache:
+            exp = time()
+            props, created = self._cache[opt]
+            if exp < created:
+                return props
         if opt is None:
             default = []
         else:
             if is_apply_req:
                 apply_requires(opt, self.context)
             default = list(opt._properties)
-        return self.properties.get(opt, default)
+        props = self.properties.get(opt, default)
+        if opt is not None:
+            self._set_cache(opt, props)
+        return props
 
-    def has_property(self, propname, opt=None, is_apply_req=True):
+    def has_property(self, propname, opt=None):
         """has property propname in the Config's properties attribute
         :param property: string wich is the name of the property"""
-        return propname in self.get_properties(opt, is_apply_req)
+        return propname in self.get_properties(opt)
 
     def enable_property(self, propname):
         "puts property propname in the Config's properties attribute"
@@ -205,6 +213,8 @@ class Setting(object):
                 self.properties[opt] = properties
 
     def add_property(self, propname, opt, is_apply_req=True):
+        if opt is None:
+            raise ValueError("option must not be None in add_property")
         properties = self.get_properties(opt, is_apply_req)
         if not propname in properties:
             properties.append(propname)
@@ -212,6 +222,8 @@ class Setting(object):
         self.context.cfgimpl_reset_cache()
 
     def del_property(self, propname, opt, is_apply_req=True):
+        if opt is None:
+            raise ValueError("option must not be None in del_property")
         properties = self.get_properties(opt, is_apply_req)
         if propname in properties:
             properties.remove(propname)
@@ -223,7 +235,7 @@ class Setting(object):
         if force_properties is not None:
             set_mandatory = ('mandatory' in force_properties or
                              set_mandatory)
-        if set_mandatory and self.has_property('mandatory', opt, False) and \
+        if set_mandatory and self.has_property('mandatory', opt) and \
                 self.context.cfgimpl_get_values()._is_empty(opt, value):
             return True
         return False
@@ -232,12 +244,11 @@ class Setting(object):
         properties = set(self.get_properties(opt_or_descr))
         #remove this properties, those properties are validate in after
         properties = properties - set(['mandatory', 'frozen'])
-        set_properties = self.get_properties()
+        set_properties = set(self.get_properties())
         if force_properties is not None:
-            set_properties.extend(force_properties)
-        set_properties = set(set_properties)
+            set_properties.update(set(force_properties))
         properties = properties & set_properties
-        if force_permissive is True or self.has_property('permissive', is_apply_req=False):
+        if force_permissive is True or self.has_property('permissive'):
             properties = properties - set(self.get_permissive())
         properties = properties - set(self.get_permissive(opt_or_descr))
         return list(properties)
@@ -246,32 +257,22 @@ class Setting(object):
     def validate_properties(self, opt_or_descr, is_descr, is_write,
                             value=None, force_permissive=False,
                             force_properties=None):
-        is_cached = False
-        if opt_or_descr in self._cache:
-            exp = time()
-            props, raise_text, created = self._cache[opt_or_descr]
-            if exp < created:
-                properties = props
-                is_cached = True
-        if not is_cached:
-            properties = self._calc_properties(opt_or_descr, force_permissive,
-                                               force_properties)
-            raise_text = _("trying to access"
-                           " to an option named: {0} with properties"
-                           " {1}")
-            if not is_descr:
-                if self._validate_mandatory(opt_or_descr, value,
-                                            force_properties=force_properties):
-                    properties.append('mandatory')
-                #frozen
-                if is_write and (self.has_property('everything_frozen') or (
-                        self.has_property('frozen') and
-                        self.has_property('frozen', opt_or_descr,
-                                          is_apply_req=False))):
-                    properties.append('frozen')
-                    raise_text = _('cannot change the value to {0} for '
-                                   'option {1} this option is frozen')
-            self._set_cache(opt_or_descr, properties, raise_text)
+        properties = self._calc_properties(opt_or_descr, force_permissive,
+                                           force_properties)
+        raise_text = _("trying to access"
+                       " to an option named: {0} with properties"
+                       " {1}")
+        if not is_descr:
+            if self._validate_mandatory(opt_or_descr, value,
+                                        force_properties=force_properties):
+                properties.append('mandatory')
+            #frozen
+            if is_write and (self.has_property('everything_frozen') or (
+                    self.has_property('frozen') and
+                    self.has_property('frozen', opt_or_descr))):
+                properties.append('frozen')
+                raise_text = _('cannot change the value to {0} for '
+                               'option {1} this option is frozen')
         if properties != []:
             raise PropertiesOptionError(raise_text.format(opt_or_descr._name,
                                                           str(properties)),
@@ -316,16 +317,17 @@ class Setting(object):
         self.enable_property('validator')
         self.disable_property('permissive')
 
-    def _set_cache(self, opt, props, raise_text):
+    def _set_cache(self, opt, props):
         if self.has_property('expire'):
-            self._cache[opt] = (props, raise_text, time() + expires_time)
+            self._cache[opt] = (props, time() + expires_time)
+            pass
 
     def reset_cache(self, only_expired):
         if only_expired:
             exp = time()
             keys = self._cache.keys()
             for key in keys:
-                props, raise_text, created = self._cache[key]
+                props, created = self._cache[key]
                 if exp > created:
                     del(self._cache[key])
         else:
index 5b0aeae..bfa79ac 100644 (file)
@@ -96,14 +96,14 @@ class Values(object):
         # options with callbacks
         setting = self.context.cfgimpl_get_settings()
         value = self._get_value(opt)
-        is_frozen = setting.has_property('frozen', opt, False)
+        is_frozen = setting.has_property('frozen', opt)
         if opt.has_callback():
             #if value is set and :
             # - not frozen
             # - frozen and not force_default_on_freeze
             if not self.is_default_owner(opt) and (
                     not is_frozen or (is_frozen and
-                                      not setting.has_property('force_default_on_freeze', opt, False))):
+                                      not setting.has_property('force_default_on_freeze', opt))):
                 pass
             else:
                 value = self._getcallback_value(opt)
@@ -112,7 +112,7 @@ class Values(object):
                 #suppress value if already set
                 self._reset(opt)
         # frozen and force default
-        elif is_frozen and setting.has_property('force_default_on_freeze', opt, False):
+        elif is_frozen and setting.has_property('force_default_on_freeze', opt):
             value = opt.getdefault()
             if opt.is_multi():
                 value = Multi(value, self.context, opt)
@@ -120,7 +120,7 @@ class Values(object):
             raise ValueError(_('invalid calculated value returned'
                              ' for option {0}: {1}').format(opt._name, value))
         if self.is_default_owner(opt) and \
-                setting.has_property('force_store_value', opt, False):
+                setting.has_property('force_store_value', opt):
             self.setitem(opt, value)
         setting.validate_properties(opt, False, False, value=value,
                                     force_permissive=force_permissive,