aboutsummaryrefslogtreecommitdiff
path: root/discord/ext/commands/cog.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2019-03-17 22:03:44 -0400
committerRapptz <[email protected]>2019-03-17 22:04:05 -0400
commitf43690bde8628844a4cee8366f9bb310b92c4e60 (patch)
tree5e782d7a6fd476a710136b1dbdae3faf4cbc0157 /discord/ext/commands/cog.py
parentSorting bucket requires an integer. (diff)
downloaddiscord.py-f43690bde8628844a4cee8366f9bb310b92c4e60.tar.xz
discord.py-f43690bde8628844a4cee8366f9bb310b92c4e60.zip
[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
Diffstat (limited to 'discord/ext/commands/cog.py')
-rw-r--r--discord/ext/commands/cog.py60
1 files changed, 37 insertions, 23 deletions
diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py
index 425b6300..628a7a1c 100644
--- a/discord/ext/commands/cog.py
+++ b/discord/ext/commands/cog.py
@@ -90,30 +90,44 @@ class CogMeta(type):
attrs['__cog_name__'] = kwargs.pop('name', name)
attrs['__cog_settings__'] = command_attrs = kwargs.pop('command_attrs', {})
- commands = []
- listeners = []
-
- for elem, value in attrs.items():
- is_static_method = isinstance(value, staticmethod)
- if is_static_method:
- value = value.__func__
- if isinstance(value, _BaseCommand):
+ commands = {}
+ 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]
+
+ is_static_method = isinstance(value, staticmethod)
if is_static_method:
- raise TypeError('Command in method {0!r} must not be staticmethod.'.format(elem))
-
- commands.append(value)
- elif inspect.iscoroutinefunction(value):
- try:
- is_listener = getattr(value, '__cog_listener__')
- except AttributeError:
- continue
- else:
- for listener_name in value.__cog_listener_names__:
- listeners.append((listener_name, value.__name__))
-
- attrs['__cog_commands__'] = commands # this will be copied in Cog.__new__
- attrs['__cog_listeners__'] = tuple(listeners)
- return super().__new__(cls, name, bases, attrs, **kwargs)
+ value = value.__func__
+ if isinstance(value, _BaseCommand):
+ if is_static_method:
+ raise TypeError('Command in method {0}.{1!r} must not be staticmethod.'.format(base, elem))
+
+ commands[elem] = value
+ elif inspect.iscoroutinefunction(value):
+ try:
+ is_listener = getattr(value, '__cog_listener__')
+ except AttributeError:
+ continue
+ else:
+ listeners[elem] = value
+
+ new_cls.__cog_commands__ = list(commands.values()) # this will be copied in Cog.__new__
+
+ 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):
super().__init__(*args)