c2c85f483cfb1fcfdf4a54021e90c11a1112345e
1 import collections
as _collections
2 import inspect
as _inspect
3 import operator
as _operator
5 from . import core
as _core
8 class DispatcherMeta(type):
9 def __new__(metacls
, name
, bases
, ns
):
10 conflicts
= _collections
.defaultdict(list)
11 for (key
, value
) in tuple(ns
.items()):
12 if not isinstance(value
, _core
.CallHook
):
16 conflicts
[typeid
].append(key
)
19 for (typeid
, keys
) in conflicts
.items():
21 raise ValueError(f
"dispatch conflict: {keys!r}")
23 return super().__new
__(metacls
, name
, bases
, ns
)
25 def __init__(cls
, name
, bases
, ns
):
27 for hook
in map(_operator
.itemgetter(1), _inspect
.getmembers(cls
,
28 predicate
=lambda member
: isinstance(member
, _core
.CallHook
))):
32 return super().__init
__(name
, bases
, ns
)
34 def dispatch(cls
, typeid
=object):
35 return cls
.__hooks
.get(typeid
)
38 class Dispatcher(metaclass
=DispatcherMeta
):
39 def __call__(self
, instance
):
40 for typeid
in instance
.__class
__.__mro
__:
41 hook
= self
.__class
__.dispatch(typeid
=typeid
)
45 hook
= self
.__class
__.dispatch()
46 return hook(dispatcher
=self
, instance
=instance
)
49 def dispatch_object(self
, instance
):
50 raise NotImplementedError()