[commands] Walk through MRO for Cog derived classes.
This should support cog subclasses in a relatively consistent way in terms of expectations. Hopefully nothing is broken. Fixes #1950
This commit is contained in:
parent
cb9ae7bd76
commit
f43690bde8
@ -90,30 +90,44 @@ class CogMeta(type):
|
|||||||
attrs['__cog_name__'] = kwargs.pop('name', name)
|
attrs['__cog_name__'] = kwargs.pop('name', name)
|
||||||
attrs['__cog_settings__'] = command_attrs = kwargs.pop('command_attrs', {})
|
attrs['__cog_settings__'] = command_attrs = kwargs.pop('command_attrs', {})
|
||||||
|
|
||||||
commands = []
|
commands = {}
|
||||||
listeners = []
|
listeners = {}
|
||||||
|
|
||||||
|
new_cls = super().__new__(cls, name, bases, attrs, **kwargs)
|
||||||
|
for base in reversed(new_cls.__mro__):
|
||||||
|
for elem, value in base.__dict__.items():
|
||||||
|
if elem in commands:
|
||||||
|
del commands[elem]
|
||||||
|
if elem in listeners:
|
||||||
|
del listeners[elem]
|
||||||
|
|
||||||
for elem, value in attrs.items():
|
|
||||||
is_static_method = isinstance(value, staticmethod)
|
is_static_method = isinstance(value, staticmethod)
|
||||||
if is_static_method:
|
if is_static_method:
|
||||||
value = value.__func__
|
value = value.__func__
|
||||||
if isinstance(value, _BaseCommand):
|
if isinstance(value, _BaseCommand):
|
||||||
if is_static_method:
|
if is_static_method:
|
||||||
raise TypeError('Command in method {0!r} must not be staticmethod.'.format(elem))
|
raise TypeError('Command in method {0}.{1!r} must not be staticmethod.'.format(base, elem))
|
||||||
|
|
||||||
commands.append(value)
|
commands[elem] = value
|
||||||
elif inspect.iscoroutinefunction(value):
|
elif inspect.iscoroutinefunction(value):
|
||||||
try:
|
try:
|
||||||
is_listener = getattr(value, '__cog_listener__')
|
is_listener = getattr(value, '__cog_listener__')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
for listener_name in value.__cog_listener_names__:
|
listeners[elem] = value
|
||||||
listeners.append((listener_name, value.__name__))
|
|
||||||
|
|
||||||
attrs['__cog_commands__'] = commands # this will be copied in Cog.__new__
|
new_cls.__cog_commands__ = list(commands.values()) # this will be copied in Cog.__new__
|
||||||
attrs['__cog_listeners__'] = tuple(listeners)
|
|
||||||
return super().__new__(cls, name, bases, attrs, **kwargs)
|
listeners_as_list = []
|
||||||
|
for listener in listeners.values():
|
||||||
|
for listener_name in listener.__cog_listener_names__:
|
||||||
|
# I use __name__ instead of just storing the value so I can inject
|
||||||
|
# the self attribute when the time comes to add them to the bot
|
||||||
|
listeners_as_list.append((listener_name, listener.__name__))
|
||||||
|
|
||||||
|
new_cls.__cog_listeners__ = listeners_as_list
|
||||||
|
return new_cls
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user