diff options
-rw-r--r-- | logilab/common/registry.py | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/logilab/common/registry.py b/logilab/common/registry.py index 27b72b6..cfebe17 100644 --- a/logilab/common/registry.py +++ b/logilab/common/registry.py @@ -263,6 +263,7 @@ class Registry(dict): def __init__(self, debugmode): super(Registry, self).__init__() self.debugmode = debugmode + self._select_listeners = [] def __getitem__(self, name): """return the registry (list of implementation objects) associated to @@ -399,6 +400,17 @@ class Registry(dict): continue yield obj + def add_select_best_listener(self, listener): + """ + Add a listener to the list of one parameters callables (function/method) + that will be called everytime the selection Registry._select_best is + done and they will recieve a dict of the following form:: + + {"all_objects": [], "end_score": 0, "winners": [], "winner": None or winner, + "self": self, "args": args, "kwargs": kwargs, } + """ + self._select_listeners.append(listener) + def _select_best(self, objects, *args, **kwargs): """return an instance of the most specific object according to parameters @@ -407,30 +419,29 @@ class Registry(dict): 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:: + Every callable stored in Registry._select_listeners will be called + once the selection is done and will recieve a dict of the following form:: {"all_objects": [], "end_score": 0, "winners": [], "winner": None or winner, "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, - } + if self._select_listeners: + select_best_report = { + "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 self._select_listeners: + select_best_report["all_objects"].append({"object": obj, "score": objectscore}) if objectscore > score: score, winners = objectscore, [obj] @@ -438,11 +449,12 @@ class Registry(dict): 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["winner"] = winners[0] if winners else winners - debug_registry_select_best["end_score"] = score - debug_callback(debug_registry_select_best) + if self._select_listeners: + select_best_report["winners"] = winners.copy() if winners else [] + select_best_report["winner"] = winners[0] if winners else winners + select_best_report["end_score"] = score + for listener in self._select_listeners: + listener(select_best_report) if winners is None: return None |