Skip to content

[V2 components] Weird nesting behavior #10335

@laggron42

Description

@laggron42

Summary

The library offers multiple ways of writing v2 components using LayoutView, but they have a weird behavior when nesting (LayoutView > Container > ActionRow > Button for example), a lot of the attributes and features can be missing.

Reproduction Steps

I have noticed two major issues:

  • The parent and view attributes of a nested item are usually set to None in runtime
  • Special methods like interaction_check do not apply to nested items (this may be a design choice, but it deserves a warning in the docs)

Minimal Reproducible Code

from discord.ui import ActionRow, Container, LayoutView, button

class MyRow(ActionRow):
  async def interaction_check(self, interaction):
    print("Hi from ActionRow!")
    return True

  @button(label="hi")
  async def mybutton(self, interaction, button):
    print(f"{self.view=}")  # None
    print(f"{self.parent=}")  # None
    print(f"{button.view=}")  # None
    print(f"{button.parent=}")  # MyRow
    print(f"{button.parent.view=}")  # None
    print(f"{button.parent.parent=}")  # None

class MyContainer(Container):
  async def interaction_check(self, interaction):
    print("Hi from Container!")  # Never reached
    return True

  row = MyRow()

class MyView(LayoutView):
  async def interaction_check(self, interaction):
    print("Hi from LayoutView!")
    return True

  container = MyContainer()

view = MyView()
await ctx.send(view=view)

Expected Results

Hi from ActionRow!
Hi from Container!
Hi from LayoutView!
self.view=<MyView timeout=180.0 children=1>
self.parent=<MyRow children=1>
button.view=<MyView timeout=180.0 children=1>
button.parent=<MyRow children=1>
button.parent.view=<MyView timeout=180.0 children=1>
button.parent.parent=<MyContainer children=1>

Actual Results

In console:

Hi from ActionRow!
Hi from LayoutView!
self.view=None
self.parent=None
button.view=None
button.parent=<MyRow children=1>
button.parent.view=None
button.parent.parent=None

Intents

guilds, guild_messages, emojis_and_stickers

System Information

  • Python v3.13.2-final
  • discord.py v2.6.4-final
  • aiohttp v3.12.14
  • system info: Linux 6.11.0-25-generic Print to stderr in on_error #25~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:20:50 UTC 2

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

I have already discussed the issue of unset view and parent attributes in the Discord server previously, there are dirty ways around it but it's not critical.

However, I really wasn't expecting MyContainer's interaction_check to be skipped in this context, and made me deploy a pretty large vulnerability on my bot. I blame myself for that, I should have tested more thoroughly, but better avoid the confusion for others

Metadata

Metadata

Assignees

No one assigned

    Labels

    unconfirmed bugA bug report that needs triaging

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions