reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class tls-sprint
authorsylvain.thenault@logilab.fr
Tue, 17 Feb 2009 21:40:10 +0100
branchtls-sprint
changeset 693 cf0817dfc787
parent 690 ea613e8a5e4f
child 694 520661be60e4
reimplements chainall/chainfirst using [And/Or], implemenent search_selector function on Selector base class
vregistry.py
--- a/vregistry.py	Tue Feb 17 20:47:22 2009 +0100
+++ b/vregistry.py	Tue Feb 17 21:40:10 2009 +0100
@@ -567,42 +567,6 @@
 set_log_methods(registerer, getLogger('cubicweb.registration'))
 
 
-# advanced selector building functions ########################################
-
-def chainall(*selectors, **kwargs):
-    """return a selector chaining given selectors. If one of
-    the selectors fail, selection will fail, else the returned score
-    will be the sum of each selector'score
-    """
-    assert selectors
-    def selector(cls, *args, **kwargs):
-        score = 0
-        for selector in selectors:
-            partscore = selector(cls, *args, **kwargs)
-            if not partscore:
-                return 0
-            score += partscore
-        return score
-    if 'name' in kwargs:
-        selector.__name__ = kwargs['name']
-    return selector
-
-def chainfirst(*selectors, **kwargs):
-    """return a selector chaining given selectors. If all
-    the selectors fail, selection will fail, else the returned score
-    will be the first non-zero selector score
-    """
-    assert selectors
-    def selector(cls, *args, **kwargs):
-        for selector in selectors:
-            partscore = selector(cls, *args, **kwargs)
-            if partscore:
-                return partscore
-        return 0
-    if 'name' in kwargs:
-        selector.__name__ = kwargs['name']
-    return selector
-
 
 # selector base classes and operations ########################################
 
@@ -630,20 +594,39 @@
             else:
                 merged_selectors.append(selector)
         return merged_selectors
-        
+
+    def search_selector(self, selector):
+        """search for the given selector or selector instance in the selectors
+        tree. Return it of None if not found
+        """
+        if self is selector:
+            return self
+        if isinstance(selector, type) and instance(self, selector):
+            return self
+        for childselector in self.selectors:
+            try:
+                if childselector.use_selector(selector):
+                    return childselector
+            except AttributeError: # simple function
+                if childselector is selector:
+                    return childselector
+        return None
+    
     def __and__(self, other):
         return AndSelector(self, other)
+    def __rand__(self, other):
+        return AndSelector(other, self)
 
     def __or__(self, other):
         return OrSelector(self, other)
-
-    __ror__ = __or__    # for cases like (function | selector)
-    __rand__ = __and__  # for cases like (function & selector)
+    def __ror__(self, other):
+        return OrSelector(other, self)
+    
     # XXX (function | function) or (function & function) not managed yet
 
     def __call__(self, cls, *args, **kwargs):
         return NotImplementedError("selector %s must implement its logic "
-                                   "in its __call__ method" % self.__class__.__name__)
+                                   "in its __call__ method" % self.__class__)
 
 
 class AndSelector(Selector):
@@ -666,3 +649,28 @@
             if partscore:
                 return partscore
         return 0
+
+
+# advanced selector building functions ########################################
+
+def chainall(*selectors, **kwargs):
+    """return a selector chaining given selectors. If one of
+    the selectors fail, selection will fail, else the returned score
+    will be the sum of each selector'score
+    """
+    assert selectors
+    selector = AndSelector(*selectors)
+    if 'name' in kwargs:
+        selector.__name__ = kwargs['name']
+    return selector
+
+def chainfirst(*selectors, **kwargs):
+    """return a selector chaining given selectors. If all
+    the selectors fail, selection will fail, else the returned score
+    will be the first non-zero selector score
+    """
+    assert selectors
+    selector = OrSelector(*selectors)
+    if 'name' in kwargs:
+        selector.__name__ = kwargs['name']
+    return selector