Open
Description
Summary
The @app_commands.dm_only()
decorator and its kin do not actually override CommandTree.{allowed_contexts,allowed_installs}
Reproduction Steps
- Set all three flags on
CommandTree.allowed_contexts
- Add a
@dm_only()
command - The command's final allowed contexts are those of the
CommandTree
, not the command, contrary to the documentation of the former ("Note that you can override this on a per command basis.")
Minimal Reproducible Code
from discord import Intents
from discord.ext.commands import Bot
from discord.app_commands import AppCommandContext, dm_only
bot = Bot(
command_prefix='/',
intents=Intents.all(),
allowed_contexts=AppCommandContext(guild=True, dm_channel=True, private_channel=True)
)
@bot.tree.command()
@dm_only()
async def test(ctx):
pass
contexts = test.to_dict(bot.tree)['contexts']
print(contexts)
assert contexts == [1]
Expected Results
The @dm_only()
command /test
should only have context 1 (dm_channel
):
[1]
Actual Results
The command has contexts 0 (guild
), 1 (dm_channel
), and 2 (private_channel
):
[0, 1, 2]
Traceback (most recent call last):
File "<string>", line 18, in <module>
assert contexts == [1]
^^^^^^^^^^^^^^^
AssertionError
Intents
discord.Intents.all()
System Information
- Python v3.13.0-final
- discord.py v2.5.2-final
- aiohttp v3.11.18
- system info: Windows 11 10.0.26100
Checklist
- I have searched the open issues for duplicates.
- I have shown the entire traceback, if possible.
- I have removed my token from display, if visible.
Additional Context
Since they are implemented with similarly flawed logic, similar issues may also apply to the following classes, decorators, and/or attributes:
@app_commands.guild_only()
@app_commands.private_channel_only()
@app_commands.user_install()
@app_commands.guild_install()
app_commands.AppInstallationType
CommandTree.allowed_installs