Skip to content

Commit 0ac5fa3

Browse files
feat: allow list operations on ContainerComponent (#1783)
* feat: allow list operations on ContainerComponent Ideally improves UX. Hasn't been tested much. * ci: correct from checks. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 6150506 commit 0ac5fa3

File tree

1 file changed

+84
-7
lines changed

1 file changed

+84
-7
lines changed

interactions/models/discord/components.py

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
from collections import UserList
12
import contextlib
23
import uuid
34
from abc import abstractmethod
4-
from typing import Any, Dict, Iterator, List, Optional, Sequence, Union, TYPE_CHECKING
5+
from typing import Any, Dict, Iterator, List, Optional, Sequence, Union, TYPE_CHECKING, overload
6+
from typing_extensions import Self
57

68
import attrs
79
import discord_typings
@@ -1092,7 +1094,12 @@ def to_dict(self) -> dict:
10921094
}
10931095

10941096

1095-
class ContainerComponent(BaseComponent):
1097+
class ContainerComponent(
1098+
BaseComponent,
1099+
UserList[
1100+
ActionRow | SectionComponent | TextDisplayComponent | MediaGalleryComponent | FileComponent | SeparatorComponent
1101+
],
1102+
):
10961103
"""
10971104
A top-level layout component. Containers are visually distinct from surrounding components and have an optional customizable color bar.
10981105
@@ -1104,9 +1111,6 @@ class ContainerComponent(BaseComponent):
11041111
11051112
"""
11061113

1107-
components: list[
1108-
ActionRow | SectionComponent | TextDisplayComponent | MediaGalleryComponent | FileComponent | SeparatorComponent
1109-
]
11101114
accent_color: Optional[int] = None
11111115
spoiler: bool = False
11121116

@@ -1121,13 +1125,86 @@ def __init__(
11211125
accent_color: Optional[int] = None,
11221126
spoiler: bool = False,
11231127
):
1124-
self.components = list(components)
1128+
self.data = list(components)
11251129
self.accent_color = accent_color
11261130
self.spoiler = spoiler
11271131
self.type = ComponentType.CONTAINER
11281132

1133+
@property
1134+
def components(
1135+
self,
1136+
) -> list[
1137+
ActionRow | SectionComponent | TextDisplayComponent | MediaGalleryComponent | FileComponent | SeparatorComponent
1138+
]:
1139+
return self.data
1140+
1141+
@components.setter
1142+
def components(
1143+
self,
1144+
value: list[
1145+
ActionRow
1146+
| SectionComponent
1147+
| TextDisplayComponent
1148+
| MediaGalleryComponent
1149+
| FileComponent
1150+
| SeparatorComponent
1151+
],
1152+
) -> None:
1153+
self.data = value
1154+
1155+
@overload
1156+
def __getitem__(
1157+
self, i: int
1158+
) -> (
1159+
ActionRow | SectionComponent | TextDisplayComponent | MediaGalleryComponent | FileComponent | SeparatorComponent
1160+
): ...
1161+
1162+
@overload
1163+
def __getitem__(self, i: slice) -> Self: ...
1164+
1165+
def __getitem__(
1166+
self, i: int | slice
1167+
) -> (
1168+
Self
1169+
| ActionRow
1170+
| SectionComponent
1171+
| TextDisplayComponent
1172+
| MediaGalleryComponent
1173+
| FileComponent
1174+
| SeparatorComponent
1175+
):
1176+
if isinstance(i, slice):
1177+
return self.__class__(*self.data[i], accent_color=self.accent_color, spoiler=self.spoiler)
1178+
return self.data[i]
1179+
1180+
def __add__(self, other: Any) -> Self:
1181+
if isinstance(other, ContainerComponent):
1182+
return self.__class__(*(self.data + other.data), accent_color=self.accent_color, spoiler=self.spoiler)
1183+
if isinstance(other, UserList):
1184+
return self.__class__(*(self.data + other.data), accent_color=self.accent_color, spoiler=self.spoiler)
1185+
if isinstance(other, type(self.data)):
1186+
return self.__class__(*(self.data + other), accent_color=self.accent_color, spoiler=self.spoiler)
1187+
return self.__class__(*(self.data + list(other)), accent_color=self.accent_color, spoiler=self.spoiler)
1188+
1189+
def __radd__(self, other: Any) -> Self:
1190+
if isinstance(other, ContainerComponent):
1191+
return self.__class__(*(self.data + other.data), accent_color=other.accent_color, spoiler=other.spoiler)
1192+
if isinstance(other, UserList):
1193+
return self.__class__(*(other.data + self.data), accent_color=self.accent_color, spoiler=self.spoiler)
1194+
if isinstance(other, type(self.data)):
1195+
return self.__class__(*(other + self.data), accent_color=self.accent_color, spoiler=self.spoiler)
1196+
return self.__class__(*(list(other) + self.data), accent_color=self.accent_color, spoiler=self.spoiler)
1197+
1198+
def __mul__(self, n: int) -> Self:
1199+
return self.__class__(*(self.data * n), accent_color=self.accent_color, spoiler=self.spoiler)
1200+
1201+
__rmul__ = __mul__
1202+
1203+
def copy(self) -> Self:
1204+
return self.__class__(*self.data, accent_color=self.accent_color, spoiler=self.spoiler)
1205+
11291206
@classmethod
1130-
def from_dict(cls, data: dict) -> "ContainerComponent":
1207+
def from_dict(cls, data: dict) -> Self:
11311208
return cls(
11321209
*[BaseComponent.from_dict_factory(component) for component in data["components"]],
11331210
accent_color=data.get("accent_color"),

0 commit comments

Comments
 (0)