Fix nested UI item parent state

This commit is contained in:
harumaki4649
2026-07-10 19:37:41 -04:00
committed by GitHub
parent f6dbb848d0
commit d2996be144
5 changed files with 113 additions and 0 deletions
+94
View File
@@ -28,6 +28,12 @@ import discord
import pytest
class DynamicButton(discord.ui.DynamicItem[discord.ui.Button], template=r'dynamic:(?P<number>[0-9]+)'):
@classmethod
async def from_custom_id(cls, interaction, item, match):
return cls(discord.ui.Button(label='Dynamic', custom_id=match.group(0)))
def test_add_item_with_full_row():
view = discord.ui.View()
@@ -86,3 +92,91 @@ def test_layout_view_add_item_with_too_many_children():
assert view.total_children_count == max_item_limit - 1
assert row.view is None
assert all(item.view is None for item in row.children)
def test_section_remove_item_clears_view_and_parent():
view = discord.ui.LayoutView()
section = discord.ui.Section('test', accessory=discord.ui.Button(label='Test'))
view.add_item(section)
item = section.children[0]
section.remove_item(item)
assert item.view is None
assert item.parent is None
def test_action_row_remove_item_clears_view_and_parent():
view = discord.ui.LayoutView()
row = discord.ui.ActionRow()
item = discord.ui.Button(label='Test')
row.add_item(item)
view.add_item(row)
row.remove_item(item)
assert item.view is None
assert item.parent is None
def test_container_remove_item_clears_view_and_parent():
view = discord.ui.LayoutView()
container = discord.ui.Container()
item = discord.ui.TextDisplay('test')
container.add_item(item)
view.add_item(container)
container.remove_item(item)
assert item.view is None
assert item.parent is None
@pytest.mark.asyncio
async def test_action_row_dynamic_item_swap_preserves_parent_checks():
calls = []
class Row(discord.ui.ActionRow):
async def interaction_check(self, interaction):
calls.append('row')
return True
base = discord.ui.Button(label='Dynamic', custom_id='dynamic:1')
row = Row(base)
view = discord.ui.LayoutView()
view.add_item(row)
item = DynamicButton(discord.ui.Button(label='Dynamic', custom_id='dynamic:1'))
row._swap_item(base, item, 'dynamic:1')
await item._run_checks(None)
assert item.view is view
assert item.parent is row
assert base.view is None
assert base.parent is None
assert calls == ['row']
@pytest.mark.asyncio
async def test_container_dynamic_item_swap_preserves_parent_checks():
calls = []
class Container(discord.ui.Container):
async def interaction_check(self, interaction):
calls.append('container')
return True
base = discord.ui.ActionRow(discord.ui.Button(label='Dynamic', custom_id='dynamic:1'))
container = Container(base)
view = discord.ui.LayoutView()
view.add_item(container)
item = DynamicButton(discord.ui.Button(label='Dynamic', custom_id='dynamic:1'))
container._swap_item(base, item, 'dynamic:1')
await item._run_checks(None)
assert item.view is view
assert item.parent is container
assert base.view is None
assert base.parent is None
assert calls == ['container']