565 set_log_methods(VObject, getLogger('cubicweb')) |
565 set_log_methods(VObject, getLogger('cubicweb')) |
566 set_log_methods(VRegistry, getLogger('cubicweb.registry')) |
566 set_log_methods(VRegistry, getLogger('cubicweb.registry')) |
567 set_log_methods(registerer, getLogger('cubicweb.registration')) |
567 set_log_methods(registerer, getLogger('cubicweb.registration')) |
568 |
568 |
569 |
569 |
570 # advanced selector building functions ######################################## |
|
571 |
|
572 def chainall(*selectors, **kwargs): |
|
573 """return a selector chaining given selectors. If one of |
|
574 the selectors fail, selection will fail, else the returned score |
|
575 will be the sum of each selector'score |
|
576 """ |
|
577 assert selectors |
|
578 def selector(cls, *args, **kwargs): |
|
579 score = 0 |
|
580 for selector in selectors: |
|
581 partscore = selector(cls, *args, **kwargs) |
|
582 if not partscore: |
|
583 return 0 |
|
584 score += partscore |
|
585 return score |
|
586 if 'name' in kwargs: |
|
587 selector.__name__ = kwargs['name'] |
|
588 return selector |
|
589 |
|
590 def chainfirst(*selectors, **kwargs): |
|
591 """return a selector chaining given selectors. If all |
|
592 the selectors fail, selection will fail, else the returned score |
|
593 will be the first non-zero selector score |
|
594 """ |
|
595 assert selectors |
|
596 def selector(cls, *args, **kwargs): |
|
597 for selector in selectors: |
|
598 partscore = selector(cls, *args, **kwargs) |
|
599 if partscore: |
|
600 return partscore |
|
601 return 0 |
|
602 if 'name' in kwargs: |
|
603 selector.__name__ = kwargs['name'] |
|
604 return selector |
|
605 |
|
606 |
570 |
607 # selector base classes and operations ######################################## |
571 # selector base classes and operations ######################################## |
608 |
572 |
609 class Selector(object): |
573 class Selector(object): |
610 """base class for selector classes providing implementation |
574 """base class for selector classes providing implementation |
628 if isinstance(selector, cls): |
592 if isinstance(selector, cls): |
629 merged_selectors += selector.selectors |
593 merged_selectors += selector.selectors |
630 else: |
594 else: |
631 merged_selectors.append(selector) |
595 merged_selectors.append(selector) |
632 return merged_selectors |
596 return merged_selectors |
633 |
597 |
|
598 def search_selector(self, selector): |
|
599 """search for the given selector or selector instance in the selectors |
|
600 tree. Return it of None if not found |
|
601 """ |
|
602 if self is selector: |
|
603 return self |
|
604 if isinstance(selector, type) and instance(self, selector): |
|
605 return self |
|
606 for childselector in self.selectors: |
|
607 try: |
|
608 if childselector.use_selector(selector): |
|
609 return childselector |
|
610 except AttributeError: # simple function |
|
611 if childselector is selector: |
|
612 return childselector |
|
613 return None |
|
614 |
634 def __and__(self, other): |
615 def __and__(self, other): |
635 return AndSelector(self, other) |
616 return AndSelector(self, other) |
|
617 def __rand__(self, other): |
|
618 return AndSelector(other, self) |
636 |
619 |
637 def __or__(self, other): |
620 def __or__(self, other): |
638 return OrSelector(self, other) |
621 return OrSelector(self, other) |
639 |
622 def __ror__(self, other): |
640 __ror__ = __or__ # for cases like (function | selector) |
623 return OrSelector(other, self) |
641 __rand__ = __and__ # for cases like (function & selector) |
624 |
642 # XXX (function | function) or (function & function) not managed yet |
625 # XXX (function | function) or (function & function) not managed yet |
643 |
626 |
644 def __call__(self, cls, *args, **kwargs): |
627 def __call__(self, cls, *args, **kwargs): |
645 return NotImplementedError("selector %s must implement its logic " |
628 return NotImplementedError("selector %s must implement its logic " |
646 "in its __call__ method" % self.__class__.__name__) |
629 "in its __call__ method" % self.__class__) |
647 |
630 |
648 |
631 |
649 class AndSelector(Selector): |
632 class AndSelector(Selector): |
650 """and-chained selectors (formerly known as chainall)""" |
633 """and-chained selectors (formerly known as chainall)""" |
651 def __call__(self, cls, *args, **kwargs): |
634 def __call__(self, cls, *args, **kwargs): |
664 for selector in self.selectors: |
647 for selector in self.selectors: |
665 partscore = selector(cls, *args, **kwargs) |
648 partscore = selector(cls, *args, **kwargs) |
666 if partscore: |
649 if partscore: |
667 return partscore |
650 return partscore |
668 return 0 |
651 return 0 |
|
652 |
|
653 |
|
654 # advanced selector building functions ######################################## |
|
655 |
|
656 def chainall(*selectors, **kwargs): |
|
657 """return a selector chaining given selectors. If one of |
|
658 the selectors fail, selection will fail, else the returned score |
|
659 will be the sum of each selector'score |
|
660 """ |
|
661 assert selectors |
|
662 selector = AndSelector(*selectors) |
|
663 if 'name' in kwargs: |
|
664 selector.__name__ = kwargs['name'] |
|
665 return selector |
|
666 |
|
667 def chainfirst(*selectors, **kwargs): |
|
668 """return a selector chaining given selectors. If all |
|
669 the selectors fail, selection will fail, else the returned score |
|
670 will be the first non-zero selector score |
|
671 """ |
|
672 assert selectors |
|
673 selector = OrSelector(*selectors) |
|
674 if 'name' in kwargs: |
|
675 selector.__name__ = kwargs['name'] |
|
676 return selector |