def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls._reaction_map = OrderedDict()
_suppressed_methods = set()
# We can't use inspect.getmembers because it returns the members in
# lexographical order, rather than definition order.
for name, member in itertools.chain.from_iterable(b.__dict__.items() for b in cls.__mro__):
if name.startswith('_'):
continue
# Support for using functools.partialmethod as a means of simplifying pages.
is_callable = callable(member) or isinstance(member, functools.partialmethod)
# Support suppressing page methods by assigning them to None
if not (member is None or is_callable):
continue
# Let sub-classes override the current methods.
if name in cls._reaction_map.values():
continue
# Let subclasses suppress page methods.
if name in _suppressed_methods:
continue
if member is None:
_suppressed_methods.add(name)
continue
emoji = getattr(member, '__reaction_emoji__', None)
if emoji:
cls._reaction_map[emoji] = name
_log.debug('Initializing emoji %s for method %s in class %s',
hex(ord(emoji)), member.__qualname__, cls.__name__)
# We need to move stop to the end (assuming it exists).
# Otherwise it will show up somewhere in the middle
with contextlib.suppress(StopIteration):
key = next(k for k, v in cls._reaction_map.items() if v == 'stop')
cls._reaction_map.move_to_end(key)
评论列表
文章目录