[Commands] Refactor command and group decorators (#1818)

* [V3 Commands] Refactor command and group decorators

* Add some tests

* Fix docs reference

* Tweak Group's MRO
This commit is contained in:
Toby Harradine 2018-08-26 23:25:25 +10:00 committed by GitHub
parent f595afab18
commit 48a7a21aca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 14 deletions

View File

@ -8,8 +8,6 @@ from pathlib import Path
import discord
import sys
from discord.ext.commands.bot import BotBase
from discord.ext.commands import GroupMixin
from discord.ext.commands import when_mentioned_or
# This supresses the PyNaCl warning that isn't relevant here
@ -29,7 +27,7 @@ def _is_submodule(parent, child):
return parent == child or child.startswith(parent + ".")
class RedBase(BotBase, RPCMixin):
class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin):
"""Mixin for the main bot class.
This exists because `Red` inherits from `discord.AutoShardedClient`, which
@ -255,7 +253,7 @@ class RedBase(BotBase, RPCMixin):
# first remove all the commands from the module
for cmd in self.all_commands.copy().values():
if cmd.module and _is_submodule(lib_name, cmd.module):
if isinstance(cmd, GroupMixin):
if isinstance(cmd, discord.ext.commands.GroupMixin):
cmd.recursively_remove_all_commands()
self.remove_command(cmd.name)

View File

@ -14,7 +14,7 @@ from ..i18n import Translator
if TYPE_CHECKING:
from .context import Context
__all__ = ["Command", "Group", "command", "group"]
__all__ = ["Command", "GroupMixin", "Group", "command", "group"]
_ = Translator("commands.commands", __file__)
@ -104,11 +104,17 @@ class Command(commands.Command):
# We should expose anything which might be a bug in the converter
raise exc
def command(self, cls=None, *args, **kwargs):
class GroupMixin(commands.GroupMixin):
"""Mixin for `Group` and `Red` classes.
This class inherits from :class:`discord.ext.commands.GroupMixin`.
"""
def command(self, *args, **kwargs):
"""A shortcut decorator that invokes :func:`.command` and adds it to
the internal command list via :meth:`~.GroupMixin.add_command`.
the internal command list.
"""
cls = cls or self.__class__
def decorator(func):
result = command(*args, **kwargs)(func)
@ -117,11 +123,10 @@ class Command(commands.Command):
return decorator
def group(self, cls=None, *args, **kwargs):
def group(self, *args, **kwargs):
"""A shortcut decorator that invokes :func:`.group` and adds it to
the internal command list via :meth:`~.GroupMixin.add_command`.
the internal command list.
"""
cls = None or Group
def decorator(func):
result = group(*args, **kwargs)(func)
@ -131,11 +136,11 @@ class Command(commands.Command):
return decorator
class Group(Command, commands.Group):
class Group(GroupMixin, Command, commands.Group):
"""Group command class for Red.
This class inherits from `discord.ext.commands.Group`, with `Command` mixed
in.
This class inherits from `Command`, with :class:`GroupMixin` and
`discord.ext.commands.Group` mixed in.
"""
def __init__(self, *args, **kwargs):

View File

@ -0,0 +1,34 @@
import pytest
from redbot.core import commands
@pytest.fixture(scope="session")
def group():
@commands.group()
async def fixturegroup(*args, **kwargs):
return args, kwargs
return fixturegroup
def is_Command(obj):
return isinstance(obj, commands.Command)
def is_Group(obj):
return isinstance(obj, commands.Group)
def test_command_decorators(coroutine):
assert is_Command(commands.command(name="cmd")(coroutine))
assert is_Group(commands.group(name="grp")(coroutine))
def test_group_decorator_methods(group, coroutine):
assert is_Command(group.command(name="cmd")(coroutine))
assert is_Group(group.group(name="grp")(coroutine))
def test_bot_decorator_methods(red, coroutine):
assert is_Command(red.command(name="cmd")(coroutine))
assert is_Group(red.group(name="grp")(coroutine))