discord.py
discord.py copied to clipboard
the "is_owner" check used on cog commands is conflicting with "on_command"
If you use the decorator @commands.is_owner() (and maybe other decorators aswell), on a command defined in a cog and you print the value of ctx.command.name in on_command as follow
async def on_command(self, ctx):
print(f"Invoked command: {ctx.command.name}")
and invoke the default help command, on_command will pint the name of the command using that check that has been loaded the first.
Minimal test case (tested on rewrite, not async)
- in
main.py
from discord.ext import commands
class Bot(commands.Bot):
async def on_command(self, ctx):
print(f"Invoked command: {ctx.command.name}")
bot = Bot(command_prefix="!")
bot.load_extension("cog")
bot.load_extension("cog2")
bot.run("<token>")
- in
cog.py
from discord.ext import commands
class HelloWorldCog:
def __init__(self, bot):
self.bot = bot
@commands.command()
@commands.is_owner()
async def hello_world(self, ctx):
await ctx.send("Hello world")
def setup(bot):
bot.add_cog(HelloWorldCog(bot))
- in
cog2.py
from discord.ext import commands
class HelloWorldCog2:
def __init__(self, bot):
self.bot = bot
@commands.command()
@commands.is_owner()
async def hello_world2(self, ctx):
await ctx.send("Hello world")
def setup(bot):
bot.add_cog(HelloWorldCog2(bot))
If you run that code and invoke the default help command, on command will print:
Invoked command: hello_world
If you switch these 2 lines from:
bot.load_extension("cog")
bot.load_extension("cog2")
to
bot.load_extension("cog2")
bot.load_extension("cog")
then run the bot again and invoke the default help command, on_command will print:
Invoked command: hello_world2
Can reproduce... sort of. Since this is an old error, had to convert to the new Cog style, just subclassing commands.Cog worked fine.
Version Information
- Python v3.7.3-final
- discord.py v1.2.0-alpha -- 007b7eb
- discord.py pkg_resources: v1.0.0a1718+g42a7c4f
- aiohttp v3.5.4
- websockets v6.0
- system info: Windows 10 10.0.18362
Results
cog.py loaded first, then cog2.py.
Invoked command: hello_world2
cog2.py loaded first, then cog.py.
Invoked command: hello_world
CR.
When loading cog.py first, then cog2.py, invoking the default help command prints "Invoked command: hello_world".
When loading cog2.py first, then cog.py, invoking the default help command prints "Invoked command: hello_world2".
my findings have shown that:
this stashing of the current instance causes issues https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/core.py#L1232-L1233
as the command is never reset at https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/core.py#L1252
then a race condition can occur when the help command invokes can_run on each command