I'm writing a Discord bot using Pycord, and I'm trying to dynamically load cogs with an async def setup(bot)
method.
Here's the relevant part of my main.py
:
async def main():
for filename in os.listdir("cogs"):
if filename.endswith(".py"):
cog_path = f"cogs.{filename[:-3]}"
print(f"π₯ Importing {cog_path}")
try:
module = importlib.import_module(cog_path)
setup = getattr(module, "setup", None)
print(f"π Checking setup in {cog_path}: {setup}")
print(f"π Type of setup: {type(setup)}")
if setup:
if inspect.iscoroutinefunction(setup):
await setup(bot)
else:
print(f"β οΈ Skipped setup for {cog_path} because it's not async.")
except Exception as e:
print(f"β Failed to load {cog_path}: {e.__class__.__name__} - {e}")
await bot.start(TOKEN)
And hereβs the trivia.py
cog:
async def setup(bot):
await bot.add_cog(Trivia(bot))
I get the following error at runtime:
π₯ Importing cogs.trivia
π Checking setup in cogs.trivia: <function setup at 0x703c16e92020>
π Type of setup: <class 'function'>
β Failed to load cogs.trivia: TypeError - object NoneType can't be used in 'await' expression
Even though the setup function is async and the cog is implemented correctly. There are more cogs than this all returning the same exact error, some of them work and some do not.
I'm using Pycord Version: 2.6.1 in a WSL environment, not discord.py
, and I confirmed that setup
is a coroutine function via inspect.iscoroutinefunction(setup)
.
Questions
Why would I be getting NoneType in await setup(bot) even when it's async?
Is there something different about Pycord's cog loading I should be aware of?
Based on pycord
doc add_cog is not async
function so you can't use it with await
because it is normal function which returns None
and you have
result = bot.add_cog(Trivia(bot)) # None
await result
which finally does
await None
You could check inspect.iscoroutinefunction(bot.add_cog)
You have to write it as normal function
def setup(bot):
bot.add_cog(Trivia(bot))
and run it as normal function
if setup:
setup(bot)
In discord.py
add_cog is async
function.
And this can make problem when you see some code or tutorial
but it doesn't show if it is for pycord
or discord.py
(both use import discord
).
Minimal code for test:
import discord
import inspect
print('title:', discord.__title__) # to make sure if it is `pycord`
# or other module for discord
bot = discord.Bot()
print('bot.add_cog: async:', inspect.iscoroutinefunction(bot.add_cog))
Result:
title: pycord
bot.add_cog: async: False