182 |
182 |
183 raise :exc:`ObjectNotFound` if not object with id <oid> in <registry> |
183 raise :exc:`ObjectNotFound` if not object with id <oid> in <registry> |
184 |
184 |
185 raise :exc:`NoSelectableObject` if not object apply |
185 raise :exc:`NoSelectableObject` if not object apply |
186 """ |
186 """ |
187 return self._select_best(self[__oid], *args, **kwargs) |
187 obj = self._select_best(self[__oid], *args, **kwargs) |
|
188 if obj is None: |
|
189 raise NoSelectableObject(args, kwargs, self[__oid] ) |
|
190 return obj |
188 |
191 |
189 def select_or_none(self, __oid, *args, **kwargs): |
192 def select_or_none(self, __oid, *args, **kwargs): |
190 """return the most specific object among those with the given oid |
193 """return the most specific object among those with the given oid |
191 according to the given context, or None if no object applies. |
194 according to the given context, or None if no object applies. |
192 """ |
195 """ |
200 def possible_objects(self, *args, **kwargs): |
203 def possible_objects(self, *args, **kwargs): |
201 """return an iterator on possible objects in this registry for the given |
204 """return an iterator on possible objects in this registry for the given |
202 context |
205 context |
203 """ |
206 """ |
204 for appobjects in self.itervalues(): |
207 for appobjects in self.itervalues(): |
205 try: |
208 obj = self._select_best(appobjects, *args, **kwargs) |
206 yield self._select_best(appobjects, *args, **kwargs) |
209 if obj is None: |
207 except NoSelectableObject: |
|
208 continue |
210 continue |
|
211 yield obj |
209 |
212 |
210 def _select_best(self, appobjects, *args, **kwargs): |
213 def _select_best(self, appobjects, *args, **kwargs): |
211 """return an instance of the most specific object according |
214 """return an instance of the most specific object according |
212 to parameters |
215 to parameters |
213 |
216 |
214 raise `NoSelectableObject` if not object apply |
217 return None if not object apply (don't raise `NoSelectableObject` since |
|
218 it's costly when searching appobjects using `possible_objects` |
|
219 (e.g. searching for hooks). |
215 """ |
220 """ |
216 if len(args) > 1: |
221 if len(args) > 1: |
217 warn('[3.5] only the request param can not be named when calling select*', |
222 warn('[3.5] only the request param can not be named when calling select*', |
218 DeprecationWarning, stacklevel=3) |
223 DeprecationWarning, stacklevel=3) |
219 score, winners = 0, None |
224 score, winners = 0, None |
222 if appobjectscore > score: |
227 if appobjectscore > score: |
223 score, winners = appobjectscore, [appobject] |
228 score, winners = appobjectscore, [appobject] |
224 elif appobjectscore > 0 and appobjectscore == score: |
229 elif appobjectscore > 0 and appobjectscore == score: |
225 winners.append(appobject) |
230 winners.append(appobject) |
226 if winners is None: |
231 if winners is None: |
227 raise NoSelectableObject(args, kwargs, appobjects) |
232 return None |
228 if len(winners) > 1: |
233 if len(winners) > 1: |
229 # log in production environement / test, error while debugging |
234 # log in production environement / test, error while debugging |
230 msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)' |
235 msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)' |
231 if self.config.debugmode or self.config.mode == 'test': |
236 if self.config.debugmode or self.config.mode == 'test': |
232 # raise bare exception in debug mode |
237 # raise bare exception in debug mode |