diff options
| author | Rapptz <[email protected]> | 2019-03-12 11:38:43 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2019-03-12 11:54:45 -0400 |
| commit | e1d9f8f59fe5a1e1eb5c926775f640ea8be385c9 (patch) | |
| tree | 2d5576394ea5372e3ee47c3f114a8e411288d186 /discord/ext/commands/cog.py | |
| parent | Add Category.create_text_channel/Category.create_voice_channel (#1976) (diff) | |
| download | discord.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.py | 23 |
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 |