diff options
-rw-r--r-- | logilab/common/registry.py | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/logilab/common/registry.py b/logilab/common/registry.py index 2a8a1c0..7820689 100644 --- a/logilab/common/registry.py +++ b/logilab/common/registry.py @@ -406,23 +406,56 @@ class Registry(dict): return None if not object apply (don't raise `NoSelectableObject` since it's costly when searching objects using `possible_objects` (e.g. searching for hooks). + + An optional argument `debug_callback` can be passed, it will be called + once the selection is done and will return a dict of the following form:: + + {"all_objects": [], "end_score": 0, "winners": [], + "self": self, "args": args, "kwargs": kwargs, } """ + + debug_callback = kwargs.pop('debug_callback', None) + + debug_registry_select_best = { + "all_objects": [], + "end_score": 0, + "winners": [], + "self": self, + "args": args, + "kwargs": kwargs, + } + score, winners = 0, None for obj in objects: objectscore = obj.__select__(obj, *args, **kwargs) + + if debug_callback: + debug_registry_select_best["all_objects"].append({"object": obj, "score": objectscore}) + if objectscore > score: score, winners = objectscore, [obj] + elif objectscore > 0 and objectscore == score: winners.append(obj) + + if debug_callback: + debug_registry_select_best["winners"] = winners.copy() if winners else [] + debug_registry_select_best["end_score"] = score + debug_callback(debug_registry_select_best) + if winners is None: return None + if len(winners) > 1: # log in production environement / test, error while debugging msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)' + if self.debugmode: # raise bare exception in debug mode raise SelectAmbiguity(msg % (winners, args, kwargs.keys())) + self.error(msg, winners, args, kwargs.keys()) + # return the result of calling the object return self.selected(winners[0], args, kwargs) |