diff --git a/discord/abc.py b/discord/abc.py index 505552684..5ea20b558 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -95,7 +95,7 @@ if TYPE_CHECKING: ) from .poll import Poll from .threads import Thread - from .ui.view import BaseView + from .ui.view import BaseView, View, LayoutView from .types.channel import ( PermissionOverwrite as PermissionOverwritePayload, Channel as ChannelPayload, @@ -1374,6 +1374,38 @@ class Messageable: async def _get_channel(self) -> MessageableChannel: raise NotImplementedError + @overload + async def send( + self, + *, + file: File = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: LayoutView, + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def send( + self, + *, + files: Sequence[File] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: LayoutView, + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + @overload async def send( self, @@ -1388,7 +1420,7 @@ class Messageable: allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1409,7 +1441,7 @@ class Messageable: allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1430,7 +1462,7 @@ class Messageable: allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1451,7 +1483,7 @@ class Messageable: allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., diff --git a/discord/channel.py b/discord/channel.py index f17a74ca8..314c46fae 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -100,7 +100,7 @@ if TYPE_CHECKING: from .file import File from .user import ClientUser, User, BaseUser from .guild import Guild, GuildChannel as GuildChannelType - from .ui.view import BaseView + from .ui.view import BaseView, View, LayoutView from .types.channel import ( TextChannel as TextChannelPayload, NewsChannel as NewsChannelPayload, @@ -2841,6 +2841,46 @@ class ForumChannel(discord.abc.GuildChannel, Hashable): return result + @overload + async def create_thread( + self, + *, + name: str, + auto_archive_duration: ThreadArchiveDuration = MISSING, + slowmode_delay: Optional[int] = None, + file: File = MISSING, + files: Sequence[File] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + mention_author: bool = MISSING, + view: LayoutView, + suppress_embeds: bool = False, + reason: Optional[str] = None, + ) -> ThreadWithMessage: + ... + + @overload + async def create_thread( + self, + *, + name: str, + auto_archive_duration: ThreadArchiveDuration = MISSING, + slowmode_delay: Optional[int] = None, + content: Optional[str] = None, + tts: bool = False, + embed: Embed = MISSING, + embeds: Sequence[Embed] = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + stickers: Sequence[Union[GuildSticker, StickerItem]] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + mention_author: bool = MISSING, + applied_tags: Sequence[ForumTag] = MISSING, + view: View = MISSING, + suppress_embeds: bool = False, + reason: Optional[str] = None, + ) -> ThreadWithMessage: + ... + async def create_thread( self, *, diff --git a/discord/ext/commands/context.py b/discord/ext/commands/context.py index 931142b38..1e957feb4 100644 --- a/discord/ext/commands/context.py +++ b/discord/ext/commands/context.py @@ -48,7 +48,7 @@ if TYPE_CHECKING: from discord.mentions import AllowedMentions from discord.sticker import GuildSticker, StickerItem from discord.message import MessageReference, PartialMessage - from discord.ui.view import BaseView + from discord.ui.view import BaseView, View, LayoutView from discord.types.interactions import ApplicationCommandInteractionData from discord.poll import Poll @@ -628,6 +628,40 @@ class Context(discord.abc.Messageable, Generic[BotT]): except CommandError as e: await cmd.on_help_command_error(self, e) + @overload + async def reply( + self, + *, + file: File = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: LayoutView, + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def reply( + self, + *, + files: Sequence[File] = ..., + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + view: LayoutView, + suppress_embeds: bool = ..., + ephemeral: bool = ..., + silent: bool = ..., + ) -> Message: + ... + @overload async def reply( self, @@ -642,7 +676,7 @@ class Context(discord.abc.Messageable, Generic[BotT]): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., ephemeral: bool = ..., silent: bool = ..., @@ -664,7 +698,7 @@ class Context(discord.abc.Messageable, Generic[BotT]): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., ephemeral: bool = ..., silent: bool = ..., @@ -686,7 +720,7 @@ class Context(discord.abc.Messageable, Generic[BotT]): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., ephemeral: bool = ..., silent: bool = ..., @@ -708,7 +742,7 @@ class Context(discord.abc.Messageable, Generic[BotT]): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., ephemeral: bool = ..., silent: bool = ..., @@ -817,6 +851,14 @@ class Context(discord.abc.Messageable, Generic[BotT]): if self.interaction: await self.interaction.response.defer(ephemeral=ephemeral) + @overload + async def send( + self, + *, + view: LayoutView, + ) -> Message: + ... + @overload async def send( self, diff --git a/discord/interactions.py b/discord/interactions.py index 658ec4127..7b0b9c493 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations import logging -from typing import Any, Dict, Optional, Generic, TYPE_CHECKING, Sequence, Tuple, Union, List +from typing import Any, Dict, Optional, Generic, TYPE_CHECKING, Sequence, Tuple, Union, List, overload import asyncio import datetime @@ -76,7 +76,7 @@ if TYPE_CHECKING: from .mentions import AllowedMentions from aiohttp import ClientSession from .embeds import Embed - from .ui.view import BaseView + from .ui.view import BaseView, View, LayoutView from .app_commands.models import Choice, ChoiceT from .ui.modal import Modal from .channel import VoiceChannel, StageChannel, TextChannel, ForumChannel, CategoryChannel, DMChannel, GroupChannel @@ -469,6 +469,30 @@ class Interaction(Generic[ClientT]): self._original_response = message return message + @overload + async def edit_original_response( + self, + *, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: LayoutView, + allowed_mentions: Optional[AllowedMentions] = None, + ) -> InteractionMessage: + ... + + @overload + async def edit_original_response( + self, + *, + content: Optional[str] = MISSING, + embeds: Sequence[Embed] = MISSING, + embed: Optional[Embed] = MISSING, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: Optional[View] = MISSING, + allowed_mentions: Optional[AllowedMentions] = None, + poll: Poll = MISSING, + ) -> InteractionMessage: + ... + async def edit_original_response( self, *, @@ -889,6 +913,41 @@ class InteractionResponse(Generic[ClientT]): ) self._response_type = InteractionResponseType.pong + @overload + async def send_message( + self, + *, + file: File = MISSING, + files: Sequence[File] = MISSING, + view: LayoutView, + ephemeral: bool = False, + allowed_mentions: AllowedMentions = MISSING, + suppress_embeds: bool = False, + silent: bool = False, + delete_after: Optional[float] = None, + ) -> InteractionCallbackResponse[ClientT]: + ... + + @overload + async def send_message( + self, + content: Optional[Any] = None, + *, + embed: Embed = MISSING, + embeds: Sequence[Embed] = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + view: View = MISSING, + tts: bool = False, + ephemeral: bool = False, + allowed_mentions: AllowedMentions = MISSING, + suppress_embeds: bool = False, + silent: bool = False, + delete_after: Optional[float] = None, + poll: Poll = MISSING, + ) -> InteractionCallbackResponse[ClientT]: + ... + async def send_message( self, content: Optional[Any] = None, @@ -1042,6 +1101,33 @@ class InteractionResponse(Generic[ClientT]): type=self._response_type, ) + @overload + async def edit_message( + self, + *, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: LayoutView, + allowed_mentions: Optional[AllowedMentions] = MISSING, + delete_after: Optional[float] = None, + suppress_embeds: bool = MISSING, + ) -> Optional[InteractionCallbackResponse[ClientT]]: + ... + + @overload + async def edit_message( + self, + *, + content: Optional[Any] = MISSING, + embed: Optional[Embed] = MISSING, + embeds: Sequence[Embed] = MISSING, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: Optional[View] = MISSING, + allowed_mentions: Optional[AllowedMentions] = MISSING, + delete_after: Optional[float] = None, + suppress_embeds: bool = MISSING, + ) -> Optional[InteractionCallbackResponse[ClientT]]: + ... + async def edit_message( self, *, @@ -1333,6 +1419,32 @@ class InteractionMessage(Message): __slots__ = () _state: _InteractionMessageState + @overload + async def edit( + self, + *, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: LayoutView, + allowed_mentions: Optional[AllowedMentions] = None, + delete_after: Optional[float] = None, + ) -> InteractionMessage: + ... + + @overload + async def edit( + self, + *, + content: Optional[str] = MISSING, + embeds: Sequence[Embed] = MISSING, + embed: Optional[Embed] = MISSING, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: Optional[View] = MISSING, + allowed_mentions: Optional[AllowedMentions] = None, + delete_after: Optional[float] = None, + poll: Poll = MISSING, + ) -> InteractionMessage: + ... + async def edit( self, *, @@ -1412,7 +1524,7 @@ class InteractionMessage(Message): embeds=embeds, embed=embed, attachments=attachments, - view=view, + view=view, # type: ignore allowed_mentions=allowed_mentions, poll=poll, ) diff --git a/discord/message.py b/discord/message.py index e4f19a4dd..f3d364ec8 100644 --- a/discord/message.py +++ b/discord/message.py @@ -101,7 +101,7 @@ if TYPE_CHECKING: from .mentions import AllowedMentions from .user import User from .role import Role - from .ui.view import BaseView + from .ui.view import BaseView, View, LayoutView EmojiInputType = Union[Emoji, PartialEmoji, str] @@ -534,7 +534,7 @@ class MessageSnapshot: for component_data in data.get('components', []): component = _component_factory(component_data, state) # type: ignore if component is not None: - self.components.append(component) # type: ignore + self.components.append(component) self._state: ConnectionState = state @@ -1302,6 +1302,17 @@ class PartialMessage(Hashable): else: await self._state.http.delete_message(self.channel.id, self.id) + @overload + async def edit( + self, + *, + view: LayoutView, + attachments: Sequence[Union[Attachment, File]] = ..., + delete_after: Optional[float] = ..., + allowed_mentions: Optional[AllowedMentions] = ..., + ) -> Message: + ... + @overload async def edit( self, @@ -1311,7 +1322,7 @@ class PartialMessage(Hashable): attachments: Sequence[Union[Attachment, File]] = ..., delete_after: Optional[float] = ..., allowed_mentions: Optional[AllowedMentions] = ..., - view: Optional[BaseView] = ..., + view: Optional[View] = ..., ) -> Message: ... @@ -1324,7 +1335,7 @@ class PartialMessage(Hashable): attachments: Sequence[Union[Attachment, File]] = ..., delete_after: Optional[float] = ..., allowed_mentions: Optional[AllowedMentions] = ..., - view: Optional[BaseView] = ..., + view: Optional[View] = ..., ) -> Message: ... @@ -1387,10 +1398,13 @@ class PartialMessage(Hashable): are used instead. .. versionadded:: 1.4 - view: Optional[:class:`~discord.ui.View`] + view: Optional[Union[:class:`~discord.ui.View`, :class:`~discord.ui.LayoutView`]] The updated view to update this message with. If ``None`` is passed then the view is removed. + .. versionchanged:: 2.6 + This now accepts :class:`~discord.ui.LayoutView` instances. + Raises ------- HTTPException @@ -1752,6 +1766,38 @@ class PartialMessage(Hashable): return await self.guild.fetch_channel(self.id) # type: ignore # Can only be Thread in this case + @overload + async def reply( + self, + *, + file: File = ...,g + view: LayoutView, + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + + @overload + async def reply( + self, + *, + files: Sequence[File] = ..., + view: LayoutView, + delete_after: float = ..., + nonce: Union[str, int] = ..., + allowed_mentions: AllowedMentions = ..., + reference: Union[Message, MessageReference, PartialMessage] = ..., + mention_author: bool = ..., + suppress_embeds: bool = ..., + silent: bool = ..., + ) -> Message: + ... + @overload async def reply( self, @@ -1766,7 +1812,7 @@ class PartialMessage(Hashable): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1787,7 +1833,7 @@ class PartialMessage(Hashable): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1808,7 +1854,7 @@ class PartialMessage(Hashable): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., @@ -1829,7 +1875,7 @@ class PartialMessage(Hashable): allowed_mentions: AllowedMentions = ..., reference: Union[Message, MessageReference, PartialMessage] = ..., mention_author: bool = ..., - view: BaseView = ..., + view: View = ..., suppress_embeds: bool = ..., silent: bool = ..., poll: Poll = ..., diff --git a/discord/ui/view.py b/discord/ui/view.py index 61abd9875..e1f53bd8e 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -708,7 +708,7 @@ class LayoutView(BaseView): This object must be inherited to create a UI within Discord. - + .. versionadded:: 2.6 diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index c2c40ada5..897ddadd3 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -71,7 +71,7 @@ if TYPE_CHECKING: from ..emoji import Emoji from ..channel import VoiceChannel from ..abc import Snowflake - from ..ui.view import BaseView + from ..ui.view import BaseView, View, LayoutView from ..poll import Poll import datetime from ..types.webhook import ( @@ -1605,6 +1605,44 @@ class Webhook(BaseWebhook): # state is artificial return WebhookMessage(data=data, state=state, channel=channel) # type: ignore + @overload + async def send( + self, + *, + username: str = MISSING, + avatar_url: Any = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + view: LayoutView, + wait: Literal[True], + thread: Snowflake = MISSING, + thread_name: str = MISSING, + suppress_embeds: bool = MISSING, + silent: bool = MISSING, + applied_tags: List[ForumTag] = MISSING, + ) -> WebhookMessage: + ... + + @overload + async def send( + self, + *, + username: str = MISSING, + avatar_url: Any = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + view: LayoutView, + wait: Literal[False] = ..., + thread: Snowflake = MISSING, + thread_name: str = MISSING, + suppress_embeds: bool = MISSING, + silent: bool = MISSING, + applied_tags: List[ForumTag] = MISSING, + ) -> None: + ... + @overload async def send( self, @@ -1619,7 +1657,7 @@ class Webhook(BaseWebhook): embed: Embed = MISSING, embeds: Sequence[Embed] = MISSING, allowed_mentions: AllowedMentions = MISSING, - view: BaseView = MISSING, + view: View = MISSING, thread: Snowflake = MISSING, thread_name: str = MISSING, wait: Literal[True], @@ -1644,7 +1682,7 @@ class Webhook(BaseWebhook): embed: Embed = MISSING, embeds: Sequence[Embed] = MISSING, allowed_mentions: AllowedMentions = MISSING, - view: BaseView = MISSING, + view: View = MISSING, thread: Snowflake = MISSING, thread_name: str = MISSING, wait: Literal[False] = ..., @@ -1940,6 +1978,30 @@ class Webhook(BaseWebhook): ) return self._create_message(data, thread=thread) + @overload + async def edit_message( + self, + message_id: int, + *, + view: LayoutView, + ) -> WebhookMessage: + ... + + @overload + async def edit_message( + self, + message_id: int, + *, + content: Optional[str] = MISSING, + embeds: Sequence[Embed] = MISSING, + embed: Optional[Embed] = MISSING, + attachments: Sequence[Union[Attachment, File]] = MISSING, + view: Optional[View] = MISSING, + allowed_mentions: Optional[AllowedMentions] = None, + thread: Snowflake = MISSING, + ) -> WebhookMessage: + ... + async def edit_message( self, message_id: int, @@ -1987,12 +2049,14 @@ class Webhook(BaseWebhook): allowed_mentions: :class:`AllowedMentions` Controls the mentions being processed in this message. See :meth:`.abc.Messageable.send` for more information. - view: Optional[:class:`~discord.ui.View`] + view: Optional[Union[:class:`~discord.ui.View`, :class:`~discord.ui.LayoutView`]] The updated view to update this message with. If ``None`` is passed then the view is removed. The webhook must have state attached, similar to :meth:`send`. .. versionadded:: 2.0 + .. versionchanged:: 2.6 + This now accepts :class:`~discord.ui.LayoutView` instances. thread: :class:`~discord.abc.Snowflake` The thread the webhook message belongs to. diff --git a/discord/webhook/sync.py b/discord/webhook/sync.py index 904597761..9c211898d 100644 --- a/discord/webhook/sync.py +++ b/discord/webhook/sync.py @@ -66,7 +66,7 @@ if TYPE_CHECKING: from ..message import Attachment from ..abc import Snowflake from ..state import ConnectionState - from ..ui.view import BaseView + from ..ui.view import BaseView, View, LayoutView from ..types.webhook import ( Webhook as WebhookPayload, ) @@ -856,6 +856,44 @@ class SyncWebhook(BaseWebhook): # state is artificial return SyncWebhookMessage(data=data, state=state, channel=channel) # type: ignore + @overload + def send( + self, + *, + username: str = MISSING, + avatar_url: Any = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + view: LayoutView, + wait: Literal[True], + thread: Snowflake = MISSING, + thread_name: str = MISSING, + suppress_embeds: bool = MISSING, + silent: bool = MISSING, + applied_tags: List[ForumTag] = MISSING, + ) -> SyncWebhookMessage: + ... + + @overload + def send( + self, + *, + username: str = MISSING, + avatar_url: Any = MISSING, + file: File = MISSING, + files: Sequence[File] = MISSING, + allowed_mentions: AllowedMentions = MISSING, + view: LayoutView, + wait: Literal[False] = ..., + thread: Snowflake = MISSING, + thread_name: str = MISSING, + suppress_embeds: bool = MISSING, + silent: bool = MISSING, + applied_tags: List[ForumTag] = MISSING, + ) -> None: + ... + @overload def send( self, @@ -876,7 +914,7 @@ class SyncWebhook(BaseWebhook): silent: bool = MISSING, applied_tags: List[ForumTag] = MISSING, poll: Poll = MISSING, - view: BaseView = MISSING, + view: View = MISSING, ) -> SyncWebhookMessage: ... @@ -900,7 +938,7 @@ class SyncWebhook(BaseWebhook): silent: bool = MISSING, applied_tags: List[ForumTag] = MISSING, poll: Poll = MISSING, - view: BaseView = MISSING, + view: View = MISSING, ) -> None: ...