From fe588a4d527f80804543cea6dbb5743fcbd786e1 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Mon, 20 Mar 2017 23:59:23 -0400 Subject: [PATCH] [commands] Change GroupMixin.commands to all_commands This is a breaking change as GroupMixin.commands now returns a set of unique Command objects. --- discord/ext/commands/bot.py | 10 +++++----- discord/ext/commands/core.py | 31 ++++++++++++++++++------------- discord/ext/commands/formatter.py | 4 ++-- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py index 733cfec26..3f5292771 100644 --- a/discord/ext/commands/bot.py +++ b/discord/ext/commands/bot.py @@ -93,7 +93,7 @@ def _default_help_command(ctx, *commands : str): if name in bot.cogs: command = bot.cogs[name] else: - command = bot.commands.get(name) + command = bot.all_commands.get(name) if command is None: yield from destination.send(bot.command_not_found.format(name)) return @@ -101,7 +101,7 @@ def _default_help_command(ctx, *commands : str): pages = yield from bot.formatter.format_help_for(ctx, command) else: name = _mention_pattern.sub(repl, commands[0]) - command = bot.commands.get(name) + command = bot.all_commands.get(name) if command is None: yield from destination.send(bot.command_not_found.format(name)) return @@ -109,7 +109,7 @@ def _default_help_command(ctx, *commands : str): for key in commands[1:]: try: key = _mention_pattern.sub(repl, key) - command = command.commands.get(key) + command = command.all_commands.get(key) if command is None: yield from destination.send(bot.command_not_found.format(key)) return @@ -564,7 +564,7 @@ class BotBase(GroupMixin): self.remove_cog(cogname) # first remove all the commands from the module - for command in self.commands.copy().values(): + for command in self.all_commands.copy().values(): if command.module is lib: command.module = None if isinstance(command, GroupMixin): @@ -676,7 +676,7 @@ class BotBase(GroupMixin): invoker = view.get_word() ctx.invoked_with = invoker ctx.prefix = invoked_prefix - ctx.command = self.commands.get(invoker) + ctx.command = self.all_commands.get(invoker) return ctx @asyncio.coroutine diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index b335e87ba..71d5ff4be 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -589,16 +589,21 @@ class GroupMixin: Attributes ----------- - commands : dict + all_commands: dict A mapping of command name to :class:`Command` or superclass objects. """ def __init__(self, **kwargs): - self.commands = {} + self.all_commands = {} super().__init__(**kwargs) + @property + def commands(self): + """Set[:class:`Command`]: A unique set of commands without aliases that are registered.""" + return set(self.all_commands.values()) + def recursively_remove_all_commands(self): - for command in self.commands.copy().values(): + for command in self.all_commands.copy().values(): if isinstance(command, GroupMixin): command.recursively_remove_all_commands() self.remove_command(command.name) @@ -629,14 +634,14 @@ class GroupMixin: if isinstance(self, Command): command.parent = self - if command.name in self.commands: + if command.name in self.all_commands: raise discord.ClientException('Command {0.name} is already registered.'.format(command)) - self.commands[command.name] = command + self.all_commands[command.name] = command for alias in command.aliases: - if alias in self.commands: + if alias in self.all_commands: raise discord.ClientException('The alias {} is already an existing command or alias.'.format(alias)) - self.commands[alias] = command + self.all_commands[alias] = command def remove_command(self, name): """Remove a :class:`Command` or subclasses from the internal list @@ -655,7 +660,7 @@ class GroupMixin: The command that was removed. If the name is not valid then `None` is returned instead. """ - command = self.commands.pop(name, None) + command = self.all_commands.pop(name, None) # does not exist if command is None: @@ -667,12 +672,12 @@ class GroupMixin: # we're not removing the alias so let's delete the rest of them. for alias in command.aliases: - self.commands.pop(alias, None) + self.all_commands.pop(alias, None) return command def walk_commands(self): """An iterator that recursively walks through all commands and subcommands.""" - for command in tuple(self.commands.values()): + for command in tuple(self.all_commands.values()): yield command if isinstance(command, GroupMixin): yield from command.walk_commands() @@ -699,13 +704,13 @@ class GroupMixin: """ names = name.split() - obj = self.commands.get(names[0]) + obj = self.all_commands.get(names[0]) if not isinstance(obj, GroupMixin): return obj for name in names[1:]: try: - obj = obj.commands[name] + obj = obj.all_commands[name] except (AttributeError, KeyError): return None @@ -769,7 +774,7 @@ class Group(GroupMixin, Command): if trigger: ctx.subcommand_passed = trigger - ctx.invoked_subcommand = self.commands.get(trigger, None) + ctx.invoked_subcommand = self.all_commands.get(trigger, None) if early_invoke: injected = hooked_wrapped_callback(self, ctx, self.callback) diff --git a/discord/ext/commands/formatter.py b/discord/ext/commands/formatter.py index c0ac67818..5c9fff2f4 100644 --- a/discord/ext/commands/formatter.py +++ b/discord/ext/commands/formatter.py @@ -171,7 +171,7 @@ class HelpFormatter: """int : Returns the largest name length of a command or if it has subcommands the largest subcommand name.""" try: - commands = self.command.commands if not self.is_cog() else self.context.bot.commands + commands = self.command.all_commands if not self.is_cog() else self.context.bot.all_commands if commands: return max(map(lambda c: len(c.name) if self.show_hidden or not c.hidden else 0, commands.values())) return 0 @@ -265,7 +265,7 @@ class HelpFormatter: except CommandError: return False - iterator = self.command.commands.items() if not self.is_cog() else self.context.bot.commands.items() + iterator = self.command.all_commands.items() if not self.is_cog() else self.context.bot.all_commands.items() if self.show_check_failure: return filter(sane_no_suspension_point_predicate, iterator)