discord.py icon indicating copy to clipboard operation
discord.py copied to clipboard

the "is_owner" check used on cog commands is conflicting with "on_command"

Open tesence opened this issue 6 years ago • 3 comments

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

tesence avatar Dec 18 '18 18:12 tesence

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

NCPlayz avatar May 19 '19 16:05 NCPlayz

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".

scrazzz avatar Feb 18 '21 05:02 scrazzz

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

ooliver1 avatar Jun 16 '22 19:06 ooliver1