Skip to content

Commit

Permalink
[commands] Fix hybrid command wrapped instances being out of sync
Browse files Browse the repository at this point in the history
  • Loading branch information
Rapptz committed Sep 30, 2023
1 parent f617d01 commit 5c5ccc4
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions discord/ext/commands/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Self:
if isinstance(app_command, app_commands.Group):
for child in app_command.walk_commands():
app_command_refs[child.qualified_name] = child
if hasattr(child, '__commands_is_hybrid_app_command__') and child.qualified_name in lookup:
child.wrapped = lookup[child.qualified_name] # type: ignore

if self.__cog_app_commands_group__:
children.append(app_command) # type: ignore # Somehow it thinks it can be None here
Expand Down
2 changes: 2 additions & 0 deletions discord/ext/commands/hybrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ def replace_parameters(


class HybridAppCommand(discord.app_commands.Command[CogT, P, T]):
__commands_is_hybrid_app_command__: ClassVar[bool] = True

def __init__(
self,
wrapped: Union[HybridCommand[CogT, ..., T], HybridGroup[CogT, ..., T]],
Expand Down
28 changes: 28 additions & 0 deletions tests/test_app_commands_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,31 @@ async def third(self, interaction: discord.Interaction) -> None:
assert isinstance(third, app_commands.Command)
assert third.parent is second
assert third.binding is cog


def test_cog_hybrid_group_wrapped_instance():
class MyCog(commands.Cog):
@commands.hybrid_group(fallback='fallback')
async def first(self, ctx: commands.Context) -> None:
pass

@first.command()
async def second(self, ctx: commands.Context) -> None:
pass

@first.group()
async def nested(self, ctx: commands.Context) -> None:
pass

@nested.app_command.command()
async def child(self, interaction: discord.Interaction) -> None:
pass

cog = MyCog()

fallback = cog.first.app_command.get_command('fallback')
assert fallback is not None
assert getattr(fallback, 'wrapped', None) is cog.first
assert fallback.parent is cog.first.app_command
assert cog.second.app_command is not None
assert cog.second.app_command.wrapped is cog.second

0 comments on commit 5c5ccc4

Please sign in to comment.