if we delete all reference to a Config and we have reference to old SubConfig, Values...
[tiramisu.git] / tiramisu / setting.py
index 02da5ae..101b551 100644 (file)
@@ -24,7 +24,7 @@ from time import time
 from copy import copy
 import weakref
 from tiramisu.error import (RequirementError, PropertiesOptionError,
-                            ConstError)
+                            ConstError, ConfigError)
 from tiramisu.i18n import _
 
 
@@ -328,6 +328,17 @@ class Settings(object):
         self.context = weakref.ref(context)
         self._p_ = storage
 
+    def _getcontext(self):
+        """context could be None, we need to test it
+        context is None only if all reference to `Config` object is deleted
+        (for example we delete a `Config` and we manipulate a reference to
+        old `SubConfig`, `Values`, `Multi` or `Settings`)
+        """
+        context = self.context()
+        if context is None:
+            raise ConfigError(_('the context does not exist anymore'))
+        return context
+
     #____________________________________________________________
     # properties methods
     def __contains__(self, propname):
@@ -357,7 +368,7 @@ class Settings(object):
             if opt is not None and _path is None:
                 _path = self._get_path_by_opt(opt)
             self._p_.reset_properties(_path)
-        self.context().cfgimpl_reset_cache()
+        self._getcontext().cfgimpl_reset_cache()
 
     def _getproperties(self, opt=None, path=None, is_apply_req=True):
         if opt is None:
@@ -410,7 +421,7 @@ class Settings(object):
                 self._p_.reset_properties(path)
             else:
                 self._p_.setproperties(path, properties)
-        self.context().cfgimpl_reset_cache()
+        self._getcontext().cfgimpl_reset_cache()
 
     #____________________________________________________________
     def validate_properties(self, opt_or_descr, is_descr, is_write, path,
@@ -458,7 +469,7 @@ class Settings(object):
             properties -= frozenset(('mandatory', 'frozen'))
         else:
             if 'mandatory' in properties and \
-                    not self.context().cfgimpl_get_values()._isempty(
+                    not self._getcontext().cfgimpl_get_values()._isempty(
                         opt_or_descr, value):
                 properties.remove('mandatory')
             if is_write and 'everything_frozen' in self_properties:
@@ -581,6 +592,7 @@ class Settings(object):
 
         # filters the callbacks
         calc_properties = set()
+        context = self._getcontext()
         for requires in opt._requires:
             for require in requires:
                 option, expected, action, inverse, \
@@ -592,8 +604,7 @@ class Settings(object):
                                              " '{0}' with requirement on: "
                                              "'{1}'").format(path, reqpath))
                 try:
-                    value = self.context()._getattr(reqpath,
-                                                    force_permissive=True)
+                    value = context._getattr(reqpath, force_permissive=True)
                 except PropertiesOptionError as err:
                     if not transitive:
                         continue
@@ -622,7 +633,7 @@ class Settings(object):
         :param opt: `Option`'s object
         :returns: path
         """
-        return self.context().cfgimpl_get_description().impl_get_path_by_opt(opt)
+        return self._getcontext().cfgimpl_get_description().impl_get_path_by_opt(opt)
 
     def get_modified_properties(self):
         return self._p_.get_modified_properties()