vregistry.py
branchtls-sprint
changeset 698 7dfd03e9e810
parent 697 06807984e610
child 707 21a59b468f1a
child 710 766c881e101f
equal deleted inserted replaced
697:06807984e610 698:7dfd03e9e810
   585     for operators ``&`` and ``|``
   585     for operators ``&`` and ``|``
   586 
   586 
   587     This class is only here to give access to binary operators, the
   587     This class is only here to give access to binary operators, the
   588     selector logic itself should be implemented in the __call__ method
   588     selector logic itself should be implemented in the __call__ method
   589     """
   589     """
       
   590 
       
   591     def search_selector(self, selector):
       
   592         """search for the given selector or selector instance in the selectors
       
   593         tree. Return it of None if not found
       
   594         """
       
   595         if self is selector:
       
   596             return self
       
   597         if isinstance(selector, type) and instance(self, selector):
       
   598             return self
       
   599         return None
       
   600     
       
   601     def __and__(self, other):
       
   602         return AndSelector(self, other)
       
   603     def __rand__(self, other):
       
   604         return AndSelector(other, self)
       
   605 
       
   606     def __or__(self, other):
       
   607         return OrSelector(self, other)
       
   608     def __ror__(self, other):
       
   609         return OrSelector(other, self)
       
   610     
       
   611     # XXX (function | function) or (function & function) not managed yet
       
   612 
       
   613     def __call__(self, cls, *args, **kwargs):
       
   614         return NotImplementedError("selector %s must implement its logic "
       
   615                                    "in its __call__ method" % self.__class__)
       
   616 
       
   617 class MultiSelector(Selector):
       
   618     """base class for compound selector classes
       
   619     """
   590     def __init__(self, *selectors):
   620     def __init__(self, *selectors):
   591         self.selectors = self.merge_selectors(selectors)
   621         self.selectors = self.merge_selectors(selectors)
   592 
   622 
   593     @classmethod
   623     @classmethod
   594     def merge_selectors(cls, selectors):
   624     def merge_selectors(cls, selectors):
   607 
   637 
   608     def search_selector(self, selector):
   638     def search_selector(self, selector):
   609         """search for the given selector or selector instance in the selectors
   639         """search for the given selector or selector instance in the selectors
   610         tree. Return it of None if not found
   640         tree. Return it of None if not found
   611         """
   641         """
   612         if self is selector:
       
   613             return self
       
   614         if isinstance(selector, type) and instance(self, selector):
       
   615             return self
       
   616         for childselector in self.selectors:
   642         for childselector in self.selectors:
   617             try:
   643             try:
   618                 if childselector.use_selector(selector):
   644                 if childselector.use_selector(selector):
   619                     return childselector
   645                     return childselector
   620             except AttributeError: # simple function
   646             except AttributeError: # simple function
   621                 if childselector is selector:
   647                 if childselector is selector:
   622                     return childselector
   648                     return childselector
   623         return None
   649         return None
   624     
       
   625     def __and__(self, other):
       
   626         return AndSelector(self, other)
       
   627     def __rand__(self, other):
       
   628         return AndSelector(other, self)
       
   629 
       
   630     def __or__(self, other):
       
   631         return OrSelector(self, other)
       
   632     def __ror__(self, other):
       
   633         return OrSelector(other, self)
       
   634     
       
   635     # XXX (function | function) or (function & function) not managed yet
       
   636 
       
   637     def __call__(self, cls, *args, **kwargs):
       
   638         return NotImplementedError("selector %s must implement its logic "
       
   639                                    "in its __call__ method" % self.__class__)
       
   640 
   650 
   641     
   651     
   642 def objectify_selector(selector_func):
   652 def objectify_selector(selector_func):
   643     """convenience decorator for simple selectors where a class definition
   653     """convenience decorator for simple selectors where a class definition
   644     would be overkill::
   654     would be overkill::
   650     """
   660     """
   651     return type(selector_func.__name__, (Selector,),
   661     return type(selector_func.__name__, (Selector,),
   652                 {'__call__': lambda self, *args: selector_func(*args)})
   662                 {'__call__': lambda self, *args: selector_func(*args)})
   653 
   663 
   654 
   664 
   655 class AndSelector(Selector):
   665 class AndSelector(MultiSelector):
   656     """and-chained selectors (formerly known as chainall)"""
   666     """and-chained selectors (formerly known as chainall)"""
   657     def __call__(self, cls, *args, **kwargs):
   667     def __call__(self, cls, *args, **kwargs):
   658         score = 0
   668         score = 0
   659         for selector in self.selectors:
   669         for selector in self.selectors:
   660             partscore = selector(cls, *args, **kwargs)
   670             partscore = selector(cls, *args, **kwargs)
   662                 return 0
   672                 return 0
   663             score += partscore
   673             score += partscore
   664         return score
   674         return score
   665 
   675 
   666 
   676 
   667 class OrSelector(Selector):
   677 class OrSelector(MultiSelector):
   668     """or-chained selectors (formerly known as chainfirst)"""
   678     """or-chained selectors (formerly known as chainfirst)"""
   669     def __call__(self, cls, *args, **kwargs):
   679     def __call__(self, cls, *args, **kwargs):
   670         for selector in self.selectors:
   680         for selector in self.selectors:
   671             partscore = selector(cls, *args, **kwargs)
   681             partscore = selector(cls, *args, **kwargs)
   672             if partscore:
   682             if partscore: