# HG changeset patch # User Alexandre Fayolle # Date 1303915081 -7200 # Node ID 771f594c12a283df2a278567ce8cdfc5e8a32546 # Parent 2bd70418b601de3853579e94f662b332c3be2b20 [vreg] vregistry._select_best was needlessly instanciating NoSelectableObject (closes #1626708) in large selections, this incurred a non negligible cost (add_relations with 2000 inlined relations runs 7% faster with this patch) diff -r 2bd70418b601 -r 771f594c12a2 cwvreg.py --- a/cwvreg.py Thu Apr 28 15:30:16 2011 +0200 +++ b/cwvreg.py Wed Apr 27 16:38:01 2011 +0200 @@ -402,10 +402,8 @@ if not isinstance(view, class_deprecated)] try: view = self._select_best(views, req, rset=rset, **kwargs) - if view.linkable(): + if view is not None and view.linkable(): yield view - except NoSelectableObject: - continue except Exception: self.exception('error while trying to select %s view for %s', vid, rset) diff -r 2bd70418b601 -r 771f594c12a2 devtools/testlib.py --- a/devtools/testlib.py Thu Apr 28 15:30:16 2011 +0200 +++ b/devtools/testlib.py Wed Apr 27 16:38:01 2011 +0200 @@ -562,6 +562,8 @@ if views: try: view = viewsvreg._select_best(views, req, rset=rset) + if view is None: + raise NoSelectableObject((req,), {'rset':rset}, views) if view.linkable(): yield view else: diff -r 2bd70418b601 -r 771f594c12a2 vregistry.py --- a/vregistry.py Thu Apr 28 15:30:16 2011 +0200 +++ b/vregistry.py Wed Apr 27 16:38:01 2011 +0200 @@ -184,7 +184,10 @@ raise :exc:`NoSelectableObject` if not object apply """ - return self._select_best(self[__oid], *args, **kwargs) + obj = self._select_best(self[__oid], *args, **kwargs) + if obj is None: + raise NoSelectableObject(args, kwargs, self[__oid] ) + return obj def select_or_none(self, __oid, *args, **kwargs): """return the most specific object among those with the given oid @@ -202,16 +205,18 @@ context """ for appobjects in self.itervalues(): - try: - yield self._select_best(appobjects, *args, **kwargs) - except NoSelectableObject: + obj = self._select_best(appobjects, *args, **kwargs) + if obj is None: continue + yield obj def _select_best(self, appobjects, *args, **kwargs): """return an instance of the most specific object according to parameters - raise `NoSelectableObject` if not object apply + return None if not object apply (don't raise `NoSelectableObject` since + it's costly when searching appobjects using `possible_objects` + (e.g. searching for hooks). """ if len(args) > 1: warn('[3.5] only the request param can not be named when calling select*', @@ -224,7 +229,7 @@ elif appobjectscore > 0 and appobjectscore == score: winners.append(appobject) if winners is None: - raise NoSelectableObject(args, kwargs, appobjects) + return None if len(winners) > 1: # log in production environement / test, error while debugging msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)' diff -r 2bd70418b601 -r 771f594c12a2 web/views/urlpublishing.py --- a/web/views/urlpublishing.py Thu Apr 28 15:30:16 2011 +0200 +++ b/web/views/urlpublishing.py Wed Apr 27 16:38:01 2011 +0200 @@ -260,9 +260,8 @@ else: try: action = actionsreg._select_best(actions, req, rset=rset) + if action is not None: + raise Redirect(action.url()) except RegistryException: - continue - else: - # XXX avoid redirect - raise Redirect(action.url()) + pass # continue searching raise PathDontMatch()