mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-08 04:38:42 +00:00
[commands] Fix nested hybrid groups inserting manual app commands
This commit is contained in:
parent
c7f6e95f1c
commit
69e9bc9454
@ -305,6 +305,7 @@ class Cog(metaclass=CogMeta):
|
|||||||
|
|
||||||
# Register the application commands
|
# Register the application commands
|
||||||
children: List[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = []
|
children: List[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = []
|
||||||
|
app_command_refs: Dict[str, Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = {}
|
||||||
|
|
||||||
if cls.__cog_is_app_commands_group__:
|
if cls.__cog_is_app_commands_group__:
|
||||||
group = app_commands.Group(
|
group = app_commands.Group(
|
||||||
@ -331,6 +332,16 @@ class Cog(metaclass=CogMeta):
|
|||||||
# Get the latest parent reference
|
# Get the latest parent reference
|
||||||
parent = lookup[parent.qualified_name] # type: ignore
|
parent = lookup[parent.qualified_name] # type: ignore
|
||||||
|
|
||||||
|
# Hybrid commands already deal with updating the reference
|
||||||
|
# Due to the copy below, so we need to handle them specially
|
||||||
|
if hasattr(parent, '__commands_is_hybrid__') and hasattr(command, '__commands_is_hybrid__'):
|
||||||
|
app_command: Optional[Union[app_commands.Group, app_commands.Command[Self, ..., Any]]] = getattr(
|
||||||
|
command, 'app_command', None
|
||||||
|
)
|
||||||
|
updated = app_command_refs.get(command.qualified_name)
|
||||||
|
if app_command and updated:
|
||||||
|
command.app_command = updated # type: ignore # Safe attribute access
|
||||||
|
|
||||||
# Update our parent's reference to our self
|
# Update our parent's reference to our self
|
||||||
parent.remove_command(command.name) # type: ignore
|
parent.remove_command(command.name) # type: ignore
|
||||||
parent.add_command(command) # type: ignore
|
parent.add_command(command) # type: ignore
|
||||||
@ -345,6 +356,11 @@ class Cog(metaclass=CogMeta):
|
|||||||
# The type checker does not see the app_command attribute even though it exists
|
# The type checker does not see the app_command attribute even though it exists
|
||||||
command.app_command = app_command # type: ignore
|
command.app_command = app_command # type: ignore
|
||||||
|
|
||||||
|
# Update all the references to point to the new copy
|
||||||
|
if isinstance(app_command, app_commands.Group):
|
||||||
|
for child in app_command.walk_commands():
|
||||||
|
app_command_refs[child.qualified_name] = child
|
||||||
|
|
||||||
if self.__cog_app_commands_group__:
|
if self.__cog_app_commands_group__:
|
||||||
children.append(app_command) # type: ignore # Somehow it thinks it can be None here
|
children.append(app_command) # type: ignore # Somehow it thinks it can be None here
|
||||||
|
|
||||||
|
@ -397,3 +397,85 @@ def test_cog_group_with_custom_state_issue9383():
|
|||||||
assert cog.inner.my_command.parent is cog.inner
|
assert cog.inner.my_command.parent is cog.inner
|
||||||
assert cog.my_inner_command.parent is cog.inner
|
assert cog.my_inner_command.parent is cog.inner
|
||||||
assert cog.my_inner_command.binding is cog
|
assert cog.my_inner_command.binding is cog
|
||||||
|
|
||||||
|
|
||||||
|
def test_cog_hybrid_group_manual_command():
|
||||||
|
class MyCog(commands.Cog):
|
||||||
|
@commands.hybrid_group()
|
||||||
|
async def first(self, ctx: commands.Context) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@first.command(name='both')
|
||||||
|
async def second_both(self, ctx: commands.Context) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
@first.app_command.command(name='second')
|
||||||
|
async def second_app(self, interaction: discord.Interaction) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
client = discord.Client(intents=discord.Intents.default())
|
||||||
|
tree = app_commands.CommandTree(client)
|
||||||
|
|
||||||
|
cog = MyCog()
|
||||||
|
tree.add_command(cog.first.app_command)
|
||||||
|
|
||||||
|
assert cog.first is not MyCog.first
|
||||||
|
assert cog.second_both is not MyCog.second_both
|
||||||
|
assert cog.second_app is not MyCog.second_app
|
||||||
|
assert cog.first.parent is None
|
||||||
|
assert cog.second_both.parent is cog.first
|
||||||
|
assert cog.second_app.parent is cog.first.app_command
|
||||||
|
assert cog.second_app.binding is cog
|
||||||
|
assert tree.get_command('first') is cog.first.app_command
|
||||||
|
|
||||||
|
first = tree.get_command('first')
|
||||||
|
assert isinstance(first, app_commands.Group)
|
||||||
|
both = first.get_command('both')
|
||||||
|
assert isinstance(both, app_commands.Command)
|
||||||
|
assert both.parent is first
|
||||||
|
assert both.binding is cog
|
||||||
|
|
||||||
|
second = first.get_command('second')
|
||||||
|
assert isinstance(second, app_commands.Command)
|
||||||
|
assert second.parent is first
|
||||||
|
assert second.binding is cog
|
||||||
|
|
||||||
|
|
||||||
|
def test_cog_hybrid_group_manual_nested_command():
|
||||||
|
class MyCog(commands.Cog):
|
||||||
|
@commands.hybrid_group()
|
||||||
|
async def first(self, ctx: commands.Context) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@first.group()
|
||||||
|
async def second(self, ctx: commands.Context) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@second.app_command.command()
|
||||||
|
async def third(self, interaction: discord.Interaction) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
client = discord.Client(intents=discord.Intents.default())
|
||||||
|
tree = app_commands.CommandTree(client)
|
||||||
|
|
||||||
|
cog = MyCog()
|
||||||
|
tree.add_command(cog.first.app_command)
|
||||||
|
|
||||||
|
assert cog.first is not MyCog.first
|
||||||
|
assert cog.second is not MyCog.second
|
||||||
|
assert cog.third is not MyCog.third
|
||||||
|
assert cog.first.parent is None
|
||||||
|
assert cog.second.parent is cog.first
|
||||||
|
assert cog.third.parent is cog.second.app_command
|
||||||
|
assert cog.third.binding is cog
|
||||||
|
|
||||||
|
first = tree.get_command('first')
|
||||||
|
assert isinstance(first, app_commands.Group)
|
||||||
|
|
||||||
|
second = first.get_command('second')
|
||||||
|
assert isinstance(second, app_commands.Group)
|
||||||
|
|
||||||
|
third = second.get_command('third')
|
||||||
|
assert isinstance(third, app_commands.Command)
|
||||||
|
assert third.parent is second
|
||||||
|
assert third.binding is cog
|
||||||
|
Loading…
x
Reference in New Issue
Block a user