Repository: Cog-Creators/Red-DiscordBot

Issue:
[API] add ability to check for disabled command
# Feature request

#### Select the type of feature you are requesting:

- [ ] Cog
- [ ] Command
- [X] API functionality

#### Describe your requested feature

Add ability to check if command is disabled. E.g. via command property `is_disabled_globally` and func `is_disabled(ctx)` or smth like that.

[API] add ability to check for disabled command
### Type of Feature Request

- [ ] Cog

- [ ] Command

- [x] API Functionality 

### Description of the changes
Previously, there was already a way to check whether the command is disabled using the command.enabled attribute, however, we needed to implement a way to check whether a command is disabled in a specific guild.

We made a method that checks whether a command is disabled in a specific guild in the Command class with the name is_disabled_in_guild(). This functions accepts a discord.Guild object as a positional-only argument and will return true if the command is disabled in the guild and returns false if the command is enabled in the guild.

Closes [#4130 ](https://github.com/Cog-Creators/Red-DiscordBot/issues/4130)


Discussion:
Hi! I am interested in working on this. Can I be assigned to this please?
Sure, I've assigned you.
For your information, it's already possible to check whether the command is disabled using the `command.enabled` attribute so that part is already covered by our APIs and you should only need to implement a way to check whether a command is disabled in a specific guild.
I think a preferred design would be to put a method for checking this in the Command class with the name `is_disabled_in_guild()` and have it accept a `discord.Guild` object as a positional-only argument.


Resolving patch:
diff --git a/redbot/core/commands/commands.py b/redbot/core/commands/commands.py
--- a/redbot/core/commands/commands.py
+++ b/redbot/core/commands/commands.py
@@ -461,11 +461,32 @@ async def can_run(
             if not change_permission_state:
                 ctx.permission_state = original_state
 
-    def is_enabled(self, ctx) -> bool:
+    def is_enabled(self, guild: Optional[discord.abc.Snowflake] = None) -> bool:
+        """
+        Check if the command is enabled globally or in a guild.
+
+        When guild is provided, this method checks whether
+        the command is enabled both globally and in the guild.
+
+        This is generally set by the settings managed with
+        the ``[p]command enable/disable global/server`` commands.
+
+        Parameters
+        ----------
+        guild : discord.abc.Snowflake, optional
+            The guild to check that the command is enabled in.
+            If this is ``None``, this will check whether
+            the command is enabled globally.
+
+        Returns
+        -------
+        bool
+            ``True`` if the command is enabled.
+        """
         if not self.enabled:
             return False
-        if ctx.guild:
-            if self._disabled_in.has(ctx.guild.id):
+        if guild is not None:
+            if self._disabled_in.has(guild.id):
                 return False
 
         return True
@@ -473,7 +494,7 @@ def is_enabled(self, ctx) -> bool:
     async def prepare(self, ctx, /):
         ctx.command = self
 
-        cmd_enabled = self.is_enabled(ctx)
+        cmd_enabled = self.is_enabled(ctx.guild)
         if not cmd_enabled:
             raise DisabledCommand(f"{self.name} command is disabled")
 
@@ -530,7 +551,15 @@ async def can_see(self, ctx: "Context"):
         return True
 
     def disable_in(self, guild: discord.Guild) -> bool:
-        """Disable this command in the given guild.
+        """
+        Disable this command in the given guild.
+
+        This is generally called by the settings managed with
+        the ``[p]command disable global/server`` commands.
+        Any changes made outside of that will not persist after cog
+        reload and may also be affected when either of those commands
+        is called on this command. It is not recommended to rely on
+        this method, if you want a consistent behavior.
 
         Parameters
         ----------
@@ -541,7 +570,6 @@ def disable_in(self, guild: discord.Guild) -> bool:
         -------
         bool
             ``True`` if the command wasn't already disabled.
-
         """
         if self._disabled_in.has(guild.id):
             return False
@@ -552,6 +580,13 @@ def disable_in(self, guild: discord.Guild) -> bool:
     def enable_in(self, guild: discord.Guild) -> bool:
         """Enable this command in the given guild.
 
+        This is generally called by the settings managed with
+        the ``[p]command disable global/server`` commands.
+        Any changes made outside of that will not persist after cog
+        reload and may also be affected when either of those commands
+        is called on this command. It is not recommended to rely on
+        this method, if you want a consistent behavior.
+
         Parameters
         ----------
         guild : discord.Guild
@@ -561,7 +596,6 @@ def enable_in(self, guild: discord.Guild) -> bool:
         -------
         bool
             ``True`` if the command wasn't already enabled.
-
         """
         try:
             self._disabled_in.remove(guild.id)


Test patch: