Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ These changes are available on the `master` branch, but have not yet been releas

### Fixed

- Fixed the `view` attribute on many view items being incorrect.
([#2981](https://github.com/Pycord-Development/pycord/pull/2981))

### Deprecated

- Deprecated manually setting the `view` attribute on view items.
([#2981](https://github.com/Pycord-Development/pycord/pull/2981))

### Removed

## [2.7.0rc2] - 2025-10-22
Expand Down
9 changes: 1 addition & 8 deletions discord/ui/action_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ def add_item(self, item: ViewItem) -> Self:
if self.width + item.width > 5:
raise ValueError(f"Not enough space left on this ActionRow")

item._view = self.view
item.parent = self

self.children.append(item)
Expand All @@ -162,6 +161,7 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
self.children.remove(item)
except ValueError:
pass
item.parent = None
return self

def get_item(self, id: str | int) -> ViewItem | None:
Expand Down Expand Up @@ -351,13 +351,6 @@ def add_select(

return self.add_item(select)

@ViewItem.view.setter
def view(self, value):
self._view = value
for item in self.children:
item.parent = self
item._view = value

def is_dispatchable(self) -> bool:
return any(item.is_dispatchable() for item in self.children)

Expand Down
15 changes: 2 additions & 13 deletions discord/ui/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,6 @@ def add_item(self, item: ViewItem) -> Self:
f"{item.__class__!r} cannot be added directly. Use ActionRow instead."
)

item._view = self.view
if hasattr(item, "items"):
item.view = self
item.parent = self

self.items.append(item)
Expand All @@ -170,12 +167,13 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
if isinstance(item, (str, int)):
item = self.get_item(item)
try:
if isinstance(item, Container):
if item.parent is self:
self.items.remove(item)
else:
item.parent.remove_item(item)
except ValueError:
pass
item.parent = None
return self

def get_item(self, id: str | int) -> ViewItem | None:
Expand Down Expand Up @@ -361,15 +359,6 @@ def colour(self, value: int | Colour | None): # type: ignore

color = colour

@ViewItem.view.setter
def view(self, value):
self._view = value
for item in self.items:
item.parent = self
item._view = value
if hasattr(item, "items") or hasattr(item, "children"):
item.view = value

def is_dispatchable(self) -> bool:
return any(item.is_dispatchable() for item in self.items)

Expand Down
17 changes: 14 additions & 3 deletions discord/ui/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"ModalItem",
)

from ..utils import warn_deprecated

if TYPE_CHECKING:
from ..components import Component
from ..enums import ComponentType
Expand Down Expand Up @@ -152,7 +154,7 @@ def __init__(self):
self._view: V | None = None
self._row: int | None = None
self._rendered_row: int | None = None
self.parent: ViewItem | BaseView | None = self.view
self.parent: ViewItem | BaseView | None = None

@property
def row(self) -> int | None:
Expand Down Expand Up @@ -208,10 +210,19 @@ def view(self) -> V | None:
Optional[:class:`BaseView`]
The parent view of this item, or ``None`` if the item is not attached to any view.
"""
return self._view
if self._view:
return self._view
if self.parent:
from .view import BaseView

if isinstance(self.parent, BaseView):
return self.parent
return self.parent.view
return None

@view.setter
def view(self, value) -> None:
def view(self, value: V | None) -> None:
warn_deprecated("Manually setting .view", since="2.7", removed="2.8")
self._view = value

async def callback(self, interaction: Interaction):
Expand Down
11 changes: 2 additions & 9 deletions discord/ui/section.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
self.items.remove(item)
except ValueError:
pass
item.parent = None
return self

def get_item(self, id: int | str) -> ViewItem | None:
Expand Down Expand Up @@ -226,8 +227,7 @@ def set_accessory(self, item: ViewItem) -> Self:

if not isinstance(item, ViewItem):
raise TypeError(f"expected ViewItem not {item.__class__!r}")
if self.view:
item._view = self.view

item.parent = self

self.accessory = item
Expand Down Expand Up @@ -260,13 +260,6 @@ def set_thumbnail(

return self.set_accessory(thumbnail)

@ViewItem.view.setter
def view(self, value):
self._view = value
for item in self.walk_items():
item._view = value
item.parent = self

def copy_text(self) -> str:
"""Returns the text of all :class:`~discord.ui.TextDisplay` items in this section.
Equivalent to the `Copy Text` option on Discord clients.
Expand Down
13 changes: 6 additions & 7 deletions discord/ui/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,10 @@ def add_item(self, item: ViewItem[V]) -> Self:
raise TypeError(f"expected ViewItem not {item.__class__!r}")

item.parent = self
item._view = self
self.children.append(item)
return self

def remove_item(self, item: ViewItem[V] | int | str) -> None:
def remove_item(self, item: ViewItem[V] | int | str) -> Self:
"""Removes an item from the view. If an :class:`int` or :class:`str` is passed,
the item will be removed by ViewItem ``id`` or ``custom_id`` respectively.

Expand All @@ -252,16 +251,19 @@ def remove_item(self, item: ViewItem[V] | int | str) -> None:
if isinstance(item, (str, int)):
item = self.get_item(item)
try:
if isinstance(item.parent, BaseView):
if item.parent is self:
self.children.remove(item)
else:
item.parent.remove_item(item)
except ValueError:
pass
item.parent = None
return self

def clear_items(self) -> None:
def clear_items(self) -> Self:
"""Removes all items from this view."""
for child in self.children:
child.parent = None
self.children.clear()
return self

Expand Down Expand Up @@ -575,7 +577,6 @@ def __init__(
**func.__discord_ui_model_kwargs__
)
item.callback = partial(func, self, item)
item._view = self
item.parent = self
setattr(self, func.__name__, item)
self.children.append(item)
Expand Down Expand Up @@ -882,8 +883,6 @@ def add_item(self, item: ViewItem[V]) -> Self:
)

super().add_item(item)
if hasattr(item, "items"):
item.view = self
return self

def refresh(self, components: list[Component]):
Expand Down