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: |