discord-py-ui / discord-ui

A discord.py extension for sending, receiving and handling ui interactions in discord
https://discord-ui.rtfd.io/
MIT License
36 stars 10 forks source link

Lacking support for split files #113

Closed johann-lau closed 2 years ago

johann-lau commented 2 years ago

Motivation

The official discord.py library supports loading extension commands from other files, so I think it is a good idea for discord_ui to have it as well. Otherwise, large bots can easily get to tens of thousands of lines in a single file.

Reference code

To put this conveniently, here is the bot.load_extension() method definition:

# In the Bot class
def load_extension(
        self,
        name: str,
        *,
        package: Optional[str] = None,
        extras: Optional[Dict[str, Any]] = None
    ) -> None:
            name = self._resolve_name(name, package)
            if name in self.__extensions:
                raise errors.ExtensionAlreadyLoaded(name)

            spec = importlib.util.find_spec(name)
            if spec is None:
                raise errors.ExtensionNotFound(name)

            self._load_from_module_spec(spec, name, extras=extras)
kvsxxx commented 2 years ago

I don't know if I'm missunderstanding something, but why can't you just use discord.py's load_extension? Both .add_cog and .remove_cog get overwritten by default in order to get application commands on cogs working.

If you want to split files, just use the cog module of discord_ui together with discord.py's cog system

other_file.py

from discord_ui import cogs
from discord.ext import commands
class MyCog(commands.Cog):
    @cogs.slash_command(...)
    async def my_command(self, ctx):
        ...
def setup(bot):
    bot.add_cog(MyCog())

main.py

...

bot.load_extension('other_file')
johann-lau commented 2 years ago

How about individual commands? I often use @ui_.slash.command(), and I am wondering if there is a similar way of doing this. Thanks!

johann-lau commented 2 years ago

OK, I've found a way to do this. In case someone is looking here, I'll post the solution for non-cogs: bot.py

ui_ = ui.UI(bot)
bot_.load_extension("other")

other.py

from bot import ui_

# context commands if any (as usual)

@ui_.slash.command(name="tester", description="Some tester.")
async def tester(ctx):
    ...

def setup:
    ...
    # Do not add any line referring to the tester command

Thanks!