mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-18 23:15:48 +00:00
Ensure explicitly set parents on nested groups are respected
This had a multiple layer bug that needed to be squashed. The first issue was that setting `parent=...` inside a `Group` wouldn't actually add the `Group` into the `parent` children mapping. This meant that it didn't actually end up copying the children when it came time to within e.g. a Cog. The second issue was that even if it was added into the children listing, it wouldn't properly set the attribute. This commit fixes both of these issues. Fix #7818
This commit is contained in:
parent
c671308211
commit
25ad5b675c
@ -971,6 +971,7 @@ class Group:
|
||||
self.name: str = validate_name(name) if name is not MISSING else cls.__discord_app_commands_group_name__
|
||||
self.description: str = description or cls.__discord_app_commands_group_description__
|
||||
self._attr: Optional[str] = None
|
||||
self._owner_cls: Optional[Type[Any]] = None
|
||||
self._guild_ids: Optional[List[int]] = guild_ids
|
||||
|
||||
if not self.description:
|
||||
@ -1004,12 +1005,15 @@ class Group:
|
||||
if copy._attr and not cls.__discord_app_commands_skip_init_binding__:
|
||||
setattr(self, copy._attr, copy)
|
||||
|
||||
if parent is not None and parent.parent is not None:
|
||||
raise ValueError('groups can only be nested at most one level')
|
||||
if parent is not None:
|
||||
if parent.parent is not None:
|
||||
raise ValueError('groups can only be nested at most one level')
|
||||
parent.add_command(self)
|
||||
|
||||
def __set_name__(self, owner: Type[Any], name: str) -> None:
|
||||
self._attr = name
|
||||
self.module = owner.__module__
|
||||
self._owner_cls = owner
|
||||
|
||||
def _copy_with(
|
||||
self,
|
||||
@ -1029,6 +1033,7 @@ class Group:
|
||||
copy.parent = parent
|
||||
copy.module = self.module
|
||||
copy._attr = self._attr
|
||||
copy._owner_cls = self._owner_cls
|
||||
copy._children = {}
|
||||
|
||||
bindings[self] = copy
|
||||
@ -1038,6 +1043,12 @@ class Group:
|
||||
child_copy.parent = copy
|
||||
copy._children[child_copy.name] = child_copy
|
||||
|
||||
if isinstance(child_copy, Group) and child_copy._attr and set_on_binding:
|
||||
if binding.__class__ is child_copy._owner_cls:
|
||||
setattr(binding, child_copy._attr, child_copy)
|
||||
elif child_copy._owner_cls is copy.__class__:
|
||||
setattr(copy, child_copy._attr, child_copy)
|
||||
|
||||
if copy._attr and set_on_binding:
|
||||
setattr(parent or binding, copy._attr, copy)
|
||||
|
||||
|
@ -95,8 +95,7 @@ def test_group_subclass_with_group_subclass():
|
||||
assert my_group.my_group_command.parent is my_group
|
||||
assert my_group.my_group_command.binding is my_group
|
||||
assert my_group.sub_group.my_sub_group_command.parent is my_group.sub_group
|
||||
print(my_group.sub_group.my_sub_group_command.binding)
|
||||
print(MyGroup.sub_group)
|
||||
assert not hasattr(my_group, 'my_sub_group_command')
|
||||
assert my_group.sub_group.my_sub_group_command.binding is my_group.sub_group
|
||||
|
||||
|
||||
@ -127,6 +126,32 @@ def test_cog_with_group_with_commands():
|
||||
assert cog.my_command.binding is cog
|
||||
|
||||
|
||||
def test_cog_with_nested_group_with_commands():
|
||||
class MyCog(commands.Cog):
|
||||
first = app_commands.Group(name='test', description='Test 1')
|
||||
second = app_commands.Group(name='test2', parent=first, description='Test 2')
|
||||
|
||||
@first.command(name='cmd')
|
||||
async def test_cmd(self, interaction: discord.Interaction) -> None:
|
||||
...
|
||||
|
||||
@second.command(name='cmd2')
|
||||
async def test2_cmd(self, interaction: discord.Interaction) -> None:
|
||||
...
|
||||
|
||||
cog = MyCog()
|
||||
|
||||
assert len(MyCog.__cog_app_commands__) == 1
|
||||
assert cog.first.parent is None
|
||||
assert cog.first is not MyCog.first
|
||||
assert cog.second is not MyCog.second
|
||||
assert cog.second.parent is cog.first
|
||||
assert cog.test_cmd.parent is cog.first
|
||||
assert cog.test2_cmd.parent is cog.second
|
||||
assert cog.test_cmd.binding is cog
|
||||
assert cog.test2_cmd.binding is cog
|
||||
|
||||
|
||||
def test_cog_with_group_subclass_with_commands():
|
||||
class MyGroup(app_commands.Group, name='mygroup'):
|
||||
@app_commands.command()
|
||||
@ -175,6 +200,8 @@ def test_cog_with_group_subclass_with_group():
|
||||
assert cog.my_group.my_command is not MyGroup.my_command
|
||||
assert cog.my_cog_command is not MyCog.my_cog_command
|
||||
assert not hasattr(cog.my_group, 'my_cog_command')
|
||||
assert not hasattr(cog, 'sub_group')
|
||||
assert not hasattr(cog, 'my_command')
|
||||
assert cog.my_group.parent is None
|
||||
assert cog.my_group.sub_group.parent is cog.my_group
|
||||
assert cog.my_group.my_command.parent is cog.my_group.sub_group
|
||||
@ -215,6 +242,10 @@ def test_cog_with_group_subclass_with_group_subclass():
|
||||
assert cog.my_group.sub_group is not MyGroup.sub_group
|
||||
assert cog.my_cog_command is not MyCog.my_cog_command
|
||||
assert not hasattr(cog.my_group, 'my_cog_command')
|
||||
assert not hasattr(cog, 'sub_group')
|
||||
assert not hasattr(cog, 'my_group_command')
|
||||
assert not hasattr(cog, 'my_sub_group_command')
|
||||
assert not hasattr(cog.my_group, 'my_sub_group_command')
|
||||
assert cog.my_group.sub_group.my_sub_group_command is not MyGroup.sub_group.my_sub_group_command
|
||||
assert cog.my_group.sub_group.my_sub_group_command is not MySubGroup.my_sub_group_command
|
||||
assert cog.my_group.sub_group.parent is cog.my_group
|
||||
|
Loading…
x
Reference in New Issue
Block a user