Skip to content

Commit 2542edc

Browse files
committed
♻️ Cleanup
1 parent 7b66171 commit 2542edc

File tree

5 files changed

+79
-95
lines changed

5 files changed

+79
-95
lines changed

discord/client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
from .mentions import AllowedMentions
5454
from .monetization import SKU, Entitlement
5555
from .object import Object
56-
from .soundboard import DefaultSoundboardSound
56+
from .soundboard import SoundboardSound
5757
from .stage_instance import StageInstance
5858
from .state import ConnectionState
5959
from .sticker import GuildSticker, StandardSticker, StickerPack, _sticker_factory
@@ -2310,4 +2310,7 @@ async def fetch_default_sounds(self) -> list[SoundboardSound]:
23102310
The bot's default sounds.
23112311
"""
23122312
data = await self._connection.http.get_default_sounds()
2313-
return [DefaultSoundboardSound(self.http, s) for s in data]
2313+
return [
2314+
SoundboardSound(http=self.http, state=self._connection, data=s)
2315+
for s in data
2316+
]

discord/soundboard.py

Lines changed: 56 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,28 @@
2525

2626
from __future__ import annotations
2727

28-
from typing import TYPE_CHECKING
28+
from typing import TYPE_CHECKING, Any, Coroutine
2929

30-
from typing_extensions import reveal_type
30+
from typing_extensions import override, reveal_type
3131

3232
from .asset import Asset
3333
from .emoji import PartialEmoji
3434
from .mixins import Hashable
3535
from .types.channel import (
3636
VoiceChannelEffectSendEvent as VoiceChannelEffectSendEventPayload,
3737
)
38-
from .types.soundboard import PartialSoundboardSound as PartialSoundboardSoundPayload
3938
from .types.soundboard import SoundboardSound as SoundboardSoundPayload
4039
from .utils import cached_slot_property
4140

4241
if TYPE_CHECKING:
4342
from .guild import Guild
4443
from .http import HTTPClient
45-
from .member import Member
4644
from .state import ConnectionState
4745

4846

4947
__all__ = (
5048
"PartialSoundboardSound",
5149
"SoundboardSound",
52-
"DefaultSoundboardSound",
5350
)
5451

5552

@@ -66,45 +63,54 @@ class PartialSoundboardSound(Hashable):
6663
The sound's emoji.
6764
"""
6865

69-
__slots__ = ("id", "volume", "emoji", "_http", "emoji")
66+
__slots__ = ("id", "volume", "emoji", "_http")
7067

7168
def __init__(
7269
self,
73-
data: PartialSoundboardSoundPayload | VoiceChannelEffectSendEventPayload,
70+
data: SoundboardSoundPayload | VoiceChannelEffectSendEventPayload,
7471
http: HTTPClient,
7572
):
7673
self._http = http
7774
self._from_data(data)
7875

79-
def __eq__(self, other: PartialSoundboardSound) -> bool:
76+
def _from_data(
77+
self, data: SoundboardSoundPayload | VoiceChannelEffectSendEventPayload
78+
) -> None:
79+
self.id = int(data.get("sound_id", 0))
80+
self.volume = (
81+
float(data.get("volume", 0) or data.get("sound_volume", 0)) or None
82+
)
83+
if raw_emoji := data.get(
84+
"emoji"
85+
): # From gateway event (VoiceChannelEffectSendEventPayload)
86+
self.emoji = PartialEmoji.from_dict(raw_emoji)
87+
else: # From HTTP response (SoundboardSoundPayload)
88+
self.emoji = PartialEmoji(
89+
name=data.get("emoji_name"),
90+
id=int(data.get("emoji_id", 0) or 0) or None,
91+
)
92+
93+
@override
94+
def __eq__(
95+
self, other: PartialSoundboardSound
96+
) -> bool: # pyright: ignore[reportIncompatibleMethodOverride]
8097
if isinstance(other, self, __class__):
8198
return self.id == other.id
8299
return NotImplemented
83100

84-
def __ne__(self, other: PartialSoundboardSound) -> bool:
101+
@override
102+
def __ne__(
103+
self, other: PartialSoundboardSound
104+
) -> bool: # pyright: ignore[reportIncompatibleMethodOverride]
85105
return not self.__eq__(other)
86106

87107
@property
88108
def file(self) -> Asset:
89109
""":class:`Asset`: Returns the sound's file."""
90110
return Asset._from_soundboard_sound(self, sound_id=self.id)
91111

92-
def _from_data(
93-
self, data: PartialSoundboardSoundPayload | VoiceChannelEffectSendEventPayload
94-
) -> None:
95-
self.id = int(data["sound_id"])
96-
self.volume = float(data.get("volume", 0)) or data.get("sound_volume")
97-
if raw_emoji := data.get(
98-
"emoji"
99-
): # From gateway event (VoiceChannelEffectSendEventPayload)
100-
self.emoji = PartialEmoji.from_dict(raw_emoji)
101-
elif emoji_id := data.get(
102-
"emoji_id", 0
103-
): # From HTTP response (PartialSoundboardSoundPayload)
104-
self.emoji = PartialEmoji(
105-
name=data.get("emoji_name"),
106-
id=int(emoji_id) or None,
107-
)
112+
def __repr__(self) -> str:
113+
return f"<PartialSoundboardSound id={self.id} volume={self.volume} emoji={self.emoji!r}>"
108114

109115

110116
class SoundboardSound(PartialSoundboardSound):
@@ -129,17 +135,12 @@ class SoundboardSound(PartialSoundboardSound):
129135
"""
130136

131137
__slots__ = (
132-
"id",
133-
"volume",
134138
"name",
135139
"available",
136-
"emoji",
137140
"guild_id",
138-
"_cs_guild",
139141
"user",
140-
"_http",
142+
"_cs_guild",
141143
"_state",
142-
"emoji",
143144
)
144145

145146
def __init__(
@@ -152,59 +153,42 @@ def __init__(
152153
self._state = state
153154
super().__init__(data, http)
154155

155-
def _from_data(self, data: SoundboardSoundPayload) -> None:
156+
@override
157+
def _from_data(
158+
self, data: SoundboardSoundPayload
159+
) -> None: # pyright: ignore[reportIncompatibleMethodOverride]
156160
super()._from_data(data)
157161
self.name = data["name"]
158162
self.available: bool = data["available"]
159-
self.guild_id = int(data["guild_id"])
163+
self.guild_id = int(data.get("guild_id", 0) or 0) or None
160164
user = data.get("user")
161-
162165
self.user = self._state.store_user(user) if user else None
163166

164167
@cached_slot_property("_cs_guild")
165-
def guild(self) -> Guild:
168+
def guild(self) -> Guild | None:
166169
""":class:`Guild`: The guild the sound belongs to.
167170
168171
The :class:`Guild` object representing the guild the sound belongs to.
169172
.. versionadded:: 2.7
170173
"""
171-
return self._state._get_guild(self.guild_id)
174+
return self._state._get_guild(self.guild_id) if self.guild_id else None
172175

173-
def __eq__(self, other: SoundboardSound) -> bool:
176+
@override
177+
def __eq__(
178+
self, other: SoundboardSound
179+
) -> bool: # pyright: ignore[reportIncompatibleMethodOverride]
174180
return isinstance(other, SoundboardSound) and self.__dict__ == other.__dict__
175181

176-
def delete(self):
177-
return self._http.delete_sound(self)
178-
179-
def _update(self, data: PartialSoundboardSound) -> None:
180-
super()._update(data)
181-
self.name = data["name"]
182-
self.available = bool(data.get("available", True))
183-
184-
185-
class DefaultSoundboardSound(PartialSoundboardSound):
186-
"""Represents a default soundboard sound.
187-
188-
Attributes
189-
----------
190-
id: :class:`int`
191-
The sound's ID.
192-
volume: :class:`float`
193-
The sound's volume.
194-
name: :class:`str`
195-
The sound's name.
196-
emoji: :class:`PartialEmoji`
197-
The sound's emoji.
198-
"""
199-
200-
__slots__ = ("id", "volume", "name", "emoji", "_http")
201-
202-
def __init__(self, *, http: HTTPClient, data: SoundboardSoundPayload) -> None:
203-
super().__init__(data, http)
204-
self.name = data["name"]
205-
206-
def __eq__(self, other: DefaultSoundboardSound) -> bool:
207-
return (
208-
isinstance(other, DefaultSoundboardSound)
209-
and self.__dict__ == other.__dict__
210-
)
182+
@property
183+
def is_default_sound(self) -> bool:
184+
""":class:`bool`: Whether the sound is a default sound."""
185+
return self.guild_id is None
186+
187+
def delete(self, *, reason: str | None = None) -> Coroutine[Any, Any, None]:
188+
if self.is_default_sound:
189+
raise ValueError("Cannot delete a default sound.")
190+
return self._http.delete_sound(self, reason=reason)
191+
192+
@override
193+
def __repr__(self) -> str:
194+
return f"<SoundboardSound id={self.id} name={self.name!r} volume={self.volume} emoji={self.emoji!r} guild={self.guild!r} user={self.user!r} available={self.available} default={self.is_default_sound}>"

discord/state.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
from .raw_models import *
6767
from .role import Role
6868
from .scheduled_events import ScheduledEvent
69-
from .soundboard import DefaultSoundboardSound, PartialSoundboardSound, SoundboardSound
69+
from .soundboard import PartialSoundboardSound, SoundboardSound
7070
from .stage_instance import StageInstance
7171
from .sticker import GuildSticker
7272
from .threads import Thread, ThreadMember
@@ -2030,7 +2030,7 @@ def parse_soundboard_sounds(self, data) -> None:
20302030
async def _add_default_sounds(self):
20312031
default_sounds = await self.http.get_default_sounds()
20322032
for default_sound in default_sounds:
2033-
sound = DefaultSoundboardSound(http=self.http, data=default_sound)
2033+
sound = SoundboardSound(http=self.http, data=default_sound)
20342034
self._add_sound(sound)
20352035

20362036
def _add_sound(self, sound: SoundboardSound):

discord/types/channel.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ class VoiceChannelEffectSendEvent(TypedDict):
188188
channel_id: Snowflake
189189
guild_id: Snowflake
190190
user_id: Snowflake
191-
sound_id: Snowflake | int
192-
sound_volume: float
193-
emoji: PartialEmoji | None
194-
animation_type: int
195-
animation_id: Snowflake
191+
emoji: NotRequired[PartialEmoji | None]
192+
animation_type: NotRequired[int | None]
193+
animation_id: NotRequired[int]
194+
sound_id: NotRequired[Snowflake | int]
195+
sound_volume: NotRequired[float]

discord/types/soundboard.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,21 @@
2323
DEALINGS IN THE SOFTWARE.
2424
"""
2525

26-
from typing import Optional, TypedDict, Union
26+
from __future__ import annotations
2727

28-
from .snowflake import Snowflake
28+
from typing_extensions import NotRequired, TypedDict
2929

30+
from discord.types.user import User
3031

31-
class PartialSoundboardSound(TypedDict):
32-
sound_id: Union[Snowflake, int]
33-
emoji_name: Optional[str]
34-
emoji_id: Optional[Snowflake]
35-
volume: float
32+
from .snowflake import Snowflake
3633

3734

38-
class SoundboardSound(PartialSoundboardSound):
39-
user_id: Snowflake
35+
class SoundboardSound(TypedDict):
4036
name: str
41-
guild_id: Snowflake
37+
sound_id: Snowflake | int
38+
volume: float
39+
emoji_name: str | None
40+
emoji_id: Snowflake | None
41+
guild_id: NotRequired[Snowflake]
42+
user: NotRequired[User]
4243
available: bool
43-
44-
45-
class DefaultSoundboardSound(PartialSoundboardSound):
46-
name: str

0 commit comments

Comments
 (0)