From ac2813012acf3e9a7f87606e6ec820782168458c Mon Sep 17 00:00:00 2001 From: Michael H Date: Fri, 12 Jul 2019 22:11:06 -0400 Subject: [PATCH] [Core] Cog load fixes (#2854) * split out some fixes from red#2853 * address feedback * feedback --- redbot/core/bot.py | 60 ++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/redbot/core/bot.py b/redbot/core/bot.py index 26a928c30..a6d48a0c9 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -407,32 +407,50 @@ class RedBase(commands.GroupMixin, commands.bot.BotBase, RPCMixin): # pylint: d f"not inherit from the commands.Cog base class. The cog author must update " f"the cog to adhere to this requirement." ) + if cog.__cog_name__ in self.cogs: + raise RuntimeError(f"There is already a cog named {cog.__cog_name__} loaded.") if not hasattr(cog, "requires"): commands.Cog.__init__(cog) - for cls in inspect.getmro(cog.__class__): - try: - hook = getattr(cog, f"_{cls.__name__}__permissions_hook") - except AttributeError: - pass - else: - self.add_permissions_hook(hook) + added_hooks = [] - for command in cog.__cog_commands__: + try: + for cls in inspect.getmro(cog.__class__): + try: + hook = getattr(cog, f"_{cls.__name__}__permissions_hook") + except AttributeError: + pass + else: + self.add_permissions_hook(hook) + added_hooks.append(hook) - if not isinstance(command, commands.Command): - raise RuntimeError( - f"The {cog.__class__.__name__} cog in the {cog.__module__} package," - " is not using Red's command module, and cannot be added. " - "If this is your cog, please use `from redbot.core import commands`" - "in place of `from discord.ext import commands`. For more details on " - "this requirement, see this page: " - "http://red-discordbot.readthedocs.io/en/v3-develop/framework_commands.html" - ) - super().add_cog(cog) - self.dispatch("cog_add", cog) - for command in cog.__cog_commands__: - self.dispatch("command_add", command) + for command in cog.__cog_commands__: + + if not isinstance(command, commands.Command): + raise RuntimeError( + f"The {cog.__class__.__name__} cog in the {cog.__module__} package," + " is not using Red's command module, and cannot be added. " + "If this is your cog, please use `from redbot.core import commands`" + "in place of `from discord.ext import commands`. For more details on " + "this requirement, see this page: " + "http://red-discordbot.readthedocs.io/en/v3-develop/framework_commands.html" + ) + super().add_cog(cog) + self.dispatch("cog_add", cog) + for command in cog.__cog_commands__: + self.dispatch("command_add", command) + except Exception: + for hook in added_hooks: + try: + self.remove_permissions_hook(hook) + except Exception: + # This shouldn't be possible + log.exception( + "A hook got extremely screwed up, " + "and could not be removed properly during another error in cog load." + ) + del cog + raise def clear_permission_rules(self, guild_id: Optional[int]) -> None: """Clear all permission overrides in a scope.