Merge branch 'master' into orm
[tiramisu.git] / tiramisu / config.py
index c9fb992..f05d900 100644 (file)
@@ -73,21 +73,24 @@ class SubConfig(object):
                                  force_properties=force_properties)
         return self, path[-1]
 
-    def __hash__(self):
-        return hash(self.cfgimpl_get_description().impl_getkey(self))
-
-    def __eq__(self, other):
-        "Config's comparison"
-        if not isinstance(other, Config):
-            return False
-        return self.cfgimpl_get_description().impl_getkey(self) == \
-            other.cfgimpl_get_description().impl_getkey(other)
-
-    def __ne__(self, other):
-        "Config's comparison"
-        if not isinstance(other, Config):
-            return True
-        return not self == other
+    #def __hash__(self):
+    #FIXME
+    #    return hash(self.cfgimpl_get_description().impl_getkey(self))
+
+    #def __eq__(self, other):
+    #FIXME
+    #    "Config's comparison"
+    #    if not isinstance(other, Config):
+    #        return False
+    #    return self.cfgimpl_get_description().impl_getkey(self) == \
+    #        other.cfgimpl_get_description().impl_getkey(other)
+
+    #def __ne__(self, other):
+    #FIXME
+    #    "Config's comparison"
+    #    if not isinstance(other, Config):
+    #        return True
+    #    return not self == other
 
     # ______________________________________________________________________
     def __iter__(self):
@@ -96,7 +99,7 @@ class SubConfig(object):
         for child in self.cfgimpl_get_description().impl_getchildren():
             if not isinstance(child, OptionDescription):
                 try:
-                    yield child._name, getattr(self, child._name)
+                    yield child.impl_getname(), getattr(self, child.impl_getname())
                 except GeneratorExit:
                     raise StopIteration
                 except PropertiesOptionError:
@@ -107,7 +110,7 @@ class SubConfig(object):
         iteration on Options and OptionDescriptions."""
         for child in self.cfgimpl_get_description().impl_getchildren():
             try:
-                yield child._name, getattr(self, child._name)
+                yield child.impl_getname(), getattr(self, child.impl_getname())
             except GeneratorExit:
                 raise StopIteration
             except PropertiesOptionError:
@@ -131,7 +134,7 @@ class SubConfig(object):
                     if group_type is None or (group_type is not None and
                                               child.impl_get_group_type()
                                               == group_type):
-                        yield child._name, getattr(self, child._name)
+                        yield child.impl_getname(), getattr(self, child.impl_getname())
                 except GeneratorExit:
                     raise StopIteration
                 except PropertiesOptionError:
@@ -262,7 +265,7 @@ class SubConfig(object):
             finds a list of options recursively in the config
 
             :param bytype: Option class (BoolOption, StrOption, ...)
-            :param byname: filter by Option._name
+            :param byname: filter by Option.impl_getname()
             :param byvalue: filter by the option's value
             :returns: list of matching Option objects
         """
@@ -278,7 +281,7 @@ class SubConfig(object):
             finds an option recursively in the config
 
             :param bytype: Option class (BoolOption, StrOption, ...)
-            :param byname: filter by Option._name
+            :param byname: filter by Option.impl_getname()
             :param byvalue: filter by the option's value
             :returns: list of matching Option objects
         """
@@ -295,12 +298,6 @@ class SubConfig(object):
         :param first: return only one option if True, a list otherwise
         :return: find list or an exception if nothing has been found
         """
-        def _filter_by_name():
-            if byname is None or path == byname or \
-                    path.endswith('.' + byname):
-                return True
-            return False
-
         def _filter_by_value():
             if byvalue is None:
                 return True
@@ -314,31 +311,19 @@ class SubConfig(object):
                                            # upon the access of the value
                 return False
 
-        def _filter_by_type():
-            if bytype is None:
-                return True
-            if isinstance(option, bytype):
-                return True
-            return False
-
         if type_ not in ('option', 'path', 'value'):
             raise ValueError(_('unknown type_ type {0}'
                                'for _find').format(type_))
         find_results = []
-        opts, paths = self.cfgimpl_get_description()._cache_paths
-        for index in range(0, len(paths)):
-            option = opts[index]
-            if isinstance(option, OptionDescription):
-                continue
-            path = paths[index]
-            if _subpath is not None and not path.startswith(_subpath + '.'):
-                continue
-            if not _filter_by_name():
-                continue
+        # if value and/or check_properties are set, need all avalaible option
+        # If first one has no good value or not good property check second one
+        # and so on
+        only_first = first is True and byvalue is None and check_properties is None
+        options = self.cfgimpl_get_description().impl_get_options_paths(
+            bytype, byname, _subpath, only_first)
+        for path, option in options:
             if not _filter_by_value():
                 continue
-            if not _filter_by_type():
-                continue
             #remove option with propertyerror, ...
             if byvalue is None and check_properties:
                 try:
@@ -415,7 +400,7 @@ class SubConfig(object):
                                "option"))
         if withoption is not None:
             mypath = self.cfgimpl_get_path()
-            for path in self._cfgimpl_get_context()._find(bytype=Option,
+            for path in self._cfgimpl_get_context()._find(bytype=None,
                                                           byname=withoption,
                                                           byvalue=withvalue,
                                                           first=False,
@@ -440,7 +425,7 @@ class SubConfig(object):
         #withoption can be set to None below !
         if withoption is None:
             for opt in self.cfgimpl_get_description().impl_getchildren():
-                path = opt._name
+                path = opt.impl_getname()
                 self._make_sub_dict(opt, path, pathsvalues, _currpath, flatten)
         if _currpath == []:
             options = dict(pathsvalues)
@@ -453,12 +438,15 @@ class SubConfig(object):
                                                          _currpath +
                                                          path.split('.'))
         else:
-            value = self._getattr(opt._name)
-            if flatten:
-                name = opt._name
-            else:
-                name = '.'.join(_currpath + [opt._name])
-            pathsvalues.append((name, value))
+            try:
+                value = self._getattr(opt.impl_getname())
+                if flatten:
+                    name = opt.impl_getname()
+                else:
+                    name = '.'.join(_currpath + [opt.impl_getname()])
+                pathsvalues.append((name, value))
+            except PropertiesOptionError:
+                pass  # this just a hidden or disabled option
 
     def cfgimpl_get_path(self):
         descr = self.cfgimpl_get_description()
@@ -470,8 +458,11 @@ class _CommonConfig(SubConfig):
     "abstract base class for the Config, GroupConfig and the MetaConfig"
     __slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test')
 
-    def _impl_build_all_paths(self):
-        self.cfgimpl_get_description().impl_build_cache()
+    def _impl_build_all_caches(self):
+        if not self.cfgimpl_get_description().impl_already_build_caches():
+            self.cfgimpl_get_description().impl_build_cache_consistency()
+            self.cfgimpl_get_description().impl_validate_options()
+            self.cfgimpl_get_description().impl_build_cache_option()
 
     def read_only(self):
         "read only is a global config's setting, see `settings.py`"
@@ -567,7 +558,7 @@ class _CommonConfig(SubConfig):
 # ____________________________________________________________
 class Config(_CommonConfig):
     "main configuration management entry"
-    __slots__ = ('__weakref__',)
+    __slots__ = ('__weakref__', '_impl_test')
 
     def __init__(self, descr, session_id=None, persistent=False):
         """ Configuration option management master class
@@ -586,7 +577,7 @@ class Config(_CommonConfig):
         self._impl_settings = Settings(self, settings)
         self._impl_values = Values(self, values)
         super(Config, self).__init__(descr, weakref.ref(self))
-        self._impl_build_all_paths()
+        self._impl_build_all_caches()
         self._impl_meta = None
         #undocumented option used only in test script
         self._impl_test = False