vregistry.py
branchtls-sprint
changeset 630 66ff0b2f7d03
parent 615 38bc11ac845b
child 631 99f5852f8604
equal deleted inserted replaced
629:59b6542f5729 630:66ff0b2f7d03
   541             if partscore:
   541             if partscore:
   542                 return partscore
   542                 return partscore
   543         return 0
   543         return 0
   544     return selector
   544     return selector
   545 
   545 
       
   546 
       
   547 # selector base classes and operations ########################################
       
   548 class Selector(object):
       
   549     """base class for selector classes providing implementation
       
   550     for operators ``&`` and ``|``
       
   551 
       
   552     This class is only here to give access to binary operators, the
       
   553     selector logic itself should be implemented in the __call__ method
       
   554     """
       
   555     def __init__(self, *selectors):
       
   556         self.selectors = self.merge_selectors(selectors)
       
   557 
       
   558     @classmethod
       
   559     def merge_selectors(cls, selectors):
       
   560         """merge selectors when possible :
       
   561 
       
   562         AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4))
       
   563         ==> AndSelector(sel1, sel2, sel3, sel4)
       
   564         """
       
   565         merged_selectors = []
       
   566         for selector in selectors:
       
   567             if isinstance(selector, cls):
       
   568                 merged_selectors += selector.selectors
       
   569             else:
       
   570                 merged_selectors.append(selector)
       
   571         return merged_selectors
       
   572         
       
   573     def __and__(self, other):
       
   574         return AndSelector(self, other)
       
   575 
       
   576     def __or__(self, other):
       
   577         return OrSelector(self, other)
       
   578 
       
   579     __ror__ = __or__    # for cases like (function | selector)
       
   580     __rand__ = __and__  # for cases like (function & selector)
       
   581     # XXX (function | function) or (function & function) not managed yet
       
   582 
       
   583     def __call__(self, cls, *args, **kwargs):
       
   584         return NotImplementedError("selector %s must implement its logic "
       
   585                                    "in its __call__ method" % self.__class__.__name__)
       
   586 
       
   587 
       
   588 class AndSelector(Selector):
       
   589     """and-chained selectors (formerly known as chainall)"""
       
   590     def __call__(self, cls, *args, **kwargs):
       
   591         score = 0
       
   592         for selector in self.selectors:
       
   593             partscore = selector(cls, *args, **kwargs)
       
   594             if not partscore:
       
   595                 return 0
       
   596             score += partscore
       
   597         return score
       
   598 
       
   599 
       
   600 class OrSelector(Selector):
       
   601     """or-chained selectors (formerly known as chainfirst)"""
       
   602     def __call__(self, cls, *args, **kwargs):
       
   603         for selector in self.selectors:
       
   604             partscore = selector(cls, *args, **kwargs)
       
   605             if partscore:
       
   606                 return partscore
       
   607         return 0