Pycord-Development / pycord

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python
https://docs.pycord.dev
MIT License
2.71k stars 458 forks source link

reloading a cog with a slash command in it fails #1025

Closed Kuchenmampfer closed 2 years ago

Kuchenmampfer commented 2 years ago

Summary

reloading a cog with a slash command in it throws RuntimeError

Reproduction Steps

I created a cog with at least one slash command in it and loaded it in the init function of my bot. In another cog, I have a text command that is supposed to reload any specified cog. It works fine when the reloaded cog only has text commands in it, but when it contains at least one slash command, reloading fails and I get RuntimeError: This event loop is already running.

Minimal Reproducible Code

# Creating a bot with a cog containing a slash command should be trivial,
# so I only provide the code of my reloading command

@commands.command(name='reload')
async def reload(self, ctx, cog_path):
    self.bot.reload_extension(cog_path)

Expected Results

I expect this command to reload the specified cog and update its commands in case I changed them. So basically I expect it to behave as it does when the cog only contains text commands.

Actual Results

Instead, the cog gets unloaded, but loading it again fails with the following traceback:

Traceback (most recent call last):
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/cog.py", line 672, in _load_from_module_spec
    setup(self)
  File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 97, in setup
    bot.add_cog(Textbefehle(bot))
  File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 618, in run_until_complete
    self._check_running()
  File "/usr/lib/python3.9/asyncio/base_events.py", line 578, in _check_running
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/cog.py", line 826, in reload_extension
    self.load_extension(name)
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/cog.py", line 732, in load_extension
    self._load_from_module_spec(spec, name)
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/cog.py", line 677, in _load_from_module_spec
    raise errors.ExtensionFailed(key, e) from e
discord.errors.ExtensionFailed: Extension 'cogs.Fun.textbefehle' raised an error: RuntimeError: This event loop is already running

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/discordbots/Uebot/cogs/Admin/run_stuff.py", line 46, in reload
    self.bot.reload_extension(name)
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/cog.py", line 831, in reload_extension
    lib.setup(self)  # type: ignore
  File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 97, in setup
    bot.add_cog(Textbefehle(bot))
  File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 618, in run_until_complete
    self._check_running()
  File "/usr/lib/python3.9/asyncio/base_events.py", line 578, in _check_running
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/ext/commands/core.py", line 179, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/discordbots/Uebot/cogs/Admin/run_stuff.py", line 48, in reload
    except commands.ExtensionError as e:
AttributeError: module 'discord.ext.commands' has no attribute 'ExtensionError'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/ext/commands/bot.py", line 335, in invoke
    await ctx.command.invoke(ctx)
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/ext/commands/core.py", line 916, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/home/discordbots/Uebot/venv/lib/python3.9/site-packages/discord/ext/commands/core.py", line 188, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: module 'discord.ext.commands' has no attribute 'ExtensionError'

Intents

I use Intents.all()

System Information

- Python v3.9.2-final
- py-cord v2.0.0-beta
    - py-cord pkg_resources: v2.0.0b1
- aiohttp v3.8.1
- system info: Linux 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18)

I also tested it on py-cord v2.0.0b4 and got the same behaviour.

Checklist

Additional Context

No response

plun1331 commented 2 years ago

This exception originated from your cog's __init__ method, and is not a problem with the library:

File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())

The rest of the exception was from asyncio, a result of you trying to run something in an already running event loop, and the library trying it's best to handle it and raise the proper exception, which it did.

Jerry-py commented 2 years ago

This exception originated from your cog's __init__ method, and is not a problem with the library:

File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())

The rest of the exception was from asyncio, a result of you trying to run something in an already running event loop, and the library trying it's best to handle it and raise the proper exception, which it did.

I'm guessing the solution is add a task to loop of the running bot, Something like this:

self.loop = ... # get the event loop of the bot
self.commands_dict = self.loop.create_task(self.load_commands())

I don't think this will work so I rather say this is not preferred

plun1331 commented 2 years ago

This exception originated from your cog's __init__ method, and is not a problem with the library:

File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())

The rest of the exception was from asyncio, a result of you trying to run something in an already running event loop, and the library trying it's best to handle it and raise the proper exception, which it did.

I'm guessing the solution is add a task to loop of the running bot, Something like this:

self.loop = ... # get the event loop of the bot
self.commands_dict = self.loop.create_task(self.load_commands())

I don't think this will work so I rather say this is not preferred

I do not care what your solution is, this is not a problem with the library.

Jerry-py commented 2 years ago

This exception originated from your cog's __init__ method, and is not a problem with the library:

File "/home/discordbots/Uebot/cogs/Fun/textbefehle.py", line 19, in __init__
    self.commands_dict = asyncio.get_event_loop().run_until_complete(self.load_commands())

The rest of the exception was from asyncio, a result of you trying to run something in an already running event loop, and the library trying it's best to handle it and raise the proper exception, which it did.

I'm guessing the solution is add a task to loop of the running bot, Something like this:

self.loop = ... # get the event loop of the bot
self.commands_dict = self.loop.create_task(self.load_commands())

I don't think this will work so I rather say this is not preferred

I do not care what your solution is, this is not a problem with the library.

Alr

Kuchenmampfer commented 2 years ago

Oh you are right. I thought I had it with different cogs too and when I asked on the support discord, they, like me, guessed it was a lib issue. But apparently the other ones work well and I just need to improve my traceback reading skills. Thank you for your help and sorry for falsely opening this issue.