Skip to content

Commit 9663af1

Browse files
committed
feat: rework how item.view is determined
1 parent d184428 commit 9663af1

File tree

5 files changed

+23
-21
lines changed

5 files changed

+23
-21
lines changed

discord/ui/action_row.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ def add_item(self, item: ViewItem) -> Self:
140140
if self.width + item.width > 5:
141141
raise ValueError(f"Not enough space left on this ActionRow")
142142

143-
item._view = self.view
144143
item.parent = self
145144

146145
self.children.append(item)
@@ -162,6 +161,7 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
162161
self.children.remove(item)
163162
except ValueError:
164163
pass
164+
item.parent = None
165165
return self
166166

167167
def get_item(self, id: str | int) -> ViewItem | None:

discord/ui/container.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,6 @@ def add_item(self, item: ViewItem) -> Self:
149149
f"{item.__class__!r} cannot be added directly. Use ActionRow instead."
150150
)
151151

152-
item._view = self.view
153-
if hasattr(item, "items"):
154-
item.view = self
155152
item.parent = self
156153

157154
self.items.append(item)
@@ -170,12 +167,13 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
170167
if isinstance(item, (str, int)):
171168
item = self.get_item(item)
172169
try:
173-
if isinstance(item, Container):
170+
if item.parent is self:
174171
self.items.remove(item)
175172
else:
176173
item.parent.remove_item(item)
177174
except ValueError:
178175
pass
176+
item.parent = None
179177
return self
180178

181179
def get_item(self, id: str | int) -> ViewItem | None:

discord/ui/item.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
"ModalItem",
3636
)
3737

38+
from ..utils import deprecated, warn_deprecated
39+
3840
if TYPE_CHECKING:
3941
from ..components import Component
4042
from ..enums import ComponentType
@@ -152,7 +154,7 @@ def __init__(self):
152154
self._view: V | None = None
153155
self._row: int | None = None
154156
self._rendered_row: int | None = None
155-
self.parent: ViewItem | BaseView | None = self.view
157+
self.parent: ViewItem | BaseView | None = None
156158

157159
@property
158160
def row(self) -> int | None:
@@ -208,10 +210,17 @@ def view(self) -> V | None:
208210
Optional[:class:`BaseView`]
209211
The parent view of this item, or ``None`` if the item is not attached to any view.
210212
"""
211-
return self._view
213+
if self._view:
214+
return self._view
215+
if self.parent:
216+
if isinstance(self.parent, BaseView):
217+
return self.parent
218+
return self.parent.view
219+
return None
212220

213221
@view.setter
214-
def view(self, value) -> None:
222+
def view(self, value: V | None) -> None:
223+
warn_deprecated("Manually setting .view", since="2.7", removed="2.8")
215224
self._view = value
216225

217226
async def callback(self, interaction: Interaction):

discord/ui/section.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def remove_item(self, item: ViewItem | str | int) -> Self:
162162
self.items.remove(item)
163163
except ValueError:
164164
pass
165+
item.parent = None
165166
return self
166167

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

227228
if not isinstance(item, ViewItem):
228229
raise TypeError(f"expected ViewItem not {item.__class__!r}")
229-
if self.view:
230-
item._view = self.view
230+
231231
item.parent = self
232232

233233
self.accessory = item
@@ -260,13 +260,6 @@ def set_thumbnail(
260260

261261
return self.set_accessory(thumbnail)
262262

263-
@ViewItem.view.setter
264-
def view(self, value):
265-
self._view = value
266-
for item in self.walk_items():
267-
item._view = value
268-
item.parent = self
269-
270263
def copy_text(self) -> str:
271264
"""Returns the text of all :class:`~discord.ui.TextDisplay` items in this section.
272265
Equivalent to the `Copy Text` option on Discord clients.

discord/ui/view.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,10 @@ def add_item(self, item: ViewItem[V]) -> Self:
235235
raise TypeError(f"expected ViewItem not {item.__class__!r}")
236236

237237
item.parent = self
238-
item._view = self
239238
self.children.append(item)
240239
return self
241240

242-
def remove_item(self, item: ViewItem[V] | int | str) -> None:
241+
def remove_item(self, item: ViewItem[V] | int | str) -> Self:
243242
"""Removes an item from the view. If an :class:`int` or :class:`str` is passed,
244243
the item will be removed by ViewItem ``id`` or ``custom_id`` respectively.
245244
@@ -252,17 +251,20 @@ def remove_item(self, item: ViewItem[V] | int | str) -> None:
252251
if isinstance(item, (str, int)):
253252
item = self.get_item(item)
254253
try:
255-
if isinstance(item.parent, BaseView):
254+
if item.parent is self:
256255
self.children.remove(item)
257256
else:
258257
item.parent.remove_item(item)
259258
except ValueError:
260259
pass
260+
item.parent = None
261261
return self
262262

263-
def clear_items(self) -> None:
263+
def clear_items(self) -> Self:
264264
"""Removes all items from this view."""
265265
self.children.clear()
266+
for child in self.children:
267+
child.parent = None
266268
return self
267269

268270
async def interaction_check(self, interaction: Interaction) -> bool:

0 commit comments

Comments
 (0)