diff --git a/discord/channel.py b/discord/channel.py index 2bf836ffb..56350aace 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -46,7 +46,7 @@ import datetime import discord.abc from .scheduled_event import ScheduledEvent from .permissions import PermissionOverwrite, Permissions -from .enums import ChannelType, PrivacyLevel, try_enum, VideoQualityMode +from .enums import ChannelType, PrivacyLevel, try_enum, VideoQualityMode, EntityType from .mixins import Hashable from . import utils from .utils import MISSING @@ -216,6 +216,10 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable): def _sorting_bucket(self) -> int: return ChannelType.text.value + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: base = super().permissions_for(obj) @@ -1045,6 +1049,10 @@ class VoiceChannel(discord.abc.Messageable, VocalGuildChannel): async def _get_channel(self) -> Self: return self + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return EntityType.voice + @property def type(self) -> Literal[ChannelType.voice]: """:class:`ChannelType`: The channel's Discord type.""" @@ -1480,6 +1488,10 @@ class StageChannel(VocalGuildChannel): super()._update(guild, data) self.topic: Optional[str] = data.get('topic') + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return EntityType.stage_instance + @property def requesting_to_speak(self) -> List[Member]: """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel.""" @@ -1758,6 +1770,10 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable): def _sorting_bucket(self) -> int: return ChannelType.category.value + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + @property def type(self) -> Literal[ChannelType.category]: """:class:`ChannelType`: The channel's Discord type.""" @@ -2034,6 +2050,10 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): def _sorting_bucket(self) -> int: return ChannelType.text.value + @property + def _scheduled_event_entity_type(self) -> Optional[EntityType]: + return None + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) def permissions_for(self, obj: Union[Member, Role], /) -> Permissions: base = super().permissions_for(obj) diff --git a/discord/guild.py b/discord/guild.py index b3cb226ef..ee9666e06 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -2657,7 +2657,7 @@ class Guild(Hashable): *, name: str, start_time: datetime.datetime, - entity_type: EntityType, + entity_type: EntityType = MISSING, privacy_level: PrivacyLevel = MISSING, channel: Optional[Snowflake] = MISSING, location: str = MISSING, @@ -2681,7 +2681,9 @@ class Guild(Hashable): description: :class:`str` The description of the scheduled event. channel: Optional[:class:`abc.Snowflake`] - The channel to send the scheduled event to. + The channel to send the scheduled event to. If the channel is + a :class:`StageInstance` or :class:`VoiceChannel` then + it automatically sets the entity type. Required if ``entity_type`` is either :attr:`EntityType.voice` or :attr:`EntityType.stage_instance`. @@ -2694,7 +2696,11 @@ class Guild(Hashable): Required if the entity type is :attr:`EntityType.external`. entity_type: :class:`EntityType` - The entity type of the scheduled event. + The entity type of the scheduled event. If the channel is a + :class:`StageInstance` or :class:`VoiceChannel` then this is + automatically set to the appropriate entity type. If no channel + is passed then the entity type is assumed to be + :attr:`EntityType.external` image: :class:`bytes` The image of the scheduled event. location: :class:`str` @@ -2736,6 +2742,18 @@ class Guild(Hashable): ) payload['scheduled_start_time'] = start_time.isoformat() + if entity_type is MISSING: + if channel is MISSING: + entity_type = EntityType.external + else: + entity_type = getattr(channel, '_scheduled_event_entity_type', MISSING) + if entity_type is None: + raise TypeError( + f'invalid GuildChannel type passed, must be VoiceChannel or StageChannel not {channel.__class__!r}' + ) + if entity_type is MISSING: + raise TypeError('entity_type must be passed in when passing an ambiguous channel type') + if not isinstance(entity_type, EntityType): raise TypeError('entity_type must be of type EntityType') diff --git a/discord/scheduled_event.py b/discord/scheduled_event.py index 44fa2ad36..b4f7f494a 100644 --- a/discord/scheduled_event.py +++ b/discord/scheduled_event.py @@ -324,7 +324,9 @@ class ScheduledEvent(Hashable): description: :class:`str` The description of the scheduled event. channel: Optional[:class:`~discord.abc.Snowflake`] - The channel to put the scheduled event in. + The channel to put the scheduled event in. If the channel is + a :class:`StageInstance` or :class:`VoiceChannel` then + it automatically sets the entity type. Required if the entity type is either :attr:`EntityType.voice` or :attr:`EntityType.stage_instance`. @@ -343,7 +345,9 @@ class ScheduledEvent(Hashable): privacy_level: :class:`PrivacyLevel` The privacy level of the scheduled event. entity_type: :class:`EntityType` - The new entity type. + The new entity type. If the channel is a :class:`StageInstance` + or :class:`VoiceChannel` then this is automatically set to the + appropriate entity type. status: :class:`EventStatus` The new status of the scheduled event. image: Optional[:class:`bytes`] @@ -407,6 +411,12 @@ class ScheduledEvent(Hashable): image_as_str: Optional[str] = _bytes_to_base64_data(image) if image is not None else image payload['image'] = image_as_str + entity_type = entity_type or getattr(channel, '_scheduled_event_entity_type', MISSING) + if entity_type is None: + raise TypeError( + f'invalid GuildChannel type passed, must be VoiceChannel or StageChannel not {channel.__class__!r}' + ) + if entity_type is not MISSING: if not isinstance(entity_type, EntityType): raise TypeError('entity_type must be of type EntityType')