diff --git a/redbot/core/bot.py b/redbot/core/bot.py index d53f994da96..04ba6aa1985 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -8,8 +8,6 @@ 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 @@ def unload_extension(self, name): # 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) diff --git a/redbot/core/commands/commands.py b/redbot/core/commands/commands.py index 46e855ddc79..016cd1ec22e 100644 --- a/redbot/core/commands/commands.py +++ b/redbot/core/commands/commands.py @@ -14,7 +14,7 @@ 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 @@ async def do_conversion( # 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 @@ def decorator(func): 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 @@ def decorator(func): 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): diff --git a/tests/core/test_commands.py b/tests/core/test_commands.py new file mode 100644 index 00000000000..9217fc1149e --- /dev/null +++ b/tests/core/test_commands.py @@ -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))