aboutsummaryrefslogtreecommitdiff
path: root/discord/ext/commands/cog.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2019-03-12 11:38:43 -0400
committerRapptz <[email protected]>2019-03-12 11:54:45 -0400
commite1d9f8f59fe5a1e1eb5c926775f640ea8be385c9 (patch)
tree2d5576394ea5372e3ee47c3f114a8e411288d186 /discord/ext/commands/cog.py
parentAdd Category.create_text_channel/Category.create_voice_channel (#1976) (diff)
downloaddiscord.py-e1d9f8f59fe5a1e1eb5c926775f640ea8be385c9.tar.xz
discord.py-e1d9f8f59fe5a1e1eb5c926775f640ea8be385c9.zip
[commands] Support staticmethod listeners and disallow them in commands
Diffstat (limited to 'discord/ext/commands/cog.py')
-rw-r--r--discord/ext/commands/cog.py23
1 files changed, 18 insertions, 5 deletions
diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py
index 8e9930ed..5892ffa1 100644
--- a/discord/ext/commands/cog.py
+++ b/discord/ext/commands/cog.py
@@ -94,7 +94,13 @@ class CogMeta(type):
listeners = []
for elem, value in attrs.items():
+ is_static_method = isinstance(value, staticmethod)
+ if is_static_method:
+ value = value.__func__
if isinstance(value, _BaseCommand):
+ 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:
@@ -211,14 +217,21 @@ class Cog(metaclass=CogMeta):
raise TypeError('Cog.listener expected str but received {0.__class__.__name__!r} instead.'.format(name))
def decorator(func):
- if not inspect.iscoroutinefunction(func):
+ actual = func
+ if isinstance(actual, staticmethod):
+ actual = actual.__func__
+ if not inspect.iscoroutinefunction(actual):
raise TypeError('Listener function must be a coroutine function.')
- func.__cog_listener__ = True
- to_assign = name or func.__name__
+ actual.__cog_listener__ = True
+ to_assign = name or actual.__name__
try:
- func.__cog_listener_names__.append(to_assign)
+ actual.__cog_listener_names__.append(to_assign)
except AttributeError:
- func.__cog_listener_names__ = [to_assign]
+ actual.__cog_listener_names__ = [to_assign]
+ # we have to return `func` instead of `actual` because
+ # we need the type to be `staticmethod` for the metaclass
+ # to pick it up but the metaclass unfurls the function and
+ # thus the assignments need to be on the actual function
return func
return decorator