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 |