selectors.py
branchstable
changeset 3522 cde0ff4f7a8c
parent 3350 fa77640a9155
child 3524 a3431f4e2f40
child 3638 648d6dbec630
equal deleted inserted replaced
3521:ad041dae15aa 3522:cde0ff4f7a8c
   148 
   148 
   149 
   149 
   150 class ImplementsMixIn(object):
   150 class ImplementsMixIn(object):
   151     """mix-in class for selectors checking implemented interfaces of something
   151     """mix-in class for selectors checking implemented interfaces of something
   152     """
   152     """
   153     def __init__(self, *expected_ifaces):
   153     def __init__(self, *expected_ifaces, **kwargs):
   154         super(ImplementsMixIn, self).__init__()
   154         super(ImplementsMixIn, self).__init__(**kwargs)
   155         self.expected_ifaces = expected_ifaces
   155         self.expected_ifaces = expected_ifaces
   156 
   156 
   157     def __str__(self):
   157     def __str__(self):
   158         return '%s(%s)' % (self.__class__.__name__,
   158         return '%s(%s)' % (self.__class__.__name__,
   159                            ','.join(str(s) for s in self.expected_ifaces))
   159                            ','.join(str(s) for s in self.expected_ifaces))
   183       - `once_is_enough` is True, in which case the first non-zero score is
   183       - `once_is_enough` is True, in which case the first non-zero score is
   184         returned
   184         returned
   185       - `once_is_enough` is False, in which case if score_class return 0, 0 is
   185       - `once_is_enough` is False, in which case if score_class return 0, 0 is
   186         returned
   186         returned
   187     """
   187     """
   188     def __init__(self, once_is_enough=False):
   188     def __init__(self, once_is_enough=False, accept_none=True):
   189         self.once_is_enough = once_is_enough
   189         self.once_is_enough = once_is_enough
       
   190         self.accept_none = accept_none
   190 
   191 
   191     @lltrace
   192     @lltrace
   192     def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
   193     def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
   193         if not rset:
   194         if not rset:
   194             return 0
   195             return 0
   195         score = 0
   196         score = 0
   196         if row is None:
   197         if row is None:
       
   198             if not self.accept_none:
       
   199                 if any(rset[i][col] is None for i in xrange(len(rset))):
       
   200                     return 0
   197             for etype in rset.column_types(col):
   201             for etype in rset.column_types(col):
   198                 if etype is None: # outer join
   202                 if etype is None: # outer join
   199                     continue
   203                     return 0
   200                 escore = self.score(cls, req, etype)
   204                 escore = self.score(cls, req, etype)
   201                 if not escore and not self.once_is_enough:
   205                 if not escore and not self.once_is_enough:
   202                     return 0
   206                     return 0
   203                 elif self.once_is_enough:
   207                 elif self.once_is_enough:
   204                     return escore
   208                     return escore