From 132d3b19317e6489df9a406bd10cc6d57edd221a Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Wed, 14 Jun 2023 12:53:06 +0300 Subject: [PATCH] dispatcher: refactor hooks binding process --- src/mdis/dispatcher.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/mdis/dispatcher.py b/src/mdis/dispatcher.py index c2c85f4..9406763 100644 --- a/src/mdis/dispatcher.py +++ b/src/mdis/dispatcher.py @@ -1,18 +1,27 @@ import collections as _collections import inspect as _inspect -import operator as _operator +import types as _types from . import core as _core class DispatcherMeta(type): def __new__(metacls, name, bases, ns): + hooks = {} + ishook = lambda member: isinstance(member, _core.CallHook) + + for basecls in reversed(bases): + members = _inspect.getmembers(basecls, predicate=ishook) + for (_, hook) in members: + hooks.update(dict.fromkeys(hook, hook)) + conflicts = _collections.defaultdict(list) for (key, value) in tuple(ns.items()): - if not isinstance(value, _core.CallHook): + if not ishook(value): continue hook = value for typeid in hook: + hooks[typeid] = hook conflicts[typeid].append(key) ns[key] = hook @@ -20,19 +29,12 @@ class DispatcherMeta(type): if len(keys) > 1: raise ValueError(f"dispatch conflict: {keys!r}") - return super().__new__(metacls, name, bases, ns) + ns["__hooks__"] = _types.MappingProxyType(hooks) - def __init__(cls, name, bases, ns): - hooks = {} - for hook in map(_operator.itemgetter(1), _inspect.getmembers(cls, - predicate=lambda member: isinstance(member, _core.CallHook))): - for typeid in hook: - hooks[typeid] = hook - cls.__hooks = hooks - return super().__init__(name, bases, ns) + return super().__new__(metacls, name, bases, ns) def dispatch(cls, typeid=object): - return cls.__hooks.get(typeid) + return cls.__hooks__.get(typeid) class Dispatcher(metaclass=DispatcherMeta): -- 2.30.2