find method in config filters by attrs
authorgwen <gremond@cadoles.com>
Fri, 12 Oct 2012 09:35:07 +0000 (11:35 +0200)
committergwen <gremond@cadoles.com>
Fri, 12 Oct 2012 09:35:07 +0000 (11:35 +0200)
test/test_config_api.py
tiramisu/config.py

index 3ac6457..db3f915 100644 (file)
@@ -141,9 +141,20 @@ def test_find_in_config():
     "finds option in config"
     descr = make_description()
     conf = Config(descr)
-    assert conf.find(byname='dummy')[0] == conf.unwrap_from_name('dummy')
-    assert conf.find(bytype=ChoiceOption)[0] == conf.unwrap_from_name('name')
-    assert conf.find(byvalue='ref')[0] == conf.unwrap_from_name('name')
+    assert conf.find(byname='dummy') == [conf.unwrap_from_name('dummy')]
+    assert conf.find_first(byname='dummy') == conf.unwrap_from_name('dummy')
+    assert conf.find(bytype=ChoiceOption) == [conf.unwrap_from_name('name'), conf.unwrap_from_name('objspace')]
+    assert conf.find_first(bytype=ChoiceOption) == conf.unwrap_from_name('name')
+    assert conf.find(byvalue='ref') == [conf.unwrap_from_name('name')]
+    assert conf.find_first(byvalue='ref') == conf.unwrap_from_name('name')
+    # combinaison of filters
+    assert conf.find(bytype=BoolOption, byname='dummy') == [conf.unwrap_from_name('dummy')]
+    assert conf.find_first(bytype=BoolOption, byname='dummy') == conf.unwrap_from_name('dummy')
+    assert conf.find(byvalue=False, byname='dummy') == [conf.unwrap_from_name('dummy')]
+    assert conf.find_first(byvalue=False, byname='dummy') == conf.unwrap_from_name('dummy')
+    # byattrs
+    assert conf.find_first(byattrs= dict(default=2.3)) == conf.unwrap_from_name('float')
+    assert conf.find_first(byvalue=False, byname='dummy', byattrs=dict(default=False)) == conf.unwrap_from_name('dummy')
 
 #def test_validator():
 #    "validates the integrity of an option towards a whole configuration"
index 6bc6780..dee5ca1 100644 (file)
@@ -585,8 +585,82 @@ class Config(object):
                  paths.append(path)
         return paths
 
+    def _find(self, bytype, byname, byvalue, byattrs, first):
+        """
+            :param first: return only one option if True, a list otherwise
+        """
+        def _filter_by_attrs():
+            if byattrs is None:
+                return True
+            for key, value in byattrs.items():
+                if not hasattr(option, key):
+                    return False
+                else:
+                    if getattr(option, key) != value:
+                        return False
+                    else:
+                        continue
+            return True
+        def _filter_by_name():
+            if byname is None:
+                return True
+            pathname = path.split('.')[-1]
+            if pathname == byname:
+                return True
+            else:
+                return False
+        def _filter_by_value():
+            if byvalue is None:
+                return True
+            try:
+                value = getattr(self, path)
+                if value == byvalue:
+                    return True
+            except Exception, e: # a property restricts the acces to value
+                pass
+            return False
+        def _filter_by_type():
+            if bytype is None:
+                return True
+            if isinstance(option, bytype):
+                return True
+            return False
+
+        find_results = []
+        paths = self.getpaths(allpaths=True)
+        for path in paths:
+            option = self.unwrap_from_path(path)
+            if not _filter_by_name():
+                continue
+            if not _filter_by_value():
+                continue
+            if not _filter_by_type():
+                continue
+            if not _filter_by_attrs():
+                continue
+            if first:
+                return option
+            else:
+                find_results.append(option)
+        if first:
+            return None
+        else:
+            return find_results
+
     def find(self, bytype=None, byname=None, byvalue=None, byattrs=None):
         """
+            finds a list of options recursively in the config
+
+            :param bytype: Option class (BoolOption, StrOption, ...)
+            :param byname: filter by Option._name
+            :param byvalue: filter by the option's value
+            :param byattrs: dict of option attributes (default, callback...)
+            :returns: list of matching Option objects
+        """
+        return self._find(bytype, byname, byvalue, byattrs, first=False)
+
+    def find_first(self, bytype=None, byname=None, byvalue=None, byattrs=None):
+        """
             finds an option recursively in the config
 
             :param bytype: Option class (BoolOption, StrOption, ...)
@@ -595,34 +669,7 @@ class Config(object):
             :param byattrs: dict of option attributes (default, callback...)
             :returns: list of matching Option objects
         """
-        def _filter_by_name():
-            if byname is not None:
-                pathname = path.split('.')[-1]
-                if pathname == byname:
-                    yield option
-        def _filter_by_value():
-            if byvalue is not None:
-                try:
-                    value = getattr(self, path)
-                    if value == byvalue:
-                        yield option
-                except Exception, e: # a property restricts the acces to value
-                    pass
-        def _filter_by_type():
-            if bytype is not None:
-                if isinstance(option, bytype):
-                    find_results.append(self.unwrap_from_path(path))
-        find_results = []
-        paths = self.getpaths(allpaths=True)
-        for path in paths:
-            option = self.unwrap_from_path(path)
-            if _filter_by_name() is not None:
-                find_results.extend(list( _filter_by_name() ))
-            if _filter_by_value() is not None:
-                find_results.extend(list( _filter_by_value() ))
-            if _filter_by_type() is not None:
-                find_results.extend(list( _filter_by_type() ))
-        return find_results
+        return self._find(bytype, byname, byvalue, byattrs, first=True)
 
 def make_dict(config, flatten=False):
     """export the whole config into a `dict`