Repository: Pycord-Development/pycord

Issue:
Autocomplete does not work for slash commands in groups
### Summary

Autocomplete methods are not executed for slash commands that are under a SlashCommandGroup.

### Reproduction Steps

I created a slash command group, and added commands with autocomplete to the group. The commands would be registered successfully, but autocomplete would not work.

### Minimal Reproducible Code

```python
import discord
import environment

bot = discord.Bot()

class CustomCog(discord.Cog):

	group = discord.SlashCommandGroup(name="test")

	async def autocomplete(ctx):
		return ["hello world"]

	@group.command()
	async def random_subcommand(self, ctx, random: discord.Option(str, name="random", autocomplete=autocomplete)):
		await ctx.respond(random)

bot.add_cog(CustomCog(bot))
bot.run(environment.DISCORD_TOKEN)
```


### Expected Results

When running the bot and typing the `/test random_subcommand` command, the text `hello world` should be suggested.

### Actual Results

The `autocomplete` method in my code did not run, and no results were suggested. Discord showed an error after a couple of seconds: "Loading options failed".

### Intents

Intents.default()

### System Information

- Python v3.9.6-final
- py-cord v2.1.3-final
- aiohttp v3.7.4.post0
- system info: Windows 10 10.0.19044

### Checklist

- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.

### Additional Context

Using a debugger I narrowed it down to [this line](https://github.com/Pycord-Development/pycord/blob/master/discord/bot.py#L759), where the `command` variable is a `SlashCommandGroup`, not a `SlashCommand`. I would have submitted a PR but I saw that line was introduced in 2.1.2 (e321fa3e2a07eb869a03de3b020f09c6d8ca431c) and assume that simply removing it (which does fix the issue) will undo whatever fixes were made with that change.

# Temporary Fix

My bots weren't experiencing any of the bugs that were fixed in v2.1.2+, so reverting to **v2.1.1** works as a temporary fix for me. But your mileage may vary.


Discussion:
Can confirm, fwiw. It does seem to be corrected by updating the `isinstance` line to `isinstance(command, (SlashCommand, SlashCommandGroup))` but perhaps that's a little too hacky; why would it be getting the group instead of the individual command?

I imagine https://github.com/Pycord-Development/pycord/blob/master/discord/bot.py#L728 might check whether the interaction `options` is type 1 for subcommand.
> why would it be getting the group instead of the individual command?

It seems to be similar to the Composite design pattern, where you can call `invoke_autocomplete_callback` on a `SlashCommandGroup` and it will forward to the correct `SlashCommand`. That removes the need to have explicit logic to check which type of command it is on line 728.

Resolving patch:
diff --git a/discord/bot.py b/discord/bot.py
--- a/discord/bot.py
+++ b/discord/bot.py
@@ -756,20 +756,19 @@ async def process_application_commands(self, interaction: Interaction, auto_sync
         await self.invoke_application_command(ctx)
 
     async def on_application_command_auto_complete(self, interaction: Interaction, command: ApplicationCommand) -> None:
-        if isinstance(command, SlashCommand):
-            async def callback() -> None:
-                ctx = await self.get_autocomplete_context(interaction)
-                ctx.command = command
-                return await command.invoke_autocomplete_callback(ctx)
+        async def callback() -> None:
+            ctx = await self.get_autocomplete_context(interaction)
+            ctx.command = command
+            return await command.invoke_autocomplete_callback(ctx)
 
-            autocomplete_task = self._bot.loop.create_task(callback())
-            try:
-                await self._bot.wait_for("application_command_auto_complete", check=lambda i, c: c == command, timeout=3)
-            except asyncio.TimeoutError:
-                return
-            else:
-                if not autocomplete_task.done():
-                    autocomplete_task.cancel()
+        autocomplete_task = self._bot.loop.create_task(callback())
+        try:
+            await self._bot.wait_for("application_command_auto_complete", check=lambda i, c: c == command, timeout=3)
+        except asyncio.TimeoutError:
+            return
+        else:
+            if not autocomplete_task.done():
+                autocomplete_task.cancel()
 
     def slash_command(self, **kwargs):
         """A shortcut decorator that invokes :func:`command` and adds it to


Test patch: