Repository: Pycord-Development/pycord

Issue:
'AutoShardedBot' object has no attribute '_bridge_commands'.
### Summary

@bot.bridge_group fails to create a bridge command group.

### Reproduction Steps

1. Make a bridge group, not in a cog, but in the main bot file.
2. put in your token
3. start the bot
4. it should fail

### Minimal Reproducible Code

```python
import discord
from discord.ext import commands
from discord.ext import bridge

intents = discord.Intents.all()

bot = bridge.AutoShardedBot(command_prefix=commands.when_mentioned_or("!"), intents=intents, auto_sync_commands=True)

@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")

@bot.bridge_group(invoke_without_command=True, help="Showing categories for commands.")
@bridge.map_to("help", "Shows the basic help menu.")
async def help(ctx):
    e = discord.Embed(
        description="test",
    )
    await ctx.respond(embed=e)

bot.run("token")
```


### Expected Results

The commands and the bridge group would work like it did in 2.2.2

### Actual Results

It fails with an error., and the bot wont even start.

![image](https://user-images.githubusercontent.com/60816479/204002281-a07438a6-e0ae-4153-baa7-5946141ceec6.png)

### Intents

all

### System Information

- Python v3.11.0-final
- py-cord v2.3.None-final (tried on the release version too)
- aiohttp v3.8.3
- system info: Windows 10 10.0.22000

### 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

Worked good in pycord 2.2.2 and on py 3.10.7
Updated to 3.11 and 2.3.0 uninstalled the any other python version other than 3.11 and still not works.
I also checked that python is added to the path, and it is.
Honestly i dont know what is happening here.


Discussion:
@Middledot mind checking this out and letting me know what you find?

Resolving patch:
diff --git a/discord/cog.py b/discord/cog.py
--- a/discord/cog.py
+++ b/discord/cog.py
@@ -199,6 +199,7 @@ def __new__(cls: type[CogMeta], *args: Any, **kwargs: Any) -> CogMeta:
 
                     commands[f"ext_{elem}"] = value.ext_variant
                     commands[f"app_{elem}"] = value.slash_variant
+                    commands[elem] = value
                     for cmd in getattr(value, "subcommands", []):
                         commands[
                             f"ext_{cmd.ext_variant.qualified_name}"
@@ -229,9 +230,13 @@ def __new__(cls: type[CogMeta], *args: Any, **kwargs: Any) -> CogMeta:
 
         # Either update the command with the cog provided defaults or copy it.
         # r.e type ignore, type-checker complains about overriding a ClassVar
-        new_cls.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in new_cls.__cog_commands__)  # type: ignore
+        new_cls.__cog_commands__ = tuple(c._update_copy(cmd_attrs) if not hasattr(c, "add_to") else c for c in new_cls.__cog_commands__)  # type: ignore
 
-        name_filter = lambda c: "app" if isinstance(c, ApplicationCommand) else "ext"
+        name_filter = (
+            lambda c: "app"
+            if isinstance(c, ApplicationCommand)
+            else ("bridge" if not hasattr(c, "add_to") else "ext")
+        )
 
         lookup = {
             f"{name_filter(cmd)}_{cmd.qualified_name}": cmd
@@ -247,7 +252,9 @@ def __new__(cls: type[CogMeta], *args: Any, **kwargs: Any) -> CogMeta:
             ):
                 command.guild_ids = new_cls.__cog_guild_ids__
 
-            if not isinstance(command, SlashCommandGroup):
+            if not isinstance(command, SlashCommandGroup) and not hasattr(
+                command, "add_to"
+            ):
                 # ignore bridge commands
                 cmd = getattr(new_cls, command.callback.__name__, None)
                 if hasattr(cmd, "add_to"):
@@ -534,6 +541,10 @@ def _inject(self: CogT, bot) -> CogT:
         # we've added so far for some form of atomic loading.
 
         for index, command in enumerate(self.__cog_commands__):
+            if hasattr(command, "add_to"):
+                bot._bridge_commands.append(command)
+                continue
+
             command._set_cog(self)
 
             if isinstance(command, ApplicationCommand):
diff --git a/discord/ext/bridge/bot.py b/discord/ext/bridge/bot.py
--- a/discord/ext/bridge/bot.py
+++ b/discord/ext/bridge/bot.py
@@ -44,7 +44,7 @@ class BotBase(ABC):
     def bridge_commands(self) -> list[BridgeCommand | BridgeCommandGroup]:
         """Returns all of the bot's bridge commands."""
 
-        if cmds := getattr(self, "_bridge_commands", []):
+        if not (cmds := getattr(self, "_bridge_commands", None)):
             self._bridge_commands = cmds = []
 
         return cmds
@@ -73,6 +73,10 @@ def add_bridge_command(self, command: BridgeCommand):
         """
         # Ignore the type hinting error here. All subclasses of BotBase pass the type checks.
         command.add_to(self)  # type: ignore
+
+        if getattr(self, "_bridge_commands", None) is None:
+            self._bridge_commands = []
+
         self._bridge_commands.append(command)
 
     def bridge_command(self, **kwargs):
diff --git a/discord/ext/bridge/core.py b/discord/ext/bridge/core.py
--- a/discord/ext/bridge/core.py
+++ b/discord/ext/bridge/core.py
@@ -191,6 +191,10 @@ def description_localizations(self) -> dict[str, str]:
     def description_localizations(self, value):
         self.slash_variant.description_localizations = value
 
+    @property
+    def qualified_name(self) -> str:
+        return self.slash_variant.qualified_name
+
     def add_to(self, bot: ExtBot) -> None:
         """Adds the command to a bot. This method is inherited by :class:`.BridgeCommandGroup`.
 


Test patch: