138 if len(selectors) == 1: |
138 if len(selectors) == 1: |
139 # micro optimization: don't bother with AndSelector if there's |
139 # micro optimization: don't bother with AndSelector if there's |
140 # only one selector |
140 # only one selector |
141 select = _instantiate_selector(selectors[0]) |
141 select = _instantiate_selector(selectors[0]) |
142 else: |
142 else: |
143 select = AndSelector(*[_instantiate_selector(selector) |
143 select = AndSelector(*selectors) |
144 for selector in selectors]) |
|
145 cls.__select__ = select |
144 cls.__select__ = select |
146 |
145 |
147 |
146 |
148 class VRegistry(object): |
147 class VRegistry(object): |
149 """class responsible to register, propose and select the various |
148 """class responsible to register, propose and select the various |
577 if self is selector: |
576 if self is selector: |
578 return self |
577 return self |
579 if isinstance(selector, type) and isinstance(self, selector): |
578 if isinstance(selector, type) and isinstance(self, selector): |
580 return self |
579 return self |
581 return None |
580 return None |
|
581 |
|
582 def __str__(self): |
|
583 return self.__class__.__name__ |
582 |
584 |
583 def __and__(self, other): |
585 def __and__(self, other): |
584 return AndSelector(self, other) |
586 return AndSelector(self, other) |
585 def __rand__(self, other): |
587 def __rand__(self, other): |
586 return AndSelector(other, self) |
588 return AndSelector(other, self) |
600 """base class for compound selector classes""" |
602 """base class for compound selector classes""" |
601 |
603 |
602 def __init__(self, *selectors): |
604 def __init__(self, *selectors): |
603 self.selectors = self.merge_selectors(selectors) |
605 self.selectors = self.merge_selectors(selectors) |
604 |
606 |
|
607 def __str__(self): |
|
608 return '%s(%s)' % (self.__class__.__name__, |
|
609 ','.join(str(s) for s in self.selectors)) |
|
610 |
605 @classmethod |
611 @classmethod |
606 def merge_selectors(cls, selectors): |
612 def merge_selectors(cls, selectors): |
607 """merge selectors when possible : |
613 """deal with selector instanciation when necessary and merge |
|
614 multi-selectors if possible: |
608 |
615 |
609 AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4)) |
616 AndSelector(AndSelector(sel1, sel2), AndSelector(sel3, sel4)) |
610 ==> AndSelector(sel1, sel2, sel3, sel4) |
617 ==> AndSelector(sel1, sel2, sel3, sel4) |
611 """ |
618 """ |
612 merged_selectors = [] |
619 merged_selectors = [] |
613 for selector in selectors: |
620 for selector in selectors: |
|
621 selector = _instantiate_selector(selector) |
|
622 assert isinstance(selector, Selector), selector |
614 if isinstance(selector, cls): |
623 if isinstance(selector, cls): |
615 merged_selectors += selector.selectors |
624 merged_selectors += selector.selectors |
616 else: |
625 else: |
617 merged_selectors.append(selector) |
626 merged_selectors.append(selector) |
618 return merged_selectors |
627 return merged_selectors |
620 def search_selector(self, selector): |
629 def search_selector(self, selector): |
621 """search for the given selector or selector instance in the selectors |
630 """search for the given selector or selector instance in the selectors |
622 tree. Return it of None if not found |
631 tree. Return it of None if not found |
623 """ |
632 """ |
624 for childselector in self.selectors: |
633 for childselector in self.selectors: |
625 try: |
634 if childselector is selector: |
626 if childselector.use_selector(selector): |
635 return childselector |
627 return childselector |
636 found = childselector.search_selector(selector) |
628 except AttributeError: # simple function |
637 if found is not None: |
629 if childselector is selector: |
638 return found |
630 return childselector |
|
631 return None |
639 return None |
632 |
640 |
633 |
641 |
634 def objectify_selector(selector_func): |
642 def objectify_selector(selector_func): |
635 """convenience decorator for simple selectors where a class definition |
643 """convenience decorator for simple selectors where a class definition |
684 the selectors fail, selection will fail, else the returned score |
692 the selectors fail, selection will fail, else the returned score |
685 will be the sum of each selector'score |
693 will be the sum of each selector'score |
686 """ |
694 """ |
687 assert selectors |
695 assert selectors |
688 # XXX do we need to create the AndSelector here, a tuple might be enough |
696 # XXX do we need to create the AndSelector here, a tuple might be enough |
689 selector = AndSelector(*[_instantiate_selector(selector) |
697 selector = AndSelector(*selectors) |
690 for selector in selectors]) |
|
691 if 'name' in kwargs: |
698 if 'name' in kwargs: |
692 selector.__name__ = kwargs['name'] |
699 selector.__name__ = kwargs['name'] |
693 return selector |
700 return selector |
694 |
701 |
695 def chainfirst(*selectors, **kwargs): |
702 def chainfirst(*selectors, **kwargs): |
696 """return a selector chaining given selectors. If all |
703 """return a selector chaining given selectors. If all |
697 the selectors fail, selection will fail, else the returned score |
704 the selectors fail, selection will fail, else the returned score |
698 will be the first non-zero selector score |
705 will be the first non-zero selector score |
699 """ |
706 """ |
700 assert selectors |
707 assert selectors |
701 selector = OrSelector(*[_instantiate_selector(selector) |
708 selector = OrSelector(*selectors) |
702 for selector in selectors]) |
|
703 if 'name' in kwargs: |
709 if 'name' in kwargs: |
704 selector.__name__ = kwargs['name'] |
710 selector.__name__ = kwargs['name'] |
705 return selector |
711 return selector |