From 7a35e216b171f4edaf848c670a3b3b934e289b0b Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 16:22:22 +0800 Subject: [PATCH 01/15] feat: application emojis --- disnake/client.py | 104 +++- disnake/emoji.py | 201 ++++++- disnake/ext/commands/bot.py | 12 + disnake/http.py | 1081 ++++++++++++++++++----------------- disnake/state.py | 34 +- 5 files changed, 898 insertions(+), 534 deletions(-) diff --git a/disnake/client.py b/disnake/client.py index 885a6979fe..c6735a32bc 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -46,7 +46,7 @@ from .application_role_connection import ApplicationRoleConnectionMetadata from .backoff import ExponentialBackoff from .channel import PartialMessageable, _threaded_channel_factory -from .emoji import Emoji +from .emoji import ApplicationEmoji, GuildEmoji from .entitlement import Entitlement from .enums import ApplicationCommandType, ChannelType, Event, Status from .errors import ( @@ -401,6 +401,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, ) -> None: # self.ws is set in the connect method self.ws: DiscordWebSocket = None # type: ignore @@ -444,6 +445,7 @@ def __init__( intents=intents, chunk_guilds_at_startup=chunk_guilds_at_startup, member_cache_flags=member_cache_flags, + cache_app_emojis=cache_app_emojis ) self.shard_id: Optional[int] = shard_id self.shard_count: Optional[int] = shard_count @@ -492,12 +494,13 @@ def _get_state( application_id: Optional[int], heartbeat_timeout: float, guild_ready_timeout: float, + cache_app_emojis: bool, allowed_mentions: Optional[AllowedMentions], activity: Optional[BaseActivity], status: Optional[Union[str, Status]], intents: Optional[Intents], chunk_guilds_at_startup: Optional[bool], - member_cache_flags: Optional[MemberCacheFlags], + member_cache_flags: Optional[MemberCacheFlags] ) -> ConnectionState: return ConnectionState( dispatch=self.dispatch, @@ -515,6 +518,7 @@ def _get_state( intents=intents, chunk_guilds_at_startup=chunk_guilds_at_startup, member_cache_flags=member_cache_flags, + cache_app_emojis=cache_app_emojis ) def _handle_ready(self) -> None: @@ -559,8 +563,14 @@ def guilds(self) -> List[Guild]: return self._connection.guilds @property - def emojis(self) -> List[Emoji]: - """List[:class:`.Emoji`]: The emojis that the connected client has.""" + def emojis(self) -> list[GuildEmoji | ApplicationEmoji]: + """The emojis that the connected client has. + + .. note:: + + This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is +``True``. + """ return self._connection.emojis @property @@ -1474,7 +1484,7 @@ def get_user(self, id: int, /) -> Optional[User]: """ return self._connection.get_user(id) - def get_emoji(self, id: int, /) -> Optional[Emoji]: + def get_emoji(self, id: int, /) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: """Returns an emoji with the given ID. Parameters @@ -3211,3 +3221,87 @@ async def create_entitlement( owner_type=2 if isinstance(owner, abc.User) else 1, ) return Entitlement(data=data, state=self._connection) + + async def fetch_application_emojis(self) -> list[ApplicationEmoji]: + r"""|coro| + Retrieves all custom :class:`ApplicationEmoji`\s from the application. + + Raises + --------- + HTTPException + An error occurred fetching the emojis. + + Returns + -------- + List[:class:`ApplicationEmoji`] + The retrieved emojis. + """ + data = await self._connection.http.get_all_application_emojis(self.application_id) + return [ + self._connection.store_application_emoji(self.application_id, d) + for d in data["items"] + ] + + async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: + """|coro| + Retrieves a custom :class:`ApplicationEmoji` from the application. + + Parameters + ---------- + emoji_id: :class:`int` + The emoji's ID. + + Returns + ------- + :class:`ApplicationEmoji` + The retrieved emoji. + + Raises + ------ + NotFound + The emoji requested could not be found. + HTTPException + An error occurred fetching the emoji. + """ + data = await self._connection.http.get_application_emoji( + self.application_id, emoji_id + ) + return self._connection.store_application_emoji(self.application_id, data) + + async def create_application_emoji( + self, + *, + name: str, + image: bytes, + ) -> ApplicationEmoji: + r"""|coro| + Creates a custom :class:`ApplicationEmoji` for the application. + There is currently a limit of 2000 emojis per application. + + Parameters + ----------- + name: :class:`str` + The emoji name. Must be at least 2 characters. + image: :class:`bytes` + The :term:`py:bytes-like object` representing the image data to use. + Only JPG, PNG and GIF images are supported. + + Raises + ------- + Forbidden + You are not allowed to create emojis. + HTTPException + An error occurred creating an emoji. + + Returns + -------- + :class:`ApplicationEmoji` + The created emoji. + """ + + img = utils._bytes_to_base64_data(image) + data = await self._connection.http.create_application_emoji( + self.application_id, name, img + ) + return self._connection.store_application_emoji(self.application_id, data) + diff --git a/disnake/emoji.py b/disnake/emoji.py index badedbce86..3b5f611fbf 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -9,20 +9,23 @@ from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ("Emoji",) +__all__ = ( + "Emoji", + "GuildEmoji", + "ApplicationEmoji" +) if TYPE_CHECKING: from datetime import datetime from .abc import Snowflake from .guild import Guild - from .guild_preview import GuildPreview from .role import Role from .state import ConnectionState from .types.emoji import Emoji as EmojiPayload -class Emoji(_EmojiTag, AssetMixin): +class BaseEmoji(_EmojiTag, AssetMixin): """Represents a custom emoji. Depending on the way this object was created, some of the attributes can @@ -81,14 +84,14 @@ class Emoji(_EmojiTag, AssetMixin): "name", "_roles", "guild_id", + "application_id", "user", "available", ) def __init__( - self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload + self, *, state: ConnectionState, data: EmojiPayload ) -> None: - self.guild_id: int = guild.id self._state: ConnectionState = state self._from_data(data) @@ -119,7 +122,7 @@ def __str__(self) -> str: return f"<:{self.name}:{self.id}>" def __repr__(self) -> str: - return f"" + return f"" def __eq__(self, other: Any) -> bool: return isinstance(other, _EmojiTag) and self.id == other.id @@ -141,6 +144,65 @@ def url(self) -> str: fmt = "gif" if self.animated else "png" return f"{Asset.BASE}/emojis/{self.id}.{fmt}" + +class GuildEmoji(BaseEmoji): + """Represents a custom emoji in a guild. + + Depending on the way this object was created, some of the attributes can + have a value of ``None``. + + .. collapse:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for Discord. + + Attributes + ---------- + name: :class:`str` + The emoji's name. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + Whether colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether the emoji is animated or not. + managed: :class:`bool` + Whether the emoji is managed by a Twitch integration. + guild_id: :class:`int` + The guild ID the emoji belongs to. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created this emoji. This can only be retrieved using + :meth:`Guild.fetch_emoji`/:meth:`Guild.fetch_emojis` while + having the :attr:`~Permissions.manage_guild_expressions` permission. + """ + + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): + self.guild_id: int = guild.id + super().__init__(state=state, data=data) + + def __repr__(self) -> str: + return f"" + @property def roles(self) -> List[Role]: """List[:class:`Role`]: A :class:`list` of roles that are allowed to use this emoji. @@ -199,8 +261,8 @@ async def delete(self, *, reason: Optional[str] = None) -> None: await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) async def edit( - self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None - ) -> Emoji: + self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None + ) -> GuildEmoji: """|coro| Edits the custom emoji. @@ -233,7 +295,7 @@ async def edit( Returns ------- - :class:`Emoji` + :class:`GuildEmoji` The newly updated emoji. """ payload = {} @@ -245,4 +307,123 @@ async def edit( data = await self._state.http.edit_custom_emoji( self.guild.id, self.id, payload=payload, reason=reason ) - return Emoji(guild=self.guild, data=data, state=self._state) + return GuildEmoji(guild=self.guild, data=data, state=self._state) + + +Emoji = GuildEmoji + + +class ApplicationEmoji(BaseEmoji): + """Represents a custom emoji from an application. + + Depending on the way this object was created, some attributes can + have a value of ``None``. + + .. container:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for discord. + + Attributes + ---------- + name: :class:`str` + The name of the emoji. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether an emoji is animated or not. + managed: :class:`bool` + If this emoji is managed by a Twitch integration. + application_id: Optional[:class:`int`] + The application ID the emoji belongs to, if available. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created the emoji. + """ + + def __init__( + self, *, application_id: int, state: ConnectionState, data: EmojiPayload + ): + self.application_id: int = application_id + super().__init__(state=state, data=data) + + def __repr__(self): + return f"" + + def is_usable(self) -> bool: + """Whether the bot can use this emoji.""" + return self.application_id == self._state.application_id + + async def delete(self) -> None: + """|coro| + Deletes the application emoji. + You must own the emoji to do this. + + Raises + ------ + Forbidden + You are not allowed to delete the emoji. + HTTPException + An error occurred deleting the emoji. + """ + + await self._state.http.delete_application_emoji(self.application_id, self.id) + if self._state.cache_app_emojis and self._state.get_emoji(self.id): + self._state._remove_emoji(self) + + async def edit( + self, + *, + name: str = MISSING, + ) -> ApplicationEmoji: + r"""|coro| + Edits the application emoji. + You must own the emoji to do this. + + Parameters + ----------- + name: :class:`str` + The new emoji name. + + Raises + ------- + Forbidden + You are not allowed to edit the emoji. + HTTPException + An error occurred editing the emoji. + + Returns + -------- + :class:`ApplicationEmoji` + The newly updated emoji. + """ + + payload = {} + if name is not MISSING: + payload["name"] = name + + data = await self._state.http.edit_application_emoji( + self.application_id, self.id, payload=payload + ) + return self._state.store_application_emoji(self.application_id, data) \ No newline at end of file diff --git a/disnake/ext/commands/bot.py b/disnake/ext/commands/bot.py index 825f96e6ae..9d9c092196 100644 --- a/disnake/ext/commands/bot.py +++ b/disnake/ext/commands/bot.py @@ -215,6 +215,10 @@ class Bot(BotBase, InteractionBotBase, disnake.Client): application commands. .. versionadded:: 2.5 + + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. + Defaults to ``False``. """ if TYPE_CHECKING: @@ -258,6 +262,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, localization_provider: Optional[LocalizationProtocol] = None, strict_localization: bool = False, ) -> None: @@ -310,6 +315,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, localization_provider: Optional[LocalizationProtocol] = None, strict_localization: bool = False, ) -> None: @@ -423,6 +429,10 @@ class InteractionBot(InteractionBotBase, disnake.Client): application commands. .. versionadded:: 2.5 + + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. + Defaults to ``False``. """ if TYPE_CHECKING: @@ -459,6 +469,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, localization_provider: Optional[LocalizationProtocol] = None, strict_localization: bool = False, ) -> None: @@ -504,6 +515,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, localization_provider: Optional[LocalizationProtocol] = None, strict_localization: bool = False, ) -> None: diff --git a/disnake/http.py b/disnake/http.py index f10cd3fdd8..bfd34156ec 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -155,7 +155,7 @@ def to_multipart(payload: Dict[str, Any], files: Sequence[File]) -> List[Dict[st def to_multipart_with_attachments( - payload: Dict[str, Any], files: Sequence[File] + payload: Dict[str, Any], files: Sequence[File] ) -> List[Dict[str, Any]]: """Updates the payload's attachments and converts it to a multipart payload @@ -202,10 +202,10 @@ def defer(self) -> None: self._unlock = False def __exit__( - self, - exc_type: Optional[Type[BaseException]], - exc: Optional[BaseException], - traceback: Optional[TracebackType], + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + traceback: Optional[TracebackType], ) -> None: if self._unlock: self.lock.release() @@ -220,13 +220,13 @@ class HTTPClient: """Represents an HTTP client sending HTTP requests to the Discord API.""" def __init__( - self, - connector: Optional[aiohttp.BaseConnector] = None, - *, - loop: asyncio.AbstractEventLoop, - proxy: Optional[str] = None, - proxy_auth: Optional[aiohttp.BasicAuth] = None, - unsync_clock: bool = True, + self, + connector: Optional[aiohttp.BaseConnector] = None, + *, + loop: asyncio.AbstractEventLoop, + proxy: Optional[str] = None, + proxy_auth: Optional[aiohttp.BasicAuth] = None, + unsync_clock: bool = True, ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.connector = connector @@ -264,12 +264,12 @@ async def ws_connect(self, url: str, *, compress: int = 0) -> aiohttp.ClientWebS ) async def request( - self, - route: Route, - *, - files: Optional[Sequence[File]] = None, - form: Optional[Iterable[Dict[str, Any]]] = None, - **kwargs: Any, + self, + route: Route, + *, + files: Optional[Sequence[File]] = None, + form: Optional[Iterable[Dict[str, Any]]] = None, + **kwargs: Any, ) -> Any: bucket = route.bucket method = route.method @@ -468,13 +468,13 @@ async def static_login(self, token: str) -> user.User: return data def create_party( - self, - channel_id: Snowflake, - max_age: int, - max_uses: int, - target_application_id: Snowflake, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + max_age: int, + max_uses: int, + target_application_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[invite.Invite]: payload = { "max_age": max_age, @@ -493,7 +493,7 @@ def create_party( # Group functionality def start_group( - self, user_id: Snowflake, recipients: List[int] + self, user_id: Snowflake, recipients: List[int] ) -> Response[channel.GroupDMChannel]: payload = { "recipients": recipients, @@ -516,19 +516,19 @@ def start_private_message(self, user_id: Snowflake) -> Response[channel.DMChanne return self.request(Route("POST", "/users/@me/channels"), json=payload) def send_message( - self, - channel_id: Snowflake, - content: Optional[str], - *, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + channel_id: Snowflake, + content: Optional[str], + *, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) payload: Dict[str, Any] = {} @@ -569,20 +569,20 @@ def send_typing(self, channel_id: Snowflake) -> Response[None]: return self.request(Route("POST", "/channels/{channel_id}/typing", channel_id=channel_id)) def send_multipart_helper( - self, - route: Route, - *, - files: Sequence[File], - content: Optional[str] = None, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + route: Route, + *, + files: Sequence[File], + content: Optional[str] = None, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: payload: Dict[str, Any] = {"tts": tts} if content: @@ -609,20 +609,20 @@ def send_multipart_helper( return self.request(route, form=multipart, files=files) def send_files( - self, - channel_id: Snowflake, - *, - files: Sequence[File], - content: Optional[str] = None, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + channel_id: Snowflake, + *, + files: Sequence[File], + content: Optional[str] = None, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) return self.send_multipart_helper( @@ -641,7 +641,7 @@ def send_files( ) def delete_message( - self, channel_id: Snowflake, message_id: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -652,7 +652,7 @@ def delete_message( return self.request(r, reason=reason) def delete_messages( - self, channel_id: Snowflake, message_ids: SnowflakeList, *, reason: Optional[str] = None + self, channel_id: Snowflake, message_ids: SnowflakeList, *, reason: Optional[str] = None ) -> Response[None]: r = Route("POST", "/channels/{channel_id}/messages/bulk-delete", channel_id=channel_id) payload = { @@ -662,12 +662,12 @@ def delete_messages( return self.request(r, json=payload, reason=reason) def edit_message( - self, - channel_id: Snowflake, - message_id: Snowflake, - *, - files: Optional[List[File]] = None, - **fields: Any, + self, + channel_id: Snowflake, + message_id: Snowflake, + *, + files: Optional[List[File]] = None, + **fields: Any, ) -> Response[message.Message]: r = Route( "PATCH", @@ -681,7 +681,7 @@ def edit_message( return self.request(r, json=fields) def add_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "PUT", @@ -693,7 +693,7 @@ def add_reaction( return self.request(r) def remove_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str, member_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake, emoji: str, member_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -706,7 +706,7 @@ def remove_reaction( return self.request(r) def remove_own_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "DELETE", @@ -718,12 +718,12 @@ def remove_own_reaction( return self.request(r) def get_reaction_users( - self, - channel_id: Snowflake, - message_id: Snowflake, - emoji: str, - limit: int, - after: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + message_id: Snowflake, + emoji: str, + limit: int, + after: Optional[Snowflake] = None, ) -> Response[List[user.User]]: r = Route( "GET", @@ -751,7 +751,7 @@ def clear_reactions(self, channel_id: Snowflake, message_id: Snowflake) -> Respo return self.request(r) def clear_single_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "DELETE", @@ -763,7 +763,7 @@ def clear_single_reaction( return self.request(r) def get_message( - self, channel_id: Snowflake, message_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake ) -> Response[message.Message]: r = Route( "GET", @@ -778,12 +778,12 @@ def get_channel(self, channel_id: Snowflake) -> Response[channel.Channel]: return self.request(r) def logs_from( - self, - channel_id: Snowflake, - limit: int, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - around: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + limit: int, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + around: Optional[Snowflake] = None, ) -> Response[List[message.Message]]: params: Dict[str, Any] = { "limit": limit, @@ -801,7 +801,7 @@ def logs_from( ) def publish_message( - self, channel_id: Snowflake, message_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake ) -> Response[message.Message]: return self.request( Route( @@ -813,7 +813,7 @@ def publish_message( ) def pin_message( - self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "PUT", @@ -824,7 +824,7 @@ def pin_message( return self.request(r, reason=reason) def unpin_message( - self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -840,14 +840,14 @@ def pins_from(self, channel_id: Snowflake) -> Response[List[message.Message]]: # Member management def search_guild_members( - self, guild_id: Snowflake, query: str, limit: int = 1 + self, guild_id: Snowflake, query: str, limit: int = 1 ) -> Response[List[member.MemberWithUser]]: r = Route("GET", "/guilds/{guild_id}/members/search", guild_id=guild_id) return self.request(r, params={"query": query, "limit": limit}) def kick( - self, user_id: Snowflake, guild_id: Snowflake, reason: Optional[str] = None + self, user_id: Snowflake, guild_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -856,12 +856,12 @@ def kick( return self.request(r, reason=reason) def ban( - self, - user_id: Snowflake, - guild_id: Snowflake, - *, - delete_message_seconds: int = 86400, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + *, + delete_message_seconds: int = 86400, + reason: Optional[str] = None, ) -> Response[None]: r = Route("PUT", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id) payload = { @@ -871,18 +871,18 @@ def ban( return self.request(r, json=payload, reason=reason) def unban( - self, user_id: Snowflake, guild_id: Snowflake, *, reason: Optional[str] = None + self, user_id: Snowflake, guild_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route("DELETE", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id) return self.request(r, reason=reason) def bulk_ban( - self, - user_ids: List[Snowflake], - guild_id: Snowflake, - *, - delete_message_seconds: int = 0, - reason: Optional[str] = None, + self, + user_ids: List[Snowflake], + guild_id: Snowflake, + *, + delete_message_seconds: int = 0, + reason: Optional[str] = None, ) -> Response[guild.BulkBanResult]: r = Route("POST", "/guilds/{guild_id}/bulk-ban", guild_id=guild_id) payload = { @@ -896,13 +896,13 @@ def get_guild_voice_regions(self, guild_id: Snowflake) -> Response[List[voice.Vo return self.request(Route("GET", "/guilds/{guild_id}/regions", guild_id=guild_id)) def guild_voice_state( - self, - user_id: Snowflake, - guild_id: Snowflake, - *, - mute: Optional[bool] = None, - deafen: Optional[bool] = None, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + *, + mute: Optional[bool] = None, + deafen: Optional[bool] = None, + reason: Optional[str] = None, ) -> Response[member.Member]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -920,12 +920,12 @@ def edit_profile(self, payload: Dict[str, Any]) -> Response[user.User]: return self.request(Route("PATCH", "/users/@me"), json=payload) def change_nickname( - self, - guild_id: Snowflake, - user_id: Snowflake, - nickname: str, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + nickname: str, + *, + reason: Optional[str] = None, ) -> Response[member.Member]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -940,7 +940,7 @@ def edit_my_voice_state(self, guild_id: Snowflake, payload: Dict[str, Any]) -> R return self.request(r, json=payload) def edit_voice_state( - self, guild_id: Snowflake, user_id: Snowflake, payload: Dict[str, Any] + self, guild_id: Snowflake, user_id: Snowflake, payload: Dict[str, Any] ) -> Response[None]: r = Route( "PATCH", "/guilds/{guild_id}/voice-states/{user_id}", guild_id=guild_id, user_id=user_id @@ -948,22 +948,22 @@ def edit_voice_state( return self.request(r, json=payload) def edit_my_member( - self, - guild_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[member.MemberWithUser]: r = Route("PATCH", "/guilds/{guild_id}/members/@me", guild_id=guild_id) return self.request(r, json=fields, reason=reason) def edit_member( - self, - guild_id: Snowflake, - user_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + user_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[member.MemberWithUser]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -973,11 +973,11 @@ def edit_member( # Channel management def edit_channel( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, - **options: Any, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, + **options: Any, ) -> Response[channel.Channel]: r = Route("PATCH", "/channels/{channel_id}", channel_id=channel_id) valid_keys = ( @@ -1010,22 +1010,22 @@ def edit_channel( return self.request(r, reason=reason, json=payload) def bulk_channel_update( - self, - guild_id: Snowflake, - data: List[guild.ChannelPositionUpdate], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + data: List[guild.ChannelPositionUpdate], + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route("PATCH", "/guilds/{guild_id}/channels", guild_id=guild_id) return self.request(r, json=data, reason=reason) def create_channel( - self, - guild_id: Snowflake, - channel_type: channel.ChannelType, - *, - reason: Optional[str] = None, - **options: Any, + self, + guild_id: Snowflake, + channel_type: channel.ChannelType, + *, + reason: Optional[str] = None, + **options: Any, ) -> Response[channel.GuildChannel]: payload = { "type": channel_type, @@ -1061,10 +1061,10 @@ def create_channel( ) def delete_channel( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: return self.request( Route("DELETE", "/channels/{channel_id}", channel_id=channel_id), reason=reason @@ -1073,14 +1073,14 @@ def delete_channel( # Thread management def start_thread_with_message( - self, - channel_id: Snowflake, - message_id: Snowflake, - *, - name: str, - auto_archive_duration: threads.ThreadArchiveDurationLiteral, - rate_limit_per_user: Optional[int] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + message_id: Snowflake, + *, + name: str, + auto_archive_duration: threads.ThreadArchiveDurationLiteral, + rate_limit_per_user: Optional[int] = None, + reason: Optional[str] = None, ) -> Response[threads.Thread]: payload = { "name": name, @@ -1099,15 +1099,15 @@ def start_thread_with_message( return self.request(route, json=payload, reason=reason) def start_thread_without_message( - self, - channel_id: Snowflake, - *, - name: str, - auto_archive_duration: threads.ThreadArchiveDurationLiteral, - type: threads.ThreadType, - invitable: bool = True, - rate_limit_per_user: Optional[int] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + name: str, + auto_archive_duration: threads.ThreadArchiveDurationLiteral, + type: threads.ThreadType, + invitable: bool = True, + rate_limit_per_user: Optional[int] = None, + reason: Optional[str] = None, ) -> Response[threads.Thread]: payload = { "name": name, @@ -1152,7 +1152,7 @@ def remove_user_from_thread(self, channel_id: Snowflake, user_id: Snowflake) -> return self.request(route) def get_public_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", "/channels/{channel_id}/threads/archived/public", channel_id=channel_id @@ -1165,7 +1165,7 @@ def get_public_archived_threads( return self.request(route, params=params) def get_private_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", "/channels/{channel_id}/threads/archived/private", channel_id=channel_id @@ -1178,7 +1178,7 @@ def get_private_archived_threads( return self.request(route, params=params) def get_joined_private_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", @@ -1196,7 +1196,7 @@ def get_active_threads(self, guild_id: Snowflake) -> Response[threads.ThreadPagi return self.request(route) def get_thread_member( - self, channel_id: Snowflake, user_id: Snowflake + self, channel_id: Snowflake, user_id: Snowflake ) -> Response[threads.ThreadMember]: route = Route( "GET", @@ -1211,11 +1211,11 @@ def get_thread_members(self, channel_id: Snowflake) -> Response[List[threads.Thr return self.request(route) def start_thread_in_forum_channel( - self, - channel_id: Snowflake, - files: Optional[Sequence[File]] = None, - reason: Optional[str] = None, - **fields: Any, + self, + channel_id: Snowflake, + files: Optional[Sequence[File]] = None, + reason: Optional[str] = None, + **fields: Any, ) -> Response[threads.ForumThread]: valid_thread_keys = ( "name", @@ -1253,12 +1253,12 @@ def start_thread_in_forum_channel( # Webhook management def create_webhook( - self, - channel_id: Snowflake, - *, - name: str, - avatar: Optional[str] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + name: str, + avatar: Optional[str] = None, + reason: Optional[str] = None, ) -> Response[webhook.Webhook]: payload: Dict[str, Any] = { "name": name, @@ -1279,10 +1279,10 @@ def get_webhook(self, webhook_id: Snowflake) -> Response[webhook.Webhook]: return self.request(Route("GET", "/webhooks/{webhook_id}", webhook_id=webhook_id)) def follow_webhook( - self, - channel_id: Snowflake, - webhook_channel_id: Snowflake, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + webhook_channel_id: Snowflake, + reason: Optional[str] = None, ) -> Response[None]: payload = { "webhook_channel_id": str(webhook_channel_id), @@ -1296,11 +1296,11 @@ def follow_webhook( # Guild management def get_guilds( - self, - limit: int, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - with_counts: bool = True, + self, + limit: int, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + with_counts: bool = True, ) -> Response[List[guild.Guild]]: params: Dict[str, Any] = { "limit": limit, @@ -1325,19 +1325,19 @@ def delete_guild(self, guild_id: Snowflake) -> Response[None]: return self.request(Route("DELETE", "/guilds/{guild_id}", guild_id=guild_id)) def create_guild( - self, - name: str, - icon: Optional[str] = None, - *, - verification_level: Optional[guild.VerificationLevel] = None, - default_message_notifications: Optional[guild.DefaultMessageNotificationLevel] = None, - explicit_content_filter: Optional[guild.ExplicitContentFilterLevel] = None, - roles: Optional[List[guild.CreateGuildPlaceholderRole]] = None, - channels: Optional[List[guild.CreateGuildPlaceholderChannel]] = None, - afk_channel: Optional[Snowflake] = None, - afk_timeout: Optional[int] = None, - system_channel: Optional[Snowflake] = None, - system_channel_flags: Optional[int] = None, + self, + name: str, + icon: Optional[str] = None, + *, + verification_level: Optional[guild.VerificationLevel] = None, + default_message_notifications: Optional[guild.DefaultMessageNotificationLevel] = None, + explicit_content_filter: Optional[guild.ExplicitContentFilterLevel] = None, + roles: Optional[List[guild.CreateGuildPlaceholderRole]] = None, + channels: Optional[List[guild.CreateGuildPlaceholderChannel]] = None, + afk_channel: Optional[Snowflake] = None, + afk_timeout: Optional[int] = None, + system_channel: Optional[Snowflake] = None, + system_channel_flags: Optional[int] = None, ) -> Response[guild.Guild]: payload: guild.CreateGuild = { "name": name, @@ -1366,7 +1366,7 @@ def create_guild( return self.request(Route("POST", "/guilds"), json=payload) def edit_guild( - self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any + self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any ) -> Response[guild.Guild]: valid_keys = ( "name", @@ -1404,7 +1404,7 @@ def guild_templates(self, guild_id: Snowflake) -> Response[List[template.Templat return self.request(Route("GET", "/guilds/{guild_id}/templates", guild_id=guild_id)) def create_template( - self, guild_id: Snowflake, payload: template.CreateTemplate + self, guild_id: Snowflake, payload: template.CreateTemplate ) -> Response[template.Template]: return self.request( Route("POST", "/guilds/{guild_id}/templates", guild_id=guild_id), json=payload @@ -1416,7 +1416,7 @@ def sync_template(self, guild_id: Snowflake, code: str) -> Response[template.Tem ) def edit_template( - self, guild_id: Snowflake, code: str, payload: Dict[str, Any] + self, guild_id: Snowflake, code: str, payload: Dict[str, Any] ) -> Response[template.Template]: valid_keys = ( "name", @@ -1434,7 +1434,7 @@ def delete_template(self, guild_id: Snowflake, code: str) -> Response[None]: ) def create_from_template( - self, code: str, name: str, icon: Optional[str] + self, code: str, name: str, icon: Optional[str] ) -> Response[guild.Guild]: payload = { "name": name, @@ -1447,11 +1447,11 @@ def get_guild_preview(self, guild_id: Snowflake) -> Response[guild.GuildPreview] return self.request(Route("GET", "/guilds/{guild_id}/preview", guild_id=guild_id)) def get_bans( - self, - guild_id: Snowflake, - limit: Optional[int] = None, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, + self, + guild_id: Snowflake, + limit: Optional[int] = None, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, ) -> Response[List[guild.Ban]]: params: Dict[str, Any] = {} @@ -1475,7 +1475,7 @@ def get_vanity_code(self, guild_id: Snowflake) -> Response[invite.VanityInvite]: return self.request(Route("GET", "/guilds/{guild_id}/vanity-url", guild_id=guild_id)) def change_vanity_code( - self, guild_id: Snowflake, code: str, *, reason: Optional[str] = None + self, guild_id: Snowflake, code: str, *, reason: Optional[str] = None ) -> Response[None]: payload: Dict[str, Any] = {"code": code} return self.request( @@ -1485,7 +1485,7 @@ def change_vanity_code( ) def edit_mfa_level( - self, guild_id: Snowflake, mfa_level: guild.MFALevel, *, reason: Optional[str] = None + self, guild_id: Snowflake, mfa_level: guild.MFALevel, *, reason: Optional[str] = None ) -> Response[guild.MFALevelUpdate]: payload: guild.MFALevelUpdate = {"level": mfa_level} return self.request( @@ -1498,7 +1498,7 @@ def get_all_guild_channels(self, guild_id: Snowflake) -> Response[List[guild.Gui return self.request(Route("GET", "/guilds/{guild_id}/channels", guild_id=guild_id)) def get_members( - self, guild_id: Snowflake, limit: int, after: Optional[Snowflake] + self, guild_id: Snowflake, limit: int, after: Optional[Snowflake] ) -> Response[List[member.MemberWithUser]]: params: Dict[str, Any] = { "limit": limit, @@ -1510,7 +1510,7 @@ def get_members( return self.request(r, params=params) def get_member( - self, guild_id: Snowflake, member_id: Snowflake + self, guild_id: Snowflake, member_id: Snowflake ) -> Response[member.MemberWithUser]: return self.request( Route( @@ -1522,13 +1522,13 @@ def get_member( ) def prune_members( - self, - guild_id: Snowflake, - days: int, - compute_prune_count: bool, - roles: List[str], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + days: int, + compute_prune_count: bool, + roles: List[str], + *, + reason: Optional[str] = None, ) -> Response[guild.GuildPrune]: payload: Dict[str, Any] = { "days": days, @@ -1544,10 +1544,10 @@ def prune_members( ) def estimate_pruned_members( - self, - guild_id: Snowflake, - days: int, - roles: List[str], + self, + guild_id: Snowflake, + days: int, + roles: List[str], ) -> Response[guild.GuildPrune]: params: Dict[str, Any] = { "days": days, @@ -1569,7 +1569,7 @@ def get_all_guild_stickers(self, guild_id: Snowflake) -> Response[List[sticker.G return self.request(Route("GET", "/guilds/{guild_id}/stickers", guild_id=guild_id)) def get_guild_sticker( - self, guild_id: Snowflake, sticker_id: Snowflake + self, guild_id: Snowflake, sticker_id: Snowflake ) -> Response[sticker.GuildSticker]: return self.request( Route( @@ -1581,12 +1581,12 @@ def get_guild_sticker( ) def create_guild_sticker( - self, - guild_id: Snowflake, - payload: sticker.CreateGuildSticker, - file: File, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + payload: sticker.CreateGuildSticker, + file: File, + *, + reason: Optional[str] = None, ) -> Response[sticker.GuildSticker]: initial_bytes = file.fp.read(16) @@ -1625,12 +1625,12 @@ def create_guild_sticker( ) def modify_guild_sticker( - self, - guild_id: Snowflake, - sticker_id: Snowflake, - payload: sticker.EditGuildSticker, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + sticker_id: Snowflake, + payload: sticker.EditGuildSticker, + *, + reason: Optional[str] = None, ) -> Response[sticker.GuildSticker]: return self.request( Route( @@ -1644,7 +1644,7 @@ def modify_guild_sticker( ) def delete_guild_sticker( - self, guild_id: Snowflake, sticker_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, sticker_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: return self.request( Route( @@ -1667,13 +1667,13 @@ def get_custom_emoji(self, guild_id: Snowflake, emoji_id: Snowflake) -> Response ) def create_custom_emoji( - self, - guild_id: Snowflake, - name: str, - image: str, - *, - roles: Optional[SnowflakeList] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + name: str, + image: str, + *, + roles: Optional[SnowflakeList] = None, + reason: Optional[str] = None, ) -> Response[emoji.Emoji]: payload: Dict[str, Any] = { "name": name, @@ -1685,11 +1685,11 @@ def create_custom_emoji( return self.request(r, json=payload, reason=reason) def delete_custom_emoji( - self, - guild_id: Snowflake, - emoji_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + emoji_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/emojis/{emoji_id}", guild_id=guild_id, emoji_id=emoji_id @@ -1709,13 +1709,70 @@ def edit_custom_emoji( ) return self.request(r, json=payload, reason=reason) + def get_all_application_emojis(self, application_id: Snowflake) -> Response[List[emoji.Emoji]]: + return self.request( + Route( + "GET","/applications/{application_id}/emojis", application_id=application_id + ) + ) + + def get_application_emoji(self, application_id: Snowflake, emoji_id: Snowflake) -> Response[emoji.Emoji]: + return self.request( + Route( + "GET", "/applications/{application_id}/emojis/{emoji_id}", application_id=application_id, emoji_id=emoji_id + ) + ) + + def create_application_emoji( + self, + application_id: Snowflake, + name: str, + image: str, + ) -> Response[emoji.Emoji]: + payload = { + "name": name, + "image": image + } + r = Route( + "POST", "/applications/{application_id}/emojis", application_id=application_id + ) + return self.request(r, json=payload) + + def delete_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + ) -> Response[None]: + r = Route( + "DELETE", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r) + + def edit_application_emoji( + self, + application_id: Snowflake, + emoji_id: Snowflake, + *, + payload: dict[str, Any], + ) -> Response[emoji.Emoji]: + r = Route( + "PATCH", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, + ) + return self.request(r, json=payload) + def get_all_integrations(self, guild_id: Snowflake) -> Response[List[integration.Integration]]: r = Route("GET", "/guilds/{guild_id}/integrations", guild_id=guild_id) return self.request(r) def create_integration( - self, guild_id: Snowflake, type: integration.IntegrationType, id: int + self, guild_id: Snowflake, type: integration.IntegrationType, id: int ) -> Response[None]: payload = { "type": type, @@ -1726,7 +1783,7 @@ def create_integration( return self.request(r, json=payload) def edit_integration( - self, guild_id: Snowflake, integration_id: Snowflake, **payload: Any + self, guild_id: Snowflake, integration_id: Snowflake, **payload: Any ) -> Response[None]: r = Route( "PATCH", @@ -1748,7 +1805,7 @@ def sync_integration(self, guild_id: Snowflake, integration_id: Snowflake) -> Re return self.request(r) def delete_integration( - self, guild_id: Snowflake, integration_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, integration_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -1760,14 +1817,14 @@ def delete_integration( return self.request(r, reason=reason) def get_audit_logs( - self, - guild_id: Snowflake, - limit: int = 100, - # only one of these two may be specified, otherwise `after` gets ignored - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - user_id: Optional[Snowflake] = None, - action_type: Optional[audit_log.AuditLogEvent] = None, + self, + guild_id: Snowflake, + limit: int = 100, + # only one of these two may be specified, otherwise `after` gets ignored + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + user_id: Optional[Snowflake] = None, + action_type: Optional[audit_log.AuditLogEvent] = None, ) -> Response[audit_log.AuditLog]: params: Dict[str, Any] = {"limit": limit} if before is not None: @@ -1789,7 +1846,7 @@ def get_widget_settings(self, guild_id: Snowflake) -> Response[widget.WidgetSett return self.request(Route("GET", "/guilds/{guild_id}/widget", guild_id=guild_id)) def edit_widget( - self, guild_id: Snowflake, payload: Dict[str, Any], *, reason: Optional[str] = None + self, guild_id: Snowflake, payload: Dict[str, Any], *, reason: Optional[str] = None ) -> Response[widget.WidgetSettings]: return self.request( Route("PATCH", "/guilds/{guild_id}/widget", guild_id=guild_id), @@ -1807,17 +1864,17 @@ def widget_image_url(self, guild_id: Snowflake, *, style: str) -> str: # Invite management def create_invite( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, - max_age: int = 0, - max_uses: int = 0, - temporary: bool = False, - unique: bool = True, - target_type: Optional[invite.InviteTargetType] = None, - target_user_id: Optional[Snowflake] = None, - target_application_id: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, + max_age: int = 0, + max_uses: int = 0, + temporary: bool = False, + unique: bool = True, + target_type: Optional[invite.InviteTargetType] = None, + target_user_id: Optional[Snowflake] = None, + target_application_id: Optional[Snowflake] = None, ) -> Response[invite.Invite]: r = Route("POST", "/channels/{channel_id}/invites", channel_id=channel_id) payload: Dict[str, Any] = { @@ -1839,12 +1896,12 @@ def create_invite( return self.request(r, reason=reason, json=payload) def get_invite( - self, - invite_id: str, - *, - with_counts: bool = True, - with_expiration: bool = True, - guild_scheduled_event_id: Optional[int] = None, + self, + invite_id: str, + *, + with_counts: bool = True, + with_expiration: bool = True, + guild_scheduled_event_id: Optional[int] = None, ) -> Response[invite.Invite]: params = { "with_counts": int(with_counts), @@ -1874,12 +1931,12 @@ def get_roles(self, guild_id: Snowflake) -> Response[List[role.Role]]: return self.request(Route("GET", "/guilds/{guild_id}/roles", guild_id=guild_id)) def edit_role( - self, - guild_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[role.Role]: r = Route("PATCH", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id) valid_keys = ( @@ -1896,7 +1953,7 @@ def edit_role( return self.request(r, json=payload, reason=reason) def delete_role( - self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id @@ -1904,38 +1961,38 @@ def delete_role( return self.request(r, reason=reason) def replace_roles( - self, - user_id: Snowflake, - guild_id: Snowflake, - role_ids: List[int], - *, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + role_ids: List[int], + *, + reason: Optional[str] = None, ) -> Response[member.MemberWithUser]: return self.edit_member(guild_id=guild_id, user_id=user_id, roles=role_ids, reason=reason) def create_role( - self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any + self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any ) -> Response[role.Role]: r = Route("POST", "/guilds/{guild_id}/roles", guild_id=guild_id) return self.request(r, json=fields, reason=reason) def move_role_position( - self, - guild_id: Snowflake, - positions: List[guild.RolePositionUpdate], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + positions: List[guild.RolePositionUpdate], + *, + reason: Optional[str] = None, ) -> Response[List[role.Role]]: r = Route("PATCH", "/guilds/{guild_id}/roles", guild_id=guild_id) return self.request(r, json=positions, reason=reason) def add_role( - self, - guild_id: Snowflake, - user_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "PUT", @@ -1947,12 +2004,12 @@ def add_role( return self.request(r, reason=reason) def remove_role( - self, - guild_id: Snowflake, - user_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "DELETE", @@ -1964,14 +2021,14 @@ def remove_role( return self.request(r, reason=reason) def edit_channel_permissions( - self, - channel_id: Snowflake, - target: Snowflake, - allow: int, - deny: int, - type: channel.OverwriteType, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + target: Snowflake, + allow: int, + deny: int, + type: channel.OverwriteType, + *, + reason: Optional[str] = None, ) -> Response[None]: payload = {"id": target, "allow": allow, "deny": deny, "type": type} r = Route( @@ -1983,7 +2040,7 @@ def edit_channel_permissions( return self.request(r, json=payload, reason=reason) def delete_channel_permissions( - self, channel_id: Snowflake, target: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, target: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -1996,12 +2053,12 @@ def delete_channel_permissions( # Voice management def move_member( - self, - user_id: Snowflake, - guild_id: Snowflake, - channel_id: Snowflake, - *, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + channel_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[member.MemberWithUser]: return self.edit_member( guild_id=guild_id, user_id=user_id, channel_id=channel_id, reason=reason @@ -2013,7 +2070,7 @@ def get_stage_instance(self, channel_id: Snowflake) -> Response[channel.StageIns return self.request(Route("GET", "/stage-instances/{channel_id}", channel_id=channel_id)) def create_stage_instance( - self, *, reason: Optional[str] = None, **payload: Any + self, *, reason: Optional[str] = None, **payload: Any ) -> Response[channel.StageInstance]: valid_keys = ( "channel_id", @@ -2027,7 +2084,7 @@ def create_stage_instance( return self.request(Route("POST", "/stage-instances"), json=payload, reason=reason) def edit_stage_instance( - self, channel_id: Snowflake, *, reason: Optional[str] = None, **payload: Any + self, channel_id: Snowflake, *, reason: Optional[str] = None, **payload: Any ) -> Response[None]: valid_keys = ( "topic", @@ -2042,7 +2099,7 @@ def edit_stage_instance( ) def delete_stage_instance( - self, channel_id: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: return self.request( Route("DELETE", "/stage-instances/{channel_id}", channel_id=channel_id), reason=reason @@ -2051,26 +2108,26 @@ def delete_stage_instance( # Scheduled event management def get_guild_scheduled_events( - self, guild_id: Snowflake, with_user_count: bool = False + self, guild_id: Snowflake, with_user_count: bool = False ) -> Response[List[guild_scheduled_event.GuildScheduledEvent]]: params = {"with_user_count": int(with_user_count)} r = Route("GET", "/guilds/{guild_id}/scheduled-events", guild_id=guild_id) return self.request(r, params=params) def create_guild_scheduled_event( - self, - guild_id: Snowflake, - *, - name: str, - privacy_level: int, - scheduled_start_time: str, - entity_type: int, - channel_id: Optional[Snowflake] = None, - entity_metadata: Optional[Dict[str, Any]] = None, - scheduled_end_time: Optional[str] = None, - description: Optional[str] = None, - image: Optional[str] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + *, + name: str, + privacy_level: int, + scheduled_start_time: str, + entity_type: int, + channel_id: Optional[Snowflake] = None, + entity_metadata: Optional[Dict[str, Any]] = None, + scheduled_end_time: Optional[str] = None, + description: Optional[str] = None, + image: Optional[str] = None, + reason: Optional[str] = None, ) -> Response[guild_scheduled_event.GuildScheduledEvent]: r = Route("POST", "/guilds/{guild_id}/scheduled-events", guild_id=guild_id) payload: Dict[str, Any] = { @@ -2098,7 +2155,7 @@ def create_guild_scheduled_event( return self.request(r, json=payload, reason=reason) def get_guild_scheduled_event( - self, guild_id: Snowflake, event_id: Snowflake, with_user_count: bool = False + self, guild_id: Snowflake, event_id: Snowflake, with_user_count: bool = False ) -> Response[guild_scheduled_event.GuildScheduledEvent]: params = {"with_user_count": int(with_user_count)} route = Route( @@ -2110,12 +2167,12 @@ def get_guild_scheduled_event( return self.request(route, params=params) def edit_guild_scheduled_event( - self, - guild_id: Snowflake, - event_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + event_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[guild_scheduled_event.GuildScheduledEvent]: route = Route( method="PATCH", @@ -2127,7 +2184,7 @@ def edit_guild_scheduled_event( return self.request(route, json=fields, reason=reason) def delete_guild_scheduled_event( - self, guild_id: Snowflake, event_id: Snowflake + self, guild_id: Snowflake, event_id: Snowflake ) -> Response[None]: route = Route( method="DELETE", @@ -2138,13 +2195,13 @@ def delete_guild_scheduled_event( return self.request(route) def get_guild_scheduled_event_users( - self, - guild_id: Snowflake, - event_id: Snowflake, - limit: Optional[int] = None, - with_member: Optional[bool] = None, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, + self, + guild_id: Snowflake, + event_id: Snowflake, + limit: Optional[int] = None, + with_member: Optional[bool] = None, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, ) -> Response[List[guild_scheduled_event.GuildScheduledEventUser]]: params: Dict[str, Any] = {} @@ -2171,17 +2228,17 @@ def get_guild_scheduled_event_users( # Welcome screens def get_guild_welcome_screen( - self, guild_id: Snowflake + self, guild_id: Snowflake ) -> Response[welcome_screen.WelcomeScreen]: r = Route("GET", "/guilds/{guild_id}/welcome-screen", guild_id=guild_id) return self.request(r) def edit_guild_welcome_screen( - self, - guild_id: Snowflake, - *, - reason: Optional[str] = None, - **kwargs: Any, + self, + guild_id: Snowflake, + *, + reason: Optional[str] = None, + **kwargs: Any, ) -> Response[welcome_screen.WelcomeScreen]: valid_keys = ( "enabled", @@ -2201,7 +2258,7 @@ def get_auto_moderation_rules(self, guild_id: Snowflake) -> Response[List[automo ) def get_auto_moderation_rule( - self, guild_id: Snowflake, rule_id: Snowflake + self, guild_id: Snowflake, rule_id: Snowflake ) -> Response[automod.AutoModRule]: return self.request( Route( @@ -2213,18 +2270,18 @@ def get_auto_moderation_rule( ) def create_auto_moderation_rule( - self, - guild_id: Snowflake, - *, - name: str, - event_type: automod.AutoModEventType, - trigger_type: automod.AutoModTriggerType, - actions: List[automod.AutoModAction], - trigger_metadata: Optional[automod.AutoModTriggerMetadata] = None, - enabled: Optional[bool] = None, - exempt_roles: Optional[SnowflakeList] = None, - exempt_channels: Optional[SnowflakeList] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + *, + name: str, + event_type: automod.AutoModEventType, + trigger_type: automod.AutoModTriggerType, + actions: List[automod.AutoModAction], + trigger_metadata: Optional[automod.AutoModTriggerMetadata] = None, + enabled: Optional[bool] = None, + exempt_roles: Optional[SnowflakeList] = None, + exempt_channels: Optional[SnowflakeList] = None, + reason: Optional[str] = None, ) -> Response[automod.AutoModRule]: payload: automod.CreateAutoModRule = { "name": name, @@ -2249,12 +2306,12 @@ def create_auto_moderation_rule( ) def edit_auto_moderation_rule( - self, - guild_id: Snowflake, - rule_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + rule_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[automod.AutoModRule]: return self.request( Route( @@ -2268,11 +2325,11 @@ def edit_auto_moderation_rule( ) def delete_auto_moderation_rule( - self, - guild_id: Snowflake, - rule_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + rule_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: return self.request( Route( @@ -2297,17 +2354,17 @@ def get_skus(self, application_id: Snowflake) -> Response[List[sku.SKU]]: ) def get_entitlements( - self, - application_id: Snowflake, - *, - # if both are specified, `after` takes priority and `before` gets ignored - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - limit: int = 100, - user_id: Optional[Snowflake] = None, - guild_id: Optional[Snowflake] = None, - sku_ids: Optional[SnowflakeList] = None, - exclude_ended: bool = False, + self, + application_id: Snowflake, + *, + # if both are specified, `after` takes priority and `before` gets ignored + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + limit: int = 100, + user_id: Optional[Snowflake] = None, + guild_id: Optional[Snowflake] = None, + sku_ids: Optional[SnowflakeList] = None, + exclude_ended: bool = False, ) -> Response[List[entitlement.Entitlement]]: params: Dict[str, Any] = { "limit": limit, @@ -2330,12 +2387,12 @@ def get_entitlements( return self.request(r, params=params) def create_test_entitlement( - self, - application_id: Snowflake, - sku_id: Snowflake, - owner_id: Snowflake, - *, - owner_type: Literal[1, 2], # 1: guild, 2: user + self, + application_id: Snowflake, + sku_id: Snowflake, + owner_id: Snowflake, + *, + owner_type: Literal[1, 2], # 1: guild, 2: user ) -> Response[entitlement.Entitlement]: payload: Dict[str, Any] = { "sku_id": sku_id, @@ -2350,9 +2407,9 @@ def create_test_entitlement( ) def delete_test_entitlement( - self, - application_id: Snowflake, - entitlement_id: Snowflake, + self, + application_id: Snowflake, + entitlement_id: Snowflake, ) -> Response[None]: return self.request( Route( @@ -2364,9 +2421,9 @@ def delete_test_entitlement( ) def consume_entitlement( - self, - application_id: Snowflake, - entitlement_id: Snowflake, + self, + application_id: Snowflake, + entitlement_id: Snowflake, ) -> Response[None]: return self.request( Route( @@ -2380,10 +2437,10 @@ def consume_entitlement( # Application commands (global) def get_global_commands( - self, - application_id: Snowflake, - *, - with_localizations: bool = True, + self, + application_id: Snowflake, + *, + with_localizations: bool = True, ) -> Response[List[interactions.ApplicationCommand]]: params: Dict[str, Any] = {} # the API currently interprets any non-empty value as truthy @@ -2396,7 +2453,7 @@ def get_global_commands( ) def get_global_command( - self, application_id: Snowflake, command_id: Snowflake + self, application_id: Snowflake, command_id: Snowflake ) -> Response[interactions.ApplicationCommand]: r = Route( "GET", @@ -2407,16 +2464,16 @@ def get_global_command( return self.request(r) def upsert_global_command( - self, application_id: Snowflake, payload: interactions.EditApplicationCommand + self, application_id: Snowflake, payload: interactions.EditApplicationCommand ) -> Response[interactions.ApplicationCommand]: r = Route("POST", "/applications/{application_id}/commands", application_id=application_id) return self.request(r, json=payload) def edit_global_command( - self, - application_id: Snowflake, - command_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + command_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "PATCH", @@ -2427,7 +2484,7 @@ def edit_global_command( return self.request(r, json=payload) def delete_global_command( - self, application_id: Snowflake, command_id: Snowflake + self, application_id: Snowflake, command_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -2438,7 +2495,7 @@ def delete_global_command( return self.request(r) def bulk_upsert_global_commands( - self, application_id: Snowflake, payload: List[interactions.EditApplicationCommand] + self, application_id: Snowflake, payload: List[interactions.EditApplicationCommand] ) -> Response[List[interactions.ApplicationCommand]]: r = Route("PUT", "/applications/{application_id}/commands", application_id=application_id) return self.request(r, json=payload) @@ -2446,11 +2503,11 @@ def bulk_upsert_global_commands( # Application commands (guild) def get_guild_commands( - self, - application_id: Snowflake, - guild_id: Snowflake, - *, - with_localizations: bool = True, + self, + application_id: Snowflake, + guild_id: Snowflake, + *, + with_localizations: bool = True, ) -> Response[List[interactions.ApplicationCommand]]: params: Dict[str, Any] = {} # the API currently interprets any non-empty value as truthy @@ -2466,10 +2523,10 @@ def get_guild_commands( return self.request(r, params=params) def get_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[interactions.ApplicationCommand]: r = Route( "GET", @@ -2481,10 +2538,10 @@ def get_guild_command( return self.request(r) def upsert_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + guild_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "POST", @@ -2495,11 +2552,11 @@ def upsert_guild_command( return self.request(r, json=payload) def edit_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "PATCH", @@ -2511,10 +2568,10 @@ def edit_guild_command( return self.request(r, json=payload) def delete_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[None]: r = Route( "DELETE", @@ -2526,10 +2583,10 @@ def delete_guild_command( return self.request(r) def bulk_upsert_guild_commands( - self, - application_id: Snowflake, - guild_id: Snowflake, - payload: List[interactions.EditApplicationCommand], + self, + application_id: Snowflake, + guild_id: Snowflake, + payload: List[interactions.EditApplicationCommand], ) -> Response[List[interactions.ApplicationCommand]]: r = Route( "PUT", @@ -2542,13 +2599,13 @@ def bulk_upsert_guild_commands( # Interaction responses def _edit_webhook_helper( - self, - route: Route, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + route: Route, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: # TODO: this does not work how it should (e.g. `embeds=[]` is ignored). # This method (or rather its calling methods) is completely unused, and hence likely untested @@ -2569,12 +2626,12 @@ def _edit_webhook_helper( return self.request(route, json=payload) def create_interaction_response( - self, - interaction_id: Snowflake, - token: str, - *, - type: InteractionResponseType, - data: Optional[interactions.InteractionCallbackData] = None, + self, + interaction_id: Snowflake, + token: str, + *, + type: InteractionResponseType, + data: Optional[interactions.InteractionCallbackData] = None, ) -> Response[None]: r = Route( "POST", @@ -2592,9 +2649,9 @@ def create_interaction_response( return self.request(r, json=payload) def get_original_interaction_response( - self, - application_id: Snowflake, - token: str, + self, + application_id: Snowflake, + token: str, ) -> Response[message.Message]: r = Route( "GET", @@ -2605,14 +2662,14 @@ def get_original_interaction_response( return self.request(r) def edit_original_interaction_response( - self, - application_id: Snowflake, - token: str, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + application_id: Snowflake, + token: str, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: r = Route( "PATCH", @@ -2630,7 +2687,7 @@ def edit_original_interaction_response( ) def delete_original_interaction_response( - self, application_id: Snowflake, token: str + self, application_id: Snowflake, token: str ) -> Response[None]: r = Route( "DELETE", @@ -2641,14 +2698,14 @@ def delete_original_interaction_response( return self.request(r) def create_followup_message( - self, - application_id: Snowflake, - token: str, - files: Optional[List[File]] = None, - content: Optional[str] = None, - tts: bool = False, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, + self, + application_id: Snowflake, + token: str, + files: Optional[List[File]] = None, + content: Optional[str] = None, + tts: bool = False, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, ) -> Response[message.Message]: r = Route( "POST", @@ -2668,15 +2725,15 @@ def create_followup_message( ) def edit_followup_message( - self, - application_id: Snowflake, - token: str, - message_id: Snowflake, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + application_id: Snowflake, + token: str, + message_id: Snowflake, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: r = Route( "PATCH", @@ -2695,7 +2752,7 @@ def edit_followup_message( ) def delete_followup_message( - self, application_id: Snowflake, token: str, message_id: Snowflake + self, application_id: Snowflake, token: str, message_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -2707,9 +2764,9 @@ def delete_followup_message( return self.request(r) def get_guild_application_command_permissions( - self, - application_id: Snowflake, - guild_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, ) -> Response[List[interactions.GuildApplicationCommandPermissions]]: r = Route( "GET", @@ -2720,10 +2777,10 @@ def get_guild_application_command_permissions( return self.request(r) def get_application_command_permissions( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[interactions.GuildApplicationCommandPermissions]: r = Route( "GET", @@ -2743,7 +2800,7 @@ def application_info(self) -> Response[appinfo.AppInfo]: return self.request(Route("GET", "/oauth2/applications/@me")) def get_application_role_connection_metadata_records( - self, application_id: Snowflake + self, application_id: Snowflake ) -> Response[List[application_role_connection.ApplicationRoleConnectionMetadata]]: return self.request( Route( @@ -2754,9 +2811,9 @@ def get_application_role_connection_metadata_records( ) def edit_application_role_connection_metadata_records( - self, - application_id: Snowflake, - records: Sequence[application_role_connection.ApplicationRoleConnectionMetadata], + self, + application_id: Snowflake, + records: Sequence[application_role_connection.ApplicationRoleConnectionMetadata], ) -> Response[List[application_role_connection.ApplicationRoleConnectionMetadata]]: return self.request( Route( @@ -2776,7 +2833,7 @@ async def get_gateway(self, *, encoding: str = "json", zlib: bool = True) -> str return self._format_gateway_url(data["url"], encoding=encoding, zlib=zlib) async def get_bot_gateway( - self, *, encoding: str = "json", zlib: bool = True + self, *, encoding: str = "json", zlib: bool = True ) -> Tuple[int, str, gateway.SessionStartLimit]: try: data: gateway.GatewayBot = await self.request(Route("GET", "/gateway/bot")) diff --git a/disnake/state.py b/disnake/state.py index f4885513d7..5a53d14328 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -44,7 +44,7 @@ VoiceChannel, _guild_channel_factory, ) -from .emoji import Emoji +from .emoji import ApplicationEmoji, Emoji, GuildEmoji from .entitlement import Entitlement from .enums import ApplicationCommandType, ChannelType, ComponentType, MessageType, Status, try_enum from .flags import ApplicationFlags, Intents, MemberCacheFlags @@ -204,6 +204,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.http: HTTPClient = http @@ -277,6 +278,8 @@ def __init__( if not self._intents.members or member_cache_flags._empty: self.store_user = self.create_user + self.cache_app_emojis: bool = cache_app_emojis + self.parsers = parsers = {} for attr, func in inspect.getmembers(self): if attr.startswith("parse_"): @@ -293,7 +296,7 @@ def clear( # - the weakref slot + object in user objects likely results in a small increase in memory usage # - accesses on `_users` are slower, e.g. `__getitem__` takes ~1us with weakrefs and ~0.2us without self._users: weakref.WeakValueDictionary[int, User] = weakref.WeakValueDictionary() - self._emojis: Dict[int, Emoji] = {} + self._emojis: Dict[int, Emoji, ApplicationEmoji] = {} self._stickers: Dict[int, GuildSticker] = {} self._guilds: Dict[int, Guild] = {} @@ -394,10 +397,19 @@ def get_user(self, id: Optional[int]) -> Optional[User]: # the keys of self._users are ints return self._users.get(id) # type: ignore - def store_emoji(self, guild: Guild, data: EmojiPayload) -> Emoji: + def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: # the id will be present here emoji_id = int(data["id"]) # type: ignore - self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data) + self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) + return emoji + + def store_application_emoji( + self, application_id: int, data: EmojiPayload + ) -> ApplicationEmoji: + emoji = ApplicationEmoji(application_id=application_id, state=self, data=data) + if self.cache_app_emojis: + emoji_id = int(data["id"]) # type: ignore + self._emojis[emoji_id] = emoji return emoji def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: @@ -435,7 +447,7 @@ def _remove_guild(self, guild: Guild) -> None: self._guilds.pop(guild.id, None) for emoji in guild.emojis: - self._emojis.pop(emoji.id, None) + self._remove_emoji(emoji.id) for sticker in guild.stickers: self._stickers.pop(sticker.id, None) @@ -508,17 +520,20 @@ def _get_guild_command_named( return cmd @property - def emojis(self) -> List[Emoji]: + def emojis(self) -> List[GuildEmoji | ApplicationEmoji]: return list(self._emojis.values()) @property def stickers(self) -> List[GuildSticker]: return list(self._stickers.values()) - def get_emoji(self, emoji_id: Optional[int]) -> Optional[Emoji]: + def get_emoji(self, emoji_id: Optional[int]) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: # the keys of self._emojis are ints return self._emojis.get(emoji_id) # type: ignore + def _remove_emoji(self, emoji: GuildEmoji | ApplicationEmoji) -> None: + self._emojis.pop(emoji.id, None) + def get_sticker(self, sticker_id: Optional[int]) -> Optional[GuildSticker]: # the keys of self._stickers are ints return self._stickers.get(sticker_id) # type: ignore @@ -2273,6 +2288,11 @@ async def _delay_ready(self) -> None: self.dispatch("shard_ready", shard_id) + if self.cache_app_emojis and self.application_id: + data = await self.http.get_all_application_emojis(self.application_id) + for e in data.get("items", []): + self.store_application_emoji(self.application_id, e) + # remove the state try: del self._ready_state From 0a86e6b14d2b9d89844d6c48a6b6e347bb9dbc4e Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 17:16:56 +0800 Subject: [PATCH 02/15] style: use pdm lint --- disnake/client.py | 36 +- disnake/emoji.py | 34 +- disnake/http.py | 1046 ++++++++++++++++++++++----------------------- disnake/state.py | 10 +- 4 files changed, 552 insertions(+), 574 deletions(-) diff --git a/disnake/client.py b/disnake/client.py index c6735a32bc..6a8f92e2e4 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -445,7 +445,7 @@ def __init__( intents=intents, chunk_guilds_at_startup=chunk_guilds_at_startup, member_cache_flags=member_cache_flags, - cache_app_emojis=cache_app_emojis + cache_app_emojis=cache_app_emojis, ) self.shard_id: Optional[int] = shard_id self.shard_count: Optional[int] = shard_count @@ -500,7 +500,7 @@ def _get_state( status: Optional[Union[str, Status]], intents: Optional[Intents], chunk_guilds_at_startup: Optional[bool], - member_cache_flags: Optional[MemberCacheFlags] + member_cache_flags: Optional[MemberCacheFlags], ) -> ConnectionState: return ConnectionState( dispatch=self.dispatch, @@ -518,7 +518,7 @@ def _get_state( intents=intents, chunk_guilds_at_startup=chunk_guilds_at_startup, member_cache_flags=member_cache_flags, - cache_app_emojis=cache_app_emojis + cache_app_emojis=cache_app_emojis, ) def _handle_ready(self) -> None: @@ -563,13 +563,12 @@ def guilds(self) -> List[Guild]: return self._connection.guilds @property - def emojis(self) -> list[GuildEmoji | ApplicationEmoji]: + def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: """The emojis that the connected client has. .. note:: - - This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is -``True``. + This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is + ``True``. """ return self._connection.emojis @@ -3227,19 +3226,18 @@ async def fetch_application_emojis(self) -> list[ApplicationEmoji]: Retrieves all custom :class:`ApplicationEmoji`\s from the application. Raises - --------- + ------ HTTPException An error occurred fetching the emojis. Returns - -------- + ------- List[:class:`ApplicationEmoji`] The retrieved emojis. """ data = await self._connection.http.get_all_application_emojis(self.application_id) return [ - self._connection.store_application_emoji(self.application_id, d) - for d in data["items"] + self._connection.store_application_emoji(self.application_id, d) for d in data["items"] ] async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: @@ -3263,9 +3261,7 @@ async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: HTTPException An error occurred fetching the emoji. """ - data = await self._connection.http.get_application_emoji( - self.application_id, emoji_id - ) + data = await self._connection.http.get_application_emoji(self.application_id, emoji_id) return self._connection.store_application_emoji(self.application_id, data) async def create_application_emoji( @@ -3279,7 +3275,7 @@ async def create_application_emoji( There is currently a limit of 2000 emojis per application. Parameters - ----------- + ---------- name: :class:`str` The emoji name. Must be at least 2 characters. image: :class:`bytes` @@ -3287,21 +3283,17 @@ async def create_application_emoji( Only JPG, PNG and GIF images are supported. Raises - ------- + ------ Forbidden You are not allowed to create emojis. HTTPException An error occurred creating an emoji. Returns - -------- + ------- :class:`ApplicationEmoji` The created emoji. """ - img = utils._bytes_to_base64_data(image) - data = await self._connection.http.create_application_emoji( - self.application_id, name, img - ) + data = await self._connection.http.create_application_emoji(self.application_id, name, img) return self._connection.store_application_emoji(self.application_id, data) - diff --git a/disnake/emoji.py b/disnake/emoji.py index 3b5f611fbf..0c39fa3f1b 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -2,18 +2,14 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple from .asset import Asset, AssetMixin from .partial_emoji import PartialEmoji, _EmojiTag from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ( - "Emoji", - "GuildEmoji", - "ApplicationEmoji" -) +__all__ = ("Emoji", "GuildEmoji", "ApplicationEmoji") if TYPE_CHECKING: from datetime import datetime @@ -89,9 +85,7 @@ class BaseEmoji(_EmojiTag, AssetMixin): "available", ) - def __init__( - self, *, state: ConnectionState, data: EmojiPayload - ) -> None: + def __init__(self, *, state: ConnectionState, data: EmojiPayload) -> None: self._state: ConnectionState = state self._from_data(data) @@ -261,7 +255,7 @@ async def delete(self, *, reason: Optional[str] = None) -> None: await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) async def edit( - self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None + self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None ) -> GuildEmoji: """|coro| @@ -362,9 +356,7 @@ class ApplicationEmoji(BaseEmoji): The user that created the emoji. """ - def __init__( - self, *, application_id: int, state: ConnectionState, data: EmojiPayload - ): + def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload): self.application_id: int = application_id super().__init__(state=state, data=data) @@ -387,38 +379,36 @@ async def delete(self) -> None: HTTPException An error occurred deleting the emoji. """ - await self._state.http.delete_application_emoji(self.application_id, self.id) if self._state.cache_app_emojis and self._state.get_emoji(self.id): self._state._remove_emoji(self) async def edit( - self, - *, - name: str = MISSING, + self, + *, + name: str = MISSING, ) -> ApplicationEmoji: r"""|coro| Edits the application emoji. You must own the emoji to do this. Parameters - ----------- + ---------- name: :class:`str` The new emoji name. Raises - ------- + ------ Forbidden You are not allowed to edit the emoji. HTTPException An error occurred editing the emoji. Returns - -------- + ------- :class:`ApplicationEmoji` The newly updated emoji. """ - payload = {} if name is not MISSING: payload["name"] = name @@ -426,4 +416,4 @@ async def edit( data = await self._state.http.edit_application_emoji( self.application_id, self.id, payload=payload ) - return self._state.store_application_emoji(self.application_id, data) \ No newline at end of file + return self._state.store_application_emoji(self.application_id, data) diff --git a/disnake/http.py b/disnake/http.py index bfd34156ec..fd760859de 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -155,7 +155,7 @@ def to_multipart(payload: Dict[str, Any], files: Sequence[File]) -> List[Dict[st def to_multipart_with_attachments( - payload: Dict[str, Any], files: Sequence[File] + payload: Dict[str, Any], files: Sequence[File] ) -> List[Dict[str, Any]]: """Updates the payload's attachments and converts it to a multipart payload @@ -202,10 +202,10 @@ def defer(self) -> None: self._unlock = False def __exit__( - self, - exc_type: Optional[Type[BaseException]], - exc: Optional[BaseException], - traceback: Optional[TracebackType], + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + traceback: Optional[TracebackType], ) -> None: if self._unlock: self.lock.release() @@ -220,13 +220,13 @@ class HTTPClient: """Represents an HTTP client sending HTTP requests to the Discord API.""" def __init__( - self, - connector: Optional[aiohttp.BaseConnector] = None, - *, - loop: asyncio.AbstractEventLoop, - proxy: Optional[str] = None, - proxy_auth: Optional[aiohttp.BasicAuth] = None, - unsync_clock: bool = True, + self, + connector: Optional[aiohttp.BaseConnector] = None, + *, + loop: asyncio.AbstractEventLoop, + proxy: Optional[str] = None, + proxy_auth: Optional[aiohttp.BasicAuth] = None, + unsync_clock: bool = True, ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.connector = connector @@ -264,12 +264,12 @@ async def ws_connect(self, url: str, *, compress: int = 0) -> aiohttp.ClientWebS ) async def request( - self, - route: Route, - *, - files: Optional[Sequence[File]] = None, - form: Optional[Iterable[Dict[str, Any]]] = None, - **kwargs: Any, + self, + route: Route, + *, + files: Optional[Sequence[File]] = None, + form: Optional[Iterable[Dict[str, Any]]] = None, + **kwargs: Any, ) -> Any: bucket = route.bucket method = route.method @@ -468,13 +468,13 @@ async def static_login(self, token: str) -> user.User: return data def create_party( - self, - channel_id: Snowflake, - max_age: int, - max_uses: int, - target_application_id: Snowflake, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + max_age: int, + max_uses: int, + target_application_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[invite.Invite]: payload = { "max_age": max_age, @@ -493,7 +493,7 @@ def create_party( # Group functionality def start_group( - self, user_id: Snowflake, recipients: List[int] + self, user_id: Snowflake, recipients: List[int] ) -> Response[channel.GroupDMChannel]: payload = { "recipients": recipients, @@ -516,19 +516,19 @@ def start_private_message(self, user_id: Snowflake) -> Response[channel.DMChanne return self.request(Route("POST", "/users/@me/channels"), json=payload) def send_message( - self, - channel_id: Snowflake, - content: Optional[str], - *, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + channel_id: Snowflake, + content: Optional[str], + *, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) payload: Dict[str, Any] = {} @@ -569,20 +569,20 @@ def send_typing(self, channel_id: Snowflake) -> Response[None]: return self.request(Route("POST", "/channels/{channel_id}/typing", channel_id=channel_id)) def send_multipart_helper( - self, - route: Route, - *, - files: Sequence[File], - content: Optional[str] = None, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + route: Route, + *, + files: Sequence[File], + content: Optional[str] = None, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: payload: Dict[str, Any] = {"tts": tts} if content: @@ -609,20 +609,20 @@ def send_multipart_helper( return self.request(route, form=multipart, files=files) def send_files( - self, - channel_id: Snowflake, - *, - files: Sequence[File], - content: Optional[str] = None, - tts: bool = False, - embed: Optional[embed.Embed] = None, - embeds: Optional[List[embed.Embed]] = None, - nonce: Optional[Union[str, int]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - message_reference: Optional[message.MessageReference] = None, - stickers: Optional[Sequence[Snowflake]] = None, - components: Optional[Sequence[components.Component]] = None, - flags: Optional[int] = None, + self, + channel_id: Snowflake, + *, + files: Sequence[File], + content: Optional[str] = None, + tts: bool = False, + embed: Optional[embed.Embed] = None, + embeds: Optional[List[embed.Embed]] = None, + nonce: Optional[Union[str, int]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + message_reference: Optional[message.MessageReference] = None, + stickers: Optional[Sequence[Snowflake]] = None, + components: Optional[Sequence[components.Component]] = None, + flags: Optional[int] = None, ) -> Response[message.Message]: r = Route("POST", "/channels/{channel_id}/messages", channel_id=channel_id) return self.send_multipart_helper( @@ -641,7 +641,7 @@ def send_files( ) def delete_message( - self, channel_id: Snowflake, message_id: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -652,7 +652,7 @@ def delete_message( return self.request(r, reason=reason) def delete_messages( - self, channel_id: Snowflake, message_ids: SnowflakeList, *, reason: Optional[str] = None + self, channel_id: Snowflake, message_ids: SnowflakeList, *, reason: Optional[str] = None ) -> Response[None]: r = Route("POST", "/channels/{channel_id}/messages/bulk-delete", channel_id=channel_id) payload = { @@ -662,12 +662,12 @@ def delete_messages( return self.request(r, json=payload, reason=reason) def edit_message( - self, - channel_id: Snowflake, - message_id: Snowflake, - *, - files: Optional[List[File]] = None, - **fields: Any, + self, + channel_id: Snowflake, + message_id: Snowflake, + *, + files: Optional[List[File]] = None, + **fields: Any, ) -> Response[message.Message]: r = Route( "PATCH", @@ -681,7 +681,7 @@ def edit_message( return self.request(r, json=fields) def add_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "PUT", @@ -693,7 +693,7 @@ def add_reaction( return self.request(r) def remove_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str, member_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake, emoji: str, member_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -706,7 +706,7 @@ def remove_reaction( return self.request(r) def remove_own_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "DELETE", @@ -718,12 +718,12 @@ def remove_own_reaction( return self.request(r) def get_reaction_users( - self, - channel_id: Snowflake, - message_id: Snowflake, - emoji: str, - limit: int, - after: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + message_id: Snowflake, + emoji: str, + limit: int, + after: Optional[Snowflake] = None, ) -> Response[List[user.User]]: r = Route( "GET", @@ -751,7 +751,7 @@ def clear_reactions(self, channel_id: Snowflake, message_id: Snowflake) -> Respo return self.request(r) def clear_single_reaction( - self, channel_id: Snowflake, message_id: Snowflake, emoji: str + self, channel_id: Snowflake, message_id: Snowflake, emoji: str ) -> Response[None]: r = Route( "DELETE", @@ -763,7 +763,7 @@ def clear_single_reaction( return self.request(r) def get_message( - self, channel_id: Snowflake, message_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake ) -> Response[message.Message]: r = Route( "GET", @@ -778,12 +778,12 @@ def get_channel(self, channel_id: Snowflake) -> Response[channel.Channel]: return self.request(r) def logs_from( - self, - channel_id: Snowflake, - limit: int, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - around: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + limit: int, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + around: Optional[Snowflake] = None, ) -> Response[List[message.Message]]: params: Dict[str, Any] = { "limit": limit, @@ -801,7 +801,7 @@ def logs_from( ) def publish_message( - self, channel_id: Snowflake, message_id: Snowflake + self, channel_id: Snowflake, message_id: Snowflake ) -> Response[message.Message]: return self.request( Route( @@ -813,7 +813,7 @@ def publish_message( ) def pin_message( - self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "PUT", @@ -824,7 +824,7 @@ def pin_message( return self.request(r, reason=reason) def unpin_message( - self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None + self, channel_id: Snowflake, message_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -840,14 +840,14 @@ def pins_from(self, channel_id: Snowflake) -> Response[List[message.Message]]: # Member management def search_guild_members( - self, guild_id: Snowflake, query: str, limit: int = 1 + self, guild_id: Snowflake, query: str, limit: int = 1 ) -> Response[List[member.MemberWithUser]]: r = Route("GET", "/guilds/{guild_id}/members/search", guild_id=guild_id) return self.request(r, params={"query": query, "limit": limit}) def kick( - self, user_id: Snowflake, guild_id: Snowflake, reason: Optional[str] = None + self, user_id: Snowflake, guild_id: Snowflake, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -856,12 +856,12 @@ def kick( return self.request(r, reason=reason) def ban( - self, - user_id: Snowflake, - guild_id: Snowflake, - *, - delete_message_seconds: int = 86400, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + *, + delete_message_seconds: int = 86400, + reason: Optional[str] = None, ) -> Response[None]: r = Route("PUT", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id) payload = { @@ -871,18 +871,18 @@ def ban( return self.request(r, json=payload, reason=reason) def unban( - self, user_id: Snowflake, guild_id: Snowflake, *, reason: Optional[str] = None + self, user_id: Snowflake, guild_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route("DELETE", "/guilds/{guild_id}/bans/{user_id}", guild_id=guild_id, user_id=user_id) return self.request(r, reason=reason) def bulk_ban( - self, - user_ids: List[Snowflake], - guild_id: Snowflake, - *, - delete_message_seconds: int = 0, - reason: Optional[str] = None, + self, + user_ids: List[Snowflake], + guild_id: Snowflake, + *, + delete_message_seconds: int = 0, + reason: Optional[str] = None, ) -> Response[guild.BulkBanResult]: r = Route("POST", "/guilds/{guild_id}/bulk-ban", guild_id=guild_id) payload = { @@ -896,13 +896,13 @@ def get_guild_voice_regions(self, guild_id: Snowflake) -> Response[List[voice.Vo return self.request(Route("GET", "/guilds/{guild_id}/regions", guild_id=guild_id)) def guild_voice_state( - self, - user_id: Snowflake, - guild_id: Snowflake, - *, - mute: Optional[bool] = None, - deafen: Optional[bool] = None, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + *, + mute: Optional[bool] = None, + deafen: Optional[bool] = None, + reason: Optional[str] = None, ) -> Response[member.Member]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -920,12 +920,12 @@ def edit_profile(self, payload: Dict[str, Any]) -> Response[user.User]: return self.request(Route("PATCH", "/users/@me"), json=payload) def change_nickname( - self, - guild_id: Snowflake, - user_id: Snowflake, - nickname: str, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + nickname: str, + *, + reason: Optional[str] = None, ) -> Response[member.Member]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -940,7 +940,7 @@ def edit_my_voice_state(self, guild_id: Snowflake, payload: Dict[str, Any]) -> R return self.request(r, json=payload) def edit_voice_state( - self, guild_id: Snowflake, user_id: Snowflake, payload: Dict[str, Any] + self, guild_id: Snowflake, user_id: Snowflake, payload: Dict[str, Any] ) -> Response[None]: r = Route( "PATCH", "/guilds/{guild_id}/voice-states/{user_id}", guild_id=guild_id, user_id=user_id @@ -948,22 +948,22 @@ def edit_voice_state( return self.request(r, json=payload) def edit_my_member( - self, - guild_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[member.MemberWithUser]: r = Route("PATCH", "/guilds/{guild_id}/members/@me", guild_id=guild_id) return self.request(r, json=fields, reason=reason) def edit_member( - self, - guild_id: Snowflake, - user_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + user_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[member.MemberWithUser]: r = Route( "PATCH", "/guilds/{guild_id}/members/{user_id}", guild_id=guild_id, user_id=user_id @@ -973,11 +973,11 @@ def edit_member( # Channel management def edit_channel( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, - **options: Any, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, + **options: Any, ) -> Response[channel.Channel]: r = Route("PATCH", "/channels/{channel_id}", channel_id=channel_id) valid_keys = ( @@ -1010,22 +1010,22 @@ def edit_channel( return self.request(r, reason=reason, json=payload) def bulk_channel_update( - self, - guild_id: Snowflake, - data: List[guild.ChannelPositionUpdate], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + data: List[guild.ChannelPositionUpdate], + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route("PATCH", "/guilds/{guild_id}/channels", guild_id=guild_id) return self.request(r, json=data, reason=reason) def create_channel( - self, - guild_id: Snowflake, - channel_type: channel.ChannelType, - *, - reason: Optional[str] = None, - **options: Any, + self, + guild_id: Snowflake, + channel_type: channel.ChannelType, + *, + reason: Optional[str] = None, + **options: Any, ) -> Response[channel.GuildChannel]: payload = { "type": channel_type, @@ -1061,10 +1061,10 @@ def create_channel( ) def delete_channel( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: return self.request( Route("DELETE", "/channels/{channel_id}", channel_id=channel_id), reason=reason @@ -1073,14 +1073,14 @@ def delete_channel( # Thread management def start_thread_with_message( - self, - channel_id: Snowflake, - message_id: Snowflake, - *, - name: str, - auto_archive_duration: threads.ThreadArchiveDurationLiteral, - rate_limit_per_user: Optional[int] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + message_id: Snowflake, + *, + name: str, + auto_archive_duration: threads.ThreadArchiveDurationLiteral, + rate_limit_per_user: Optional[int] = None, + reason: Optional[str] = None, ) -> Response[threads.Thread]: payload = { "name": name, @@ -1099,15 +1099,15 @@ def start_thread_with_message( return self.request(route, json=payload, reason=reason) def start_thread_without_message( - self, - channel_id: Snowflake, - *, - name: str, - auto_archive_duration: threads.ThreadArchiveDurationLiteral, - type: threads.ThreadType, - invitable: bool = True, - rate_limit_per_user: Optional[int] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + name: str, + auto_archive_duration: threads.ThreadArchiveDurationLiteral, + type: threads.ThreadType, + invitable: bool = True, + rate_limit_per_user: Optional[int] = None, + reason: Optional[str] = None, ) -> Response[threads.Thread]: payload = { "name": name, @@ -1152,7 +1152,7 @@ def remove_user_from_thread(self, channel_id: Snowflake, user_id: Snowflake) -> return self.request(route) def get_public_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", "/channels/{channel_id}/threads/archived/public", channel_id=channel_id @@ -1165,7 +1165,7 @@ def get_public_archived_threads( return self.request(route, params=params) def get_private_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", "/channels/{channel_id}/threads/archived/private", channel_id=channel_id @@ -1178,7 +1178,7 @@ def get_private_archived_threads( return self.request(route, params=params) def get_joined_private_archived_threads( - self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 + self, channel_id: Snowflake, before: Optional[Snowflake] = None, limit: int = 50 ) -> Response[threads.ThreadPaginationPayload]: route = Route( "GET", @@ -1196,7 +1196,7 @@ def get_active_threads(self, guild_id: Snowflake) -> Response[threads.ThreadPagi return self.request(route) def get_thread_member( - self, channel_id: Snowflake, user_id: Snowflake + self, channel_id: Snowflake, user_id: Snowflake ) -> Response[threads.ThreadMember]: route = Route( "GET", @@ -1211,11 +1211,11 @@ def get_thread_members(self, channel_id: Snowflake) -> Response[List[threads.Thr return self.request(route) def start_thread_in_forum_channel( - self, - channel_id: Snowflake, - files: Optional[Sequence[File]] = None, - reason: Optional[str] = None, - **fields: Any, + self, + channel_id: Snowflake, + files: Optional[Sequence[File]] = None, + reason: Optional[str] = None, + **fields: Any, ) -> Response[threads.ForumThread]: valid_thread_keys = ( "name", @@ -1253,12 +1253,12 @@ def start_thread_in_forum_channel( # Webhook management def create_webhook( - self, - channel_id: Snowflake, - *, - name: str, - avatar: Optional[str] = None, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + *, + name: str, + avatar: Optional[str] = None, + reason: Optional[str] = None, ) -> Response[webhook.Webhook]: payload: Dict[str, Any] = { "name": name, @@ -1279,10 +1279,10 @@ def get_webhook(self, webhook_id: Snowflake) -> Response[webhook.Webhook]: return self.request(Route("GET", "/webhooks/{webhook_id}", webhook_id=webhook_id)) def follow_webhook( - self, - channel_id: Snowflake, - webhook_channel_id: Snowflake, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + webhook_channel_id: Snowflake, + reason: Optional[str] = None, ) -> Response[None]: payload = { "webhook_channel_id": str(webhook_channel_id), @@ -1296,11 +1296,11 @@ def follow_webhook( # Guild management def get_guilds( - self, - limit: int, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - with_counts: bool = True, + self, + limit: int, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + with_counts: bool = True, ) -> Response[List[guild.Guild]]: params: Dict[str, Any] = { "limit": limit, @@ -1325,19 +1325,19 @@ def delete_guild(self, guild_id: Snowflake) -> Response[None]: return self.request(Route("DELETE", "/guilds/{guild_id}", guild_id=guild_id)) def create_guild( - self, - name: str, - icon: Optional[str] = None, - *, - verification_level: Optional[guild.VerificationLevel] = None, - default_message_notifications: Optional[guild.DefaultMessageNotificationLevel] = None, - explicit_content_filter: Optional[guild.ExplicitContentFilterLevel] = None, - roles: Optional[List[guild.CreateGuildPlaceholderRole]] = None, - channels: Optional[List[guild.CreateGuildPlaceholderChannel]] = None, - afk_channel: Optional[Snowflake] = None, - afk_timeout: Optional[int] = None, - system_channel: Optional[Snowflake] = None, - system_channel_flags: Optional[int] = None, + self, + name: str, + icon: Optional[str] = None, + *, + verification_level: Optional[guild.VerificationLevel] = None, + default_message_notifications: Optional[guild.DefaultMessageNotificationLevel] = None, + explicit_content_filter: Optional[guild.ExplicitContentFilterLevel] = None, + roles: Optional[List[guild.CreateGuildPlaceholderRole]] = None, + channels: Optional[List[guild.CreateGuildPlaceholderChannel]] = None, + afk_channel: Optional[Snowflake] = None, + afk_timeout: Optional[int] = None, + system_channel: Optional[Snowflake] = None, + system_channel_flags: Optional[int] = None, ) -> Response[guild.Guild]: payload: guild.CreateGuild = { "name": name, @@ -1366,7 +1366,7 @@ def create_guild( return self.request(Route("POST", "/guilds"), json=payload) def edit_guild( - self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any + self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any ) -> Response[guild.Guild]: valid_keys = ( "name", @@ -1404,7 +1404,7 @@ def guild_templates(self, guild_id: Snowflake) -> Response[List[template.Templat return self.request(Route("GET", "/guilds/{guild_id}/templates", guild_id=guild_id)) def create_template( - self, guild_id: Snowflake, payload: template.CreateTemplate + self, guild_id: Snowflake, payload: template.CreateTemplate ) -> Response[template.Template]: return self.request( Route("POST", "/guilds/{guild_id}/templates", guild_id=guild_id), json=payload @@ -1416,7 +1416,7 @@ def sync_template(self, guild_id: Snowflake, code: str) -> Response[template.Tem ) def edit_template( - self, guild_id: Snowflake, code: str, payload: Dict[str, Any] + self, guild_id: Snowflake, code: str, payload: Dict[str, Any] ) -> Response[template.Template]: valid_keys = ( "name", @@ -1434,7 +1434,7 @@ def delete_template(self, guild_id: Snowflake, code: str) -> Response[None]: ) def create_from_template( - self, code: str, name: str, icon: Optional[str] + self, code: str, name: str, icon: Optional[str] ) -> Response[guild.Guild]: payload = { "name": name, @@ -1447,11 +1447,11 @@ def get_guild_preview(self, guild_id: Snowflake) -> Response[guild.GuildPreview] return self.request(Route("GET", "/guilds/{guild_id}/preview", guild_id=guild_id)) def get_bans( - self, - guild_id: Snowflake, - limit: Optional[int] = None, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, + self, + guild_id: Snowflake, + limit: Optional[int] = None, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, ) -> Response[List[guild.Ban]]: params: Dict[str, Any] = {} @@ -1475,7 +1475,7 @@ def get_vanity_code(self, guild_id: Snowflake) -> Response[invite.VanityInvite]: return self.request(Route("GET", "/guilds/{guild_id}/vanity-url", guild_id=guild_id)) def change_vanity_code( - self, guild_id: Snowflake, code: str, *, reason: Optional[str] = None + self, guild_id: Snowflake, code: str, *, reason: Optional[str] = None ) -> Response[None]: payload: Dict[str, Any] = {"code": code} return self.request( @@ -1485,7 +1485,7 @@ def change_vanity_code( ) def edit_mfa_level( - self, guild_id: Snowflake, mfa_level: guild.MFALevel, *, reason: Optional[str] = None + self, guild_id: Snowflake, mfa_level: guild.MFALevel, *, reason: Optional[str] = None ) -> Response[guild.MFALevelUpdate]: payload: guild.MFALevelUpdate = {"level": mfa_level} return self.request( @@ -1498,7 +1498,7 @@ def get_all_guild_channels(self, guild_id: Snowflake) -> Response[List[guild.Gui return self.request(Route("GET", "/guilds/{guild_id}/channels", guild_id=guild_id)) def get_members( - self, guild_id: Snowflake, limit: int, after: Optional[Snowflake] + self, guild_id: Snowflake, limit: int, after: Optional[Snowflake] ) -> Response[List[member.MemberWithUser]]: params: Dict[str, Any] = { "limit": limit, @@ -1510,7 +1510,7 @@ def get_members( return self.request(r, params=params) def get_member( - self, guild_id: Snowflake, member_id: Snowflake + self, guild_id: Snowflake, member_id: Snowflake ) -> Response[member.MemberWithUser]: return self.request( Route( @@ -1522,13 +1522,13 @@ def get_member( ) def prune_members( - self, - guild_id: Snowflake, - days: int, - compute_prune_count: bool, - roles: List[str], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + days: int, + compute_prune_count: bool, + roles: List[str], + *, + reason: Optional[str] = None, ) -> Response[guild.GuildPrune]: payload: Dict[str, Any] = { "days": days, @@ -1544,10 +1544,10 @@ def prune_members( ) def estimate_pruned_members( - self, - guild_id: Snowflake, - days: int, - roles: List[str], + self, + guild_id: Snowflake, + days: int, + roles: List[str], ) -> Response[guild.GuildPrune]: params: Dict[str, Any] = { "days": days, @@ -1569,7 +1569,7 @@ def get_all_guild_stickers(self, guild_id: Snowflake) -> Response[List[sticker.G return self.request(Route("GET", "/guilds/{guild_id}/stickers", guild_id=guild_id)) def get_guild_sticker( - self, guild_id: Snowflake, sticker_id: Snowflake + self, guild_id: Snowflake, sticker_id: Snowflake ) -> Response[sticker.GuildSticker]: return self.request( Route( @@ -1581,12 +1581,12 @@ def get_guild_sticker( ) def create_guild_sticker( - self, - guild_id: Snowflake, - payload: sticker.CreateGuildSticker, - file: File, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + payload: sticker.CreateGuildSticker, + file: File, + *, + reason: Optional[str] = None, ) -> Response[sticker.GuildSticker]: initial_bytes = file.fp.read(16) @@ -1625,12 +1625,12 @@ def create_guild_sticker( ) def modify_guild_sticker( - self, - guild_id: Snowflake, - sticker_id: Snowflake, - payload: sticker.EditGuildSticker, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + sticker_id: Snowflake, + payload: sticker.EditGuildSticker, + *, + reason: Optional[str] = None, ) -> Response[sticker.GuildSticker]: return self.request( Route( @@ -1644,7 +1644,7 @@ def modify_guild_sticker( ) def delete_guild_sticker( - self, guild_id: Snowflake, sticker_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, sticker_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: return self.request( Route( @@ -1667,13 +1667,13 @@ def get_custom_emoji(self, guild_id: Snowflake, emoji_id: Snowflake) -> Response ) def create_custom_emoji( - self, - guild_id: Snowflake, - name: str, - image: str, - *, - roles: Optional[SnowflakeList] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + name: str, + image: str, + *, + roles: Optional[SnowflakeList] = None, + reason: Optional[str] = None, ) -> Response[emoji.Emoji]: payload: Dict[str, Any] = { "name": name, @@ -1685,11 +1685,11 @@ def create_custom_emoji( return self.request(r, json=payload, reason=reason) def delete_custom_emoji( - self, - guild_id: Snowflake, - emoji_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + emoji_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/emojis/{emoji_id}", guild_id=guild_id, emoji_id=emoji_id @@ -1711,15 +1711,18 @@ def edit_custom_emoji( def get_all_application_emojis(self, application_id: Snowflake) -> Response[List[emoji.Emoji]]: return self.request( - Route( - "GET","/applications/{application_id}/emojis", application_id=application_id - ) + Route("GET", "/applications/{application_id}/emojis", application_id=application_id) ) - def get_application_emoji(self, application_id: Snowflake, emoji_id: Snowflake) -> Response[emoji.Emoji]: + def get_application_emoji( + self, application_id: Snowflake, emoji_id: Snowflake + ) -> Response[emoji.Emoji]: return self.request( Route( - "GET", "/applications/{application_id}/emojis/{emoji_id}", application_id=application_id, emoji_id=emoji_id + "GET", + "/applications/{application_id}/emojis/{emoji_id}", + application_id=application_id, + emoji_id=emoji_id, ) ) @@ -1729,13 +1732,8 @@ def create_application_emoji( name: str, image: str, ) -> Response[emoji.Emoji]: - payload = { - "name": name, - "image": image - } - r = Route( - "POST", "/applications/{application_id}/emojis", application_id=application_id - ) + payload = {"name": name, "image": image} + r = Route("POST", "/applications/{application_id}/emojis", application_id=application_id) return self.request(r, json=payload) def delete_application_emoji( @@ -1772,7 +1770,7 @@ def get_all_integrations(self, guild_id: Snowflake) -> Response[List[integration return self.request(r) def create_integration( - self, guild_id: Snowflake, type: integration.IntegrationType, id: int + self, guild_id: Snowflake, type: integration.IntegrationType, id: int ) -> Response[None]: payload = { "type": type, @@ -1783,7 +1781,7 @@ def create_integration( return self.request(r, json=payload) def edit_integration( - self, guild_id: Snowflake, integration_id: Snowflake, **payload: Any + self, guild_id: Snowflake, integration_id: Snowflake, **payload: Any ) -> Response[None]: r = Route( "PATCH", @@ -1805,7 +1803,7 @@ def sync_integration(self, guild_id: Snowflake, integration_id: Snowflake) -> Re return self.request(r) def delete_integration( - self, guild_id: Snowflake, integration_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, integration_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -1817,14 +1815,14 @@ def delete_integration( return self.request(r, reason=reason) def get_audit_logs( - self, - guild_id: Snowflake, - limit: int = 100, - # only one of these two may be specified, otherwise `after` gets ignored - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - user_id: Optional[Snowflake] = None, - action_type: Optional[audit_log.AuditLogEvent] = None, + self, + guild_id: Snowflake, + limit: int = 100, + # only one of these two may be specified, otherwise `after` gets ignored + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + user_id: Optional[Snowflake] = None, + action_type: Optional[audit_log.AuditLogEvent] = None, ) -> Response[audit_log.AuditLog]: params: Dict[str, Any] = {"limit": limit} if before is not None: @@ -1846,7 +1844,7 @@ def get_widget_settings(self, guild_id: Snowflake) -> Response[widget.WidgetSett return self.request(Route("GET", "/guilds/{guild_id}/widget", guild_id=guild_id)) def edit_widget( - self, guild_id: Snowflake, payload: Dict[str, Any], *, reason: Optional[str] = None + self, guild_id: Snowflake, payload: Dict[str, Any], *, reason: Optional[str] = None ) -> Response[widget.WidgetSettings]: return self.request( Route("PATCH", "/guilds/{guild_id}/widget", guild_id=guild_id), @@ -1864,17 +1862,17 @@ def widget_image_url(self, guild_id: Snowflake, *, style: str) -> str: # Invite management def create_invite( - self, - channel_id: Snowflake, - *, - reason: Optional[str] = None, - max_age: int = 0, - max_uses: int = 0, - temporary: bool = False, - unique: bool = True, - target_type: Optional[invite.InviteTargetType] = None, - target_user_id: Optional[Snowflake] = None, - target_application_id: Optional[Snowflake] = None, + self, + channel_id: Snowflake, + *, + reason: Optional[str] = None, + max_age: int = 0, + max_uses: int = 0, + temporary: bool = False, + unique: bool = True, + target_type: Optional[invite.InviteTargetType] = None, + target_user_id: Optional[Snowflake] = None, + target_application_id: Optional[Snowflake] = None, ) -> Response[invite.Invite]: r = Route("POST", "/channels/{channel_id}/invites", channel_id=channel_id) payload: Dict[str, Any] = { @@ -1896,12 +1894,12 @@ def create_invite( return self.request(r, reason=reason, json=payload) def get_invite( - self, - invite_id: str, - *, - with_counts: bool = True, - with_expiration: bool = True, - guild_scheduled_event_id: Optional[int] = None, + self, + invite_id: str, + *, + with_counts: bool = True, + with_expiration: bool = True, + guild_scheduled_event_id: Optional[int] = None, ) -> Response[invite.Invite]: params = { "with_counts": int(with_counts), @@ -1931,12 +1929,12 @@ def get_roles(self, guild_id: Snowflake) -> Response[List[role.Role]]: return self.request(Route("GET", "/guilds/{guild_id}/roles", guild_id=guild_id)) def edit_role( - self, - guild_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[role.Role]: r = Route("PATCH", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id) valid_keys = ( @@ -1953,7 +1951,7 @@ def edit_role( return self.request(r, json=payload, reason=reason) def delete_role( - self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None + self, guild_id: Snowflake, role_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", "/guilds/{guild_id}/roles/{role_id}", guild_id=guild_id, role_id=role_id @@ -1961,38 +1959,38 @@ def delete_role( return self.request(r, reason=reason) def replace_roles( - self, - user_id: Snowflake, - guild_id: Snowflake, - role_ids: List[int], - *, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + role_ids: List[int], + *, + reason: Optional[str] = None, ) -> Response[member.MemberWithUser]: return self.edit_member(guild_id=guild_id, user_id=user_id, roles=role_ids, reason=reason) def create_role( - self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any + self, guild_id: Snowflake, *, reason: Optional[str] = None, **fields: Any ) -> Response[role.Role]: r = Route("POST", "/guilds/{guild_id}/roles", guild_id=guild_id) return self.request(r, json=fields, reason=reason) def move_role_position( - self, - guild_id: Snowflake, - positions: List[guild.RolePositionUpdate], - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + positions: List[guild.RolePositionUpdate], + *, + reason: Optional[str] = None, ) -> Response[List[role.Role]]: r = Route("PATCH", "/guilds/{guild_id}/roles", guild_id=guild_id) return self.request(r, json=positions, reason=reason) def add_role( - self, - guild_id: Snowflake, - user_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "PUT", @@ -2004,12 +2002,12 @@ def add_role( return self.request(r, reason=reason) def remove_role( - self, - guild_id: Snowflake, - user_id: Snowflake, - role_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + user_id: Snowflake, + role_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: r = Route( "DELETE", @@ -2021,14 +2019,14 @@ def remove_role( return self.request(r, reason=reason) def edit_channel_permissions( - self, - channel_id: Snowflake, - target: Snowflake, - allow: int, - deny: int, - type: channel.OverwriteType, - *, - reason: Optional[str] = None, + self, + channel_id: Snowflake, + target: Snowflake, + allow: int, + deny: int, + type: channel.OverwriteType, + *, + reason: Optional[str] = None, ) -> Response[None]: payload = {"id": target, "allow": allow, "deny": deny, "type": type} r = Route( @@ -2040,7 +2038,7 @@ def edit_channel_permissions( return self.request(r, json=payload, reason=reason) def delete_channel_permissions( - self, channel_id: Snowflake, target: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, target: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: r = Route( "DELETE", @@ -2053,12 +2051,12 @@ def delete_channel_permissions( # Voice management def move_member( - self, - user_id: Snowflake, - guild_id: Snowflake, - channel_id: Snowflake, - *, - reason: Optional[str] = None, + self, + user_id: Snowflake, + guild_id: Snowflake, + channel_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[member.MemberWithUser]: return self.edit_member( guild_id=guild_id, user_id=user_id, channel_id=channel_id, reason=reason @@ -2070,7 +2068,7 @@ def get_stage_instance(self, channel_id: Snowflake) -> Response[channel.StageIns return self.request(Route("GET", "/stage-instances/{channel_id}", channel_id=channel_id)) def create_stage_instance( - self, *, reason: Optional[str] = None, **payload: Any + self, *, reason: Optional[str] = None, **payload: Any ) -> Response[channel.StageInstance]: valid_keys = ( "channel_id", @@ -2084,7 +2082,7 @@ def create_stage_instance( return self.request(Route("POST", "/stage-instances"), json=payload, reason=reason) def edit_stage_instance( - self, channel_id: Snowflake, *, reason: Optional[str] = None, **payload: Any + self, channel_id: Snowflake, *, reason: Optional[str] = None, **payload: Any ) -> Response[None]: valid_keys = ( "topic", @@ -2099,7 +2097,7 @@ def edit_stage_instance( ) def delete_stage_instance( - self, channel_id: Snowflake, *, reason: Optional[str] = None + self, channel_id: Snowflake, *, reason: Optional[str] = None ) -> Response[None]: return self.request( Route("DELETE", "/stage-instances/{channel_id}", channel_id=channel_id), reason=reason @@ -2108,26 +2106,26 @@ def delete_stage_instance( # Scheduled event management def get_guild_scheduled_events( - self, guild_id: Snowflake, with_user_count: bool = False + self, guild_id: Snowflake, with_user_count: bool = False ) -> Response[List[guild_scheduled_event.GuildScheduledEvent]]: params = {"with_user_count": int(with_user_count)} r = Route("GET", "/guilds/{guild_id}/scheduled-events", guild_id=guild_id) return self.request(r, params=params) def create_guild_scheduled_event( - self, - guild_id: Snowflake, - *, - name: str, - privacy_level: int, - scheduled_start_time: str, - entity_type: int, - channel_id: Optional[Snowflake] = None, - entity_metadata: Optional[Dict[str, Any]] = None, - scheduled_end_time: Optional[str] = None, - description: Optional[str] = None, - image: Optional[str] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + *, + name: str, + privacy_level: int, + scheduled_start_time: str, + entity_type: int, + channel_id: Optional[Snowflake] = None, + entity_metadata: Optional[Dict[str, Any]] = None, + scheduled_end_time: Optional[str] = None, + description: Optional[str] = None, + image: Optional[str] = None, + reason: Optional[str] = None, ) -> Response[guild_scheduled_event.GuildScheduledEvent]: r = Route("POST", "/guilds/{guild_id}/scheduled-events", guild_id=guild_id) payload: Dict[str, Any] = { @@ -2155,7 +2153,7 @@ def create_guild_scheduled_event( return self.request(r, json=payload, reason=reason) def get_guild_scheduled_event( - self, guild_id: Snowflake, event_id: Snowflake, with_user_count: bool = False + self, guild_id: Snowflake, event_id: Snowflake, with_user_count: bool = False ) -> Response[guild_scheduled_event.GuildScheduledEvent]: params = {"with_user_count": int(with_user_count)} route = Route( @@ -2167,12 +2165,12 @@ def get_guild_scheduled_event( return self.request(route, params=params) def edit_guild_scheduled_event( - self, - guild_id: Snowflake, - event_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + event_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[guild_scheduled_event.GuildScheduledEvent]: route = Route( method="PATCH", @@ -2184,7 +2182,7 @@ def edit_guild_scheduled_event( return self.request(route, json=fields, reason=reason) def delete_guild_scheduled_event( - self, guild_id: Snowflake, event_id: Snowflake + self, guild_id: Snowflake, event_id: Snowflake ) -> Response[None]: route = Route( method="DELETE", @@ -2195,13 +2193,13 @@ def delete_guild_scheduled_event( return self.request(route) def get_guild_scheduled_event_users( - self, - guild_id: Snowflake, - event_id: Snowflake, - limit: Optional[int] = None, - with_member: Optional[bool] = None, - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, + self, + guild_id: Snowflake, + event_id: Snowflake, + limit: Optional[int] = None, + with_member: Optional[bool] = None, + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, ) -> Response[List[guild_scheduled_event.GuildScheduledEventUser]]: params: Dict[str, Any] = {} @@ -2228,17 +2226,17 @@ def get_guild_scheduled_event_users( # Welcome screens def get_guild_welcome_screen( - self, guild_id: Snowflake + self, guild_id: Snowflake ) -> Response[welcome_screen.WelcomeScreen]: r = Route("GET", "/guilds/{guild_id}/welcome-screen", guild_id=guild_id) return self.request(r) def edit_guild_welcome_screen( - self, - guild_id: Snowflake, - *, - reason: Optional[str] = None, - **kwargs: Any, + self, + guild_id: Snowflake, + *, + reason: Optional[str] = None, + **kwargs: Any, ) -> Response[welcome_screen.WelcomeScreen]: valid_keys = ( "enabled", @@ -2258,7 +2256,7 @@ def get_auto_moderation_rules(self, guild_id: Snowflake) -> Response[List[automo ) def get_auto_moderation_rule( - self, guild_id: Snowflake, rule_id: Snowflake + self, guild_id: Snowflake, rule_id: Snowflake ) -> Response[automod.AutoModRule]: return self.request( Route( @@ -2270,18 +2268,18 @@ def get_auto_moderation_rule( ) def create_auto_moderation_rule( - self, - guild_id: Snowflake, - *, - name: str, - event_type: automod.AutoModEventType, - trigger_type: automod.AutoModTriggerType, - actions: List[automod.AutoModAction], - trigger_metadata: Optional[automod.AutoModTriggerMetadata] = None, - enabled: Optional[bool] = None, - exempt_roles: Optional[SnowflakeList] = None, - exempt_channels: Optional[SnowflakeList] = None, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + *, + name: str, + event_type: automod.AutoModEventType, + trigger_type: automod.AutoModTriggerType, + actions: List[automod.AutoModAction], + trigger_metadata: Optional[automod.AutoModTriggerMetadata] = None, + enabled: Optional[bool] = None, + exempt_roles: Optional[SnowflakeList] = None, + exempt_channels: Optional[SnowflakeList] = None, + reason: Optional[str] = None, ) -> Response[automod.AutoModRule]: payload: automod.CreateAutoModRule = { "name": name, @@ -2306,12 +2304,12 @@ def create_auto_moderation_rule( ) def edit_auto_moderation_rule( - self, - guild_id: Snowflake, - rule_id: Snowflake, - *, - reason: Optional[str] = None, - **fields: Any, + self, + guild_id: Snowflake, + rule_id: Snowflake, + *, + reason: Optional[str] = None, + **fields: Any, ) -> Response[automod.AutoModRule]: return self.request( Route( @@ -2325,11 +2323,11 @@ def edit_auto_moderation_rule( ) def delete_auto_moderation_rule( - self, - guild_id: Snowflake, - rule_id: Snowflake, - *, - reason: Optional[str] = None, + self, + guild_id: Snowflake, + rule_id: Snowflake, + *, + reason: Optional[str] = None, ) -> Response[None]: return self.request( Route( @@ -2354,17 +2352,17 @@ def get_skus(self, application_id: Snowflake) -> Response[List[sku.SKU]]: ) def get_entitlements( - self, - application_id: Snowflake, - *, - # if both are specified, `after` takes priority and `before` gets ignored - before: Optional[Snowflake] = None, - after: Optional[Snowflake] = None, - limit: int = 100, - user_id: Optional[Snowflake] = None, - guild_id: Optional[Snowflake] = None, - sku_ids: Optional[SnowflakeList] = None, - exclude_ended: bool = False, + self, + application_id: Snowflake, + *, + # if both are specified, `after` takes priority and `before` gets ignored + before: Optional[Snowflake] = None, + after: Optional[Snowflake] = None, + limit: int = 100, + user_id: Optional[Snowflake] = None, + guild_id: Optional[Snowflake] = None, + sku_ids: Optional[SnowflakeList] = None, + exclude_ended: bool = False, ) -> Response[List[entitlement.Entitlement]]: params: Dict[str, Any] = { "limit": limit, @@ -2387,12 +2385,12 @@ def get_entitlements( return self.request(r, params=params) def create_test_entitlement( - self, - application_id: Snowflake, - sku_id: Snowflake, - owner_id: Snowflake, - *, - owner_type: Literal[1, 2], # 1: guild, 2: user + self, + application_id: Snowflake, + sku_id: Snowflake, + owner_id: Snowflake, + *, + owner_type: Literal[1, 2], # 1: guild, 2: user ) -> Response[entitlement.Entitlement]: payload: Dict[str, Any] = { "sku_id": sku_id, @@ -2407,9 +2405,9 @@ def create_test_entitlement( ) def delete_test_entitlement( - self, - application_id: Snowflake, - entitlement_id: Snowflake, + self, + application_id: Snowflake, + entitlement_id: Snowflake, ) -> Response[None]: return self.request( Route( @@ -2421,9 +2419,9 @@ def delete_test_entitlement( ) def consume_entitlement( - self, - application_id: Snowflake, - entitlement_id: Snowflake, + self, + application_id: Snowflake, + entitlement_id: Snowflake, ) -> Response[None]: return self.request( Route( @@ -2437,10 +2435,10 @@ def consume_entitlement( # Application commands (global) def get_global_commands( - self, - application_id: Snowflake, - *, - with_localizations: bool = True, + self, + application_id: Snowflake, + *, + with_localizations: bool = True, ) -> Response[List[interactions.ApplicationCommand]]: params: Dict[str, Any] = {} # the API currently interprets any non-empty value as truthy @@ -2453,7 +2451,7 @@ def get_global_commands( ) def get_global_command( - self, application_id: Snowflake, command_id: Snowflake + self, application_id: Snowflake, command_id: Snowflake ) -> Response[interactions.ApplicationCommand]: r = Route( "GET", @@ -2464,16 +2462,16 @@ def get_global_command( return self.request(r) def upsert_global_command( - self, application_id: Snowflake, payload: interactions.EditApplicationCommand + self, application_id: Snowflake, payload: interactions.EditApplicationCommand ) -> Response[interactions.ApplicationCommand]: r = Route("POST", "/applications/{application_id}/commands", application_id=application_id) return self.request(r, json=payload) def edit_global_command( - self, - application_id: Snowflake, - command_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + command_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "PATCH", @@ -2484,7 +2482,7 @@ def edit_global_command( return self.request(r, json=payload) def delete_global_command( - self, application_id: Snowflake, command_id: Snowflake + self, application_id: Snowflake, command_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -2495,7 +2493,7 @@ def delete_global_command( return self.request(r) def bulk_upsert_global_commands( - self, application_id: Snowflake, payload: List[interactions.EditApplicationCommand] + self, application_id: Snowflake, payload: List[interactions.EditApplicationCommand] ) -> Response[List[interactions.ApplicationCommand]]: r = Route("PUT", "/applications/{application_id}/commands", application_id=application_id) return self.request(r, json=payload) @@ -2503,11 +2501,11 @@ def bulk_upsert_global_commands( # Application commands (guild) def get_guild_commands( - self, - application_id: Snowflake, - guild_id: Snowflake, - *, - with_localizations: bool = True, + self, + application_id: Snowflake, + guild_id: Snowflake, + *, + with_localizations: bool = True, ) -> Response[List[interactions.ApplicationCommand]]: params: Dict[str, Any] = {} # the API currently interprets any non-empty value as truthy @@ -2523,10 +2521,10 @@ def get_guild_commands( return self.request(r, params=params) def get_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[interactions.ApplicationCommand]: r = Route( "GET", @@ -2538,10 +2536,10 @@ def get_guild_command( return self.request(r) def upsert_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + guild_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "POST", @@ -2552,11 +2550,11 @@ def upsert_guild_command( return self.request(r, json=payload) def edit_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, - payload: interactions.EditApplicationCommand, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, + payload: interactions.EditApplicationCommand, ) -> Response[interactions.ApplicationCommand]: r = Route( "PATCH", @@ -2568,10 +2566,10 @@ def edit_guild_command( return self.request(r, json=payload) def delete_guild_command( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[None]: r = Route( "DELETE", @@ -2583,10 +2581,10 @@ def delete_guild_command( return self.request(r) def bulk_upsert_guild_commands( - self, - application_id: Snowflake, - guild_id: Snowflake, - payload: List[interactions.EditApplicationCommand], + self, + application_id: Snowflake, + guild_id: Snowflake, + payload: List[interactions.EditApplicationCommand], ) -> Response[List[interactions.ApplicationCommand]]: r = Route( "PUT", @@ -2599,13 +2597,13 @@ def bulk_upsert_guild_commands( # Interaction responses def _edit_webhook_helper( - self, - route: Route, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + route: Route, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: # TODO: this does not work how it should (e.g. `embeds=[]` is ignored). # This method (or rather its calling methods) is completely unused, and hence likely untested @@ -2626,12 +2624,12 @@ def _edit_webhook_helper( return self.request(route, json=payload) def create_interaction_response( - self, - interaction_id: Snowflake, - token: str, - *, - type: InteractionResponseType, - data: Optional[interactions.InteractionCallbackData] = None, + self, + interaction_id: Snowflake, + token: str, + *, + type: InteractionResponseType, + data: Optional[interactions.InteractionCallbackData] = None, ) -> Response[None]: r = Route( "POST", @@ -2649,9 +2647,9 @@ def create_interaction_response( return self.request(r, json=payload) def get_original_interaction_response( - self, - application_id: Snowflake, - token: str, + self, + application_id: Snowflake, + token: str, ) -> Response[message.Message]: r = Route( "GET", @@ -2662,14 +2660,14 @@ def get_original_interaction_response( return self.request(r) def edit_original_interaction_response( - self, - application_id: Snowflake, - token: str, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + application_id: Snowflake, + token: str, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: r = Route( "PATCH", @@ -2687,7 +2685,7 @@ def edit_original_interaction_response( ) def delete_original_interaction_response( - self, application_id: Snowflake, token: str + self, application_id: Snowflake, token: str ) -> Response[None]: r = Route( "DELETE", @@ -2698,14 +2696,14 @@ def delete_original_interaction_response( return self.request(r) def create_followup_message( - self, - application_id: Snowflake, - token: str, - files: Optional[List[File]] = None, - content: Optional[str] = None, - tts: bool = False, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, + self, + application_id: Snowflake, + token: str, + files: Optional[List[File]] = None, + content: Optional[str] = None, + tts: bool = False, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, ) -> Response[message.Message]: r = Route( "POST", @@ -2725,15 +2723,15 @@ def create_followup_message( ) def edit_followup_message( - self, - application_id: Snowflake, - token: str, - message_id: Snowflake, - file: Optional[File] = None, - content: Optional[str] = None, - embeds: Optional[List[embed.Embed]] = None, - allowed_mentions: Optional[message.AllowedMentions] = None, - attachments: Optional[List[Attachment]] = None, + self, + application_id: Snowflake, + token: str, + message_id: Snowflake, + file: Optional[File] = None, + content: Optional[str] = None, + embeds: Optional[List[embed.Embed]] = None, + allowed_mentions: Optional[message.AllowedMentions] = None, + attachments: Optional[List[Attachment]] = None, ) -> Response[message.Message]: r = Route( "PATCH", @@ -2752,7 +2750,7 @@ def edit_followup_message( ) def delete_followup_message( - self, application_id: Snowflake, token: str, message_id: Snowflake + self, application_id: Snowflake, token: str, message_id: Snowflake ) -> Response[None]: r = Route( "DELETE", @@ -2764,9 +2762,9 @@ def delete_followup_message( return self.request(r) def get_guild_application_command_permissions( - self, - application_id: Snowflake, - guild_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, ) -> Response[List[interactions.GuildApplicationCommandPermissions]]: r = Route( "GET", @@ -2777,10 +2775,10 @@ def get_guild_application_command_permissions( return self.request(r) def get_application_command_permissions( - self, - application_id: Snowflake, - guild_id: Snowflake, - command_id: Snowflake, + self, + application_id: Snowflake, + guild_id: Snowflake, + command_id: Snowflake, ) -> Response[interactions.GuildApplicationCommandPermissions]: r = Route( "GET", @@ -2800,7 +2798,7 @@ def application_info(self) -> Response[appinfo.AppInfo]: return self.request(Route("GET", "/oauth2/applications/@me")) def get_application_role_connection_metadata_records( - self, application_id: Snowflake + self, application_id: Snowflake ) -> Response[List[application_role_connection.ApplicationRoleConnectionMetadata]]: return self.request( Route( @@ -2811,9 +2809,9 @@ def get_application_role_connection_metadata_records( ) def edit_application_role_connection_metadata_records( - self, - application_id: Snowflake, - records: Sequence[application_role_connection.ApplicationRoleConnectionMetadata], + self, + application_id: Snowflake, + records: Sequence[application_role_connection.ApplicationRoleConnectionMetadata], ) -> Response[List[application_role_connection.ApplicationRoleConnectionMetadata]]: return self.request( Route( @@ -2833,7 +2831,7 @@ async def get_gateway(self, *, encoding: str = "json", zlib: bool = True) -> str return self._format_gateway_url(data["url"], encoding=encoding, zlib=zlib) async def get_bot_gateway( - self, *, encoding: str = "json", zlib: bool = True + self, *, encoding: str = "json", zlib: bool = True ) -> Tuple[int, str, gateway.SessionStartLimit]: try: data: gateway.GatewayBot = await self.request(Route("GET", "/gateway/bot")) diff --git a/disnake/state.py b/disnake/state.py index 5a53d14328..2c72fae163 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -204,7 +204,7 @@ def __init__( intents: Optional[Intents] = None, chunk_guilds_at_startup: Optional[bool] = None, member_cache_flags: Optional[MemberCacheFlags] = None, - cache_app_emojis: bool = False + cache_app_emojis: bool = False, ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.http: HTTPClient = http @@ -403,9 +403,7 @@ def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) return emoji - def store_application_emoji( - self, application_id: int, data: EmojiPayload - ) -> ApplicationEmoji: + def store_application_emoji(self, application_id: int, data: EmojiPayload) -> ApplicationEmoji: emoji = ApplicationEmoji(application_id=application_id, state=self, data=data) if self.cache_app_emojis: emoji_id = int(data["id"]) # type: ignore @@ -520,7 +518,7 @@ def _get_guild_command_named( return cmd @property - def emojis(self) -> List[GuildEmoji | ApplicationEmoji]: + def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: return list(self._emojis.values()) @property @@ -531,7 +529,7 @@ def get_emoji(self, emoji_id: Optional[int]) -> Optional[Union[GuildEmoji, Appli # the keys of self._emojis are ints return self._emojis.get(emoji_id) # type: ignore - def _remove_emoji(self, emoji: GuildEmoji | ApplicationEmoji) -> None: + def _remove_emoji(self, emoji: Union[GuildEmoji, ApplicationEmoji]) -> None: self._emojis.pop(emoji.id, None) def get_sticker(self, sticker_id: Optional[int]) -> Optional[GuildSticker]: From d55e36040adeb2317ce375a487e31549c8792c62 Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 17:38:05 +0800 Subject: [PATCH 03/15] refactor: Modified _emojis type definition to Dict[int, Union[GuildEmoji, ApplicationEmoji]] --- disnake/state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disnake/state.py b/disnake/state.py index 2c72fae163..329e007d18 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -296,7 +296,7 @@ def clear( # - the weakref slot + object in user objects likely results in a small increase in memory usage # - accesses on `_users` are slower, e.g. `__getitem__` takes ~1us with weakrefs and ~0.2us without self._users: weakref.WeakValueDictionary[int, User] = weakref.WeakValueDictionary() - self._emojis: Dict[int, Emoji, ApplicationEmoji] = {} + self._emojis: Dict[int, Union[GuildEmoji, ApplicationEmoji]] = {} self._stickers: Dict[int, GuildSticker] = {} self._guilds: Dict[int, Guild] = {} From b7c494f2d3d5d39b10db26301ee483c8a0449e88 Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 20:47:21 +0800 Subject: [PATCH 04/15] fix: attempt to resolve pyright test issues --- disnake/audit_logs.py | 4 ++-- disnake/client.py | 4 ++-- disnake/emoji.py | 5 +++-- disnake/http.py | 2 +- disnake/state.py | 2 +- disnake/types/emoji.py | 6 +++++- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/disnake/audit_logs.py b/disnake/audit_logs.py index c5ec6caf79..a3271e2f61 100644 --- a/disnake/audit_logs.py +++ b/disnake/audit_logs.py @@ -43,7 +43,7 @@ from .app_commands import APIApplicationCommand from .automod import AutoModRule - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .guild import Guild from .guild_scheduled_event import GuildScheduledEvent from .integrations import PartialIntegration @@ -817,7 +817,7 @@ def _convert_target_invite(self, target_id: int) -> Invite: def _convert_target_webhook(self, target_id: int) -> Union[Webhook, Object]: return self._webhooks.get(target_id) or Object(id=target_id) - def _convert_target_emoji(self, target_id: int) -> Union[Emoji, Object]: + def _convert_target_emoji(self, target_id: int) -> Union[Emoji, ApplicationEmoji, Object]: return self._state.get_emoji(target_id) or Object(id=target_id) def _convert_target_message(self, target_id: int) -> Union[Member, User, Object, None]: diff --git a/disnake/client.py b/disnake/client.py index 6a8f92e2e4..bec283a3b3 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -3235,9 +3235,9 @@ async def fetch_application_emojis(self) -> list[ApplicationEmoji]: List[:class:`ApplicationEmoji`] The retrieved emojis. """ - data = await self._connection.http.get_all_application_emojis(self.application_id) + emojis = await self._connection.http.get_all_application_emojis(self.application_id) return [ - self._connection.store_application_emoji(self.application_id, d) for d in data["items"] + self._connection.store_application_emoji(self.application_id, e) for e in emojis['items'] ] async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: diff --git a/disnake/emoji.py b/disnake/emoji.py index 0c39fa3f1b..488eee894d 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple +from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Tuple, Union from .asset import Asset, AssetMixin from .partial_emoji import PartialEmoji, _EmojiTag @@ -16,6 +16,7 @@ from .abc import Snowflake from .guild import Guild + from .guild_preview import GuildPreview from .role import Role from .state import ConnectionState from .types.emoji import Emoji as EmojiPayload @@ -190,7 +191,7 @@ class GuildEmoji(BaseEmoji): having the :attr:`~Permissions.manage_guild_expressions` permission. """ - def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): + def __init__(self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload): self.guild_id: int = guild.id super().__init__(state=state, data=data) diff --git a/disnake/http.py b/disnake/http.py index fd760859de..69b9242d78 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -1709,7 +1709,7 @@ def edit_custom_emoji( ) return self.request(r, json=payload, reason=reason) - def get_all_application_emojis(self, application_id: Snowflake) -> Response[List[emoji.Emoji]]: + def get_all_application_emojis(self, application_id: Snowflake) -> Response[Dict[str, List[emoji.Emoji]]]: return self.request( Route("GET", "/applications/{application_id}/emojis", application_id=application_id) ) diff --git a/disnake/state.py b/disnake/state.py index 329e007d18..a5b05ecfb9 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -445,7 +445,7 @@ def _remove_guild(self, guild: Guild) -> None: self._guilds.pop(guild.id, None) for emoji in guild.emojis: - self._remove_emoji(emoji.id) + self._remove_emoji(emoji) for sticker in guild.stickers: self._stickers.pop(sticker.id, None) diff --git a/disnake/types/emoji.py b/disnake/types/emoji.py index 5b8bdcf756..6a09c95933 100644 --- a/disnake/types/emoji.py +++ b/disnake/types/emoji.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT -from typing import Optional, TypedDict +from typing import Optional, TypedDict, List from .snowflake import Snowflake, SnowflakeList from .user import User @@ -20,6 +20,10 @@ class Emoji(PartialEmoji, total=False): available: bool +class ApplicationEmojiList(TypedDict): + items: List[Emoji] + + class EditEmoji(TypedDict): name: str roles: Optional[SnowflakeList] From 0957059439516600330687abcb1513879fe1b1f9 Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 20:52:10 +0800 Subject: [PATCH 05/15] fix: Expression of type cannot be assigned to return type --- disnake/state.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/disnake/state.py b/disnake/state.py index a5b05ecfb9..89b7442851 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -1942,7 +1942,7 @@ def _get_reaction_user( def _get_emoji_from_data( self, data: PartialEmojiPayload - ) -> Optional[Union[str, Emoji, PartialEmoji]]: + ) -> Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]: """Convert partial emoji data to proper emoji. Returns unicode emojis as strings. @@ -1973,7 +1973,7 @@ def _get_emoji_from_fields( name: Optional[str], id: Optional[int], animated: Optional[bool] = False, - ) -> Optional[Union[Emoji, PartialEmoji]]: + ) -> Optional[Union[Emoji, ApplicationEmoji ,PartialEmoji]]: """Convert partial emoji fields to proper emoji, if possible. If both `id` and `name` are nullish, returns `None`. @@ -1999,7 +1999,7 @@ def _get_emoji_from_fields( animated=animated or False, ) - def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> Union[Emoji, PartialEmoji, str]: + def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> Union[Emoji, ApplicationEmoji, PartialEmoji, str]: emoji_id = emoji.id if not emoji_id: return emoji.name From 4c8b7a91ff69a1aa327c545345269c785226e6f6 Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 21:21:32 +0800 Subject: [PATCH 06/15] fix: attempt to resolve pyright test issues too --- disnake/audit_logs.py | 2 +- disnake/channel.py | 4 +- disnake/message.py | 6 +- disnake/onboarding.py | 4 +- disnake/state.py | 222 +++++++++++++++++++------------------- disnake/threads.py | 6 +- disnake/welcome_screen.py | 6 +- 7 files changed, 126 insertions(+), 124 deletions(-) diff --git a/disnake/audit_logs.py b/disnake/audit_logs.py index a3271e2f61..12b78e8a44 100644 --- a/disnake/audit_logs.py +++ b/disnake/audit_logs.py @@ -280,7 +280,7 @@ def _transform_automod_trigger_metadata( def _transform_default_reaction( entry: AuditLogEntry, data: Optional[DefaultReactionPayload] -) -> Optional[Union[Emoji, PartialEmoji]]: +) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: if data is None: return None return entry._state._get_emoji_from_fields( diff --git a/disnake/channel.py b/disnake/channel.py index 8eaf8dd794..f654cda67c 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -69,7 +69,7 @@ from .abc import Snowflake, SnowflakeTime from .asset import AssetBytes from .embeds import Embed - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .guild import Guild, GuildChannel as GuildChannelType from .member import Member, VoiceState from .message import AllowedMentions, Message, PartialMessage @@ -3314,7 +3314,7 @@ def requires_tag(self) -> bool: return self.flags.require_tag @property - def default_reaction(self) -> Optional[Union[Emoji, PartialEmoji]]: + def default_reaction(self) -> Optional[Union[Emoji, ApplicationEmoji ,PartialEmoji]]: """Optional[Union[:class:`Emoji`, :class:`PartialEmoji`]]: The default emoji shown for reacting to threads. diff --git a/disnake/message.py b/disnake/message.py index 7957799de6..7503fe98ff 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -25,7 +25,7 @@ from . import utils from .components import ActionRow, MessageComponent, _component_factory from .embeds import Embed -from .emoji import Emoji +from .emoji import Emoji, ApplicationEmoji from .enums import ChannelType, InteractionType, MessageType, try_enum, try_enum_to_int from .errors import HTTPException from .file import File @@ -76,7 +76,7 @@ from .ui.action_row import Components, MessageUIComponent from .ui.view import View - EmojiInputType = Union[Emoji, PartialEmoji, str] + EmojiInputType = Union[Emoji, ApplicationEmoji, PartialEmoji, str] __all__ = ( "Attachment", @@ -93,7 +93,7 @@ def convert_emoji_reaction(emoji: Union[EmojiInputType, Reaction]) -> str: if isinstance(emoji, Reaction): emoji = emoji.emoji - if isinstance(emoji, Emoji): + if isinstance(emoji, Emoji) or isinstance(emoji, ApplicationEmoji): return f"{emoji.name}:{emoji.id}" if isinstance(emoji, PartialEmoji): return emoji._as_reaction() diff --git a/disnake/onboarding.py b/disnake/onboarding.py index 069e0fb7fa..c114649d38 100644 --- a/disnake/onboarding.py +++ b/disnake/onboarding.py @@ -7,7 +7,7 @@ from .mixins import Hashable if TYPE_CHECKING: - from .emoji import Emoji, PartialEmoji + from .emoji import Emoji, PartialEmoji, ApplicationEmoji from .guild import Guild, GuildChannel from .role import Role from .types.onboarding import ( @@ -170,7 +170,7 @@ def __init__(self, *, guild: Guild, data: OnboardingPromptOptionPayload) -> None else frozenset() ) - self.emoji: Optional[Union[Emoji, PartialEmoji, str]] + self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji, str]] if emoji_data := data.get("emoji"): self.emoji = guild._state.get_reaction_emoji(emoji_data) else: diff --git a/disnake/state.py b/disnake/state.py index 89b7442851..2da4349702 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -113,12 +113,12 @@ class ChunkRequest: def __init__( - self, - guild_id: int, - loop: asyncio.AbstractEventLoop, - resolver: Callable[[int], Any], - *, - cache: bool = True, + self, + guild_id: int, + loop: asyncio.AbstractEventLoop, + resolver: Callable[[int], Any], + *, + cache: bool = True, ) -> None: self.guild_id: int = guild_id self.resolver: Callable[[int], Any] = resolver @@ -187,24 +187,24 @@ class ConnectionState: _parsers: Dict[str, Callable[[Dict[str, Any]], None]] def __init__( - self, - *, - dispatch: Callable, - handlers: Dict[str, Callable], - hooks: Dict[str, Callable], - http: HTTPClient, - loop: asyncio.AbstractEventLoop, - max_messages: Optional[int] = 1000, - application_id: Optional[int] = None, - heartbeat_timeout: float = 60.0, - guild_ready_timeout: float = 2.0, - allowed_mentions: Optional[AllowedMentions] = None, - activity: Optional[BaseActivity] = None, - status: Optional[Union[str, Status]] = None, - intents: Optional[Intents] = None, - chunk_guilds_at_startup: Optional[bool] = None, - member_cache_flags: Optional[MemberCacheFlags] = None, - cache_app_emojis: bool = False, + self, + *, + dispatch: Callable, + handlers: Dict[str, Callable], + hooks: Dict[str, Callable], + http: HTTPClient, + loop: asyncio.AbstractEventLoop, + max_messages: Optional[int] = 1000, + application_id: Optional[int] = None, + heartbeat_timeout: float = 60.0, + guild_ready_timeout: float = 2.0, + allowed_mentions: Optional[AllowedMentions] = None, + activity: Optional[BaseActivity] = None, + status: Optional[Union[str, Status]] = None, + intents: Optional[Intents] = None, + chunk_guilds_at_startup: Optional[bool] = None, + member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.http: HTTPClient = http @@ -288,7 +288,7 @@ def __init__( self.clear() def clear( - self, *, views: bool = True, application_commands: bool = True, modals: bool = True + self, *, views: bool = True, application_commands: bool = True, modals: bool = True ) -> None: self.user: ClientUser = MISSING # NOTE: without weakrefs, these user objects would otherwise be kept in memory indefinitely. @@ -322,7 +322,7 @@ def clear( self._messages: Optional[Deque[Message]] = None def process_chunk_requests( - self, guild_id: int, nonce: Optional[str], members: List[Member], complete: bool + self, guild_id: int, nonce: Optional[str], members: List[Member], complete: bool ) -> None: removed = [] for key, request in self._chunk_requests.items(): @@ -453,14 +453,14 @@ def _remove_guild(self, guild: Guild) -> None: del guild def _get_global_application_command( - self, application_command_id: int + self, application_command_id: int ) -> Optional[APIApplicationCommand]: return self._global_application_commands.get(application_command_id) def _add_global_application_command( - self, - application_command: APIApplicationCommand, - /, + self, + application_command: APIApplicationCommand, + /, ) -> None: if not application_command.id: AssertionError("The provided application command does not have an ID") @@ -473,14 +473,14 @@ def _clear_global_application_commands(self) -> None: self._global_application_commands.clear() def _get_guild_application_command( - self, guild_id: int, application_command_id: int + self, guild_id: int, application_command_id: int ) -> Optional[APIApplicationCommand]: granula = self._guild_application_commands.get(guild_id) if granula is not None: return granula.get(application_command_id) def _add_guild_application_command( - self, guild_id: int, application_command: APIApplicationCommand + self, guild_id: int, application_command: APIApplicationCommand ) -> None: if not application_command.id: AssertionError("The provided application command does not have an ID") @@ -503,14 +503,14 @@ def _clear_guild_application_commands(self, guild_id: int) -> None: self._guild_application_commands.pop(guild_id, None) def _get_global_command_named( - self, name: str, cmd_type: Optional[ApplicationCommandType] = None + self, name: str, cmd_type: Optional[ApplicationCommandType] = None ) -> Optional[APIApplicationCommand]: for cmd in self._global_application_commands.values(): if cmd.name == name and (cmd_type is None or cmd.type is cmd_type): return cmd def _get_guild_command_named( - self, guild_id: int, name: str, cmd_type: Optional[ApplicationCommandType] = None + self, guild_id: int, name: str, cmd_type: Optional[ApplicationCommandType] = None ) -> Optional[APIApplicationCommand]: granula = self._guild_application_commands.get(guild_id, {}) for cmd in granula.values(): @@ -597,14 +597,14 @@ def _add_guild_from_data(self, data: Union[GuildPayload, UnavailableGuildPayload def _guild_needs_chunking(self, guild: Guild) -> bool: # If presences are enabled then we get back the old guild.large behaviour return ( - self._chunk_guilds - and not guild.chunked - and not (self._intents.presences and not guild.large) + self._chunk_guilds + and not guild.chunked + and not (self._intents.presences and not guild.large) ) def _get_guild_channel( - self, - data: Union[MessagePayload, gateway.TypingStartEvent], + self, + data: Union[MessagePayload, gateway.TypingStartEvent], ) -> Tuple[Union[PartialChannel, Thread], Optional[Guild]]: channel_id = int(data["channel_id"]) try: @@ -627,13 +627,13 @@ def _get_guild_channel( return channel or PartialMessageable(state=self, id=channel_id), guild async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - nonce: Optional[str] = None, + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + nonce: Optional[str] = None, ) -> None: ws = self._get_websocket(guild_id) # This is ignored upstream await ws.request_chunks( @@ -641,13 +641,13 @@ async def chunker( ) async def query_members( - self, - guild: Guild, - query: Optional[str], - limit: int, - user_ids: Optional[List[int]], - cache: bool, - presences: bool, + self, + guild: Guild, + query: Optional[str], + limit: int, + user_ids: Optional[List[int]], + cache: bool, + presences: bool, ): guild_id = guild.id ws = self._get_websocket(guild_id) @@ -757,7 +757,7 @@ def parse_resumed(self, data: gateway.ResumedEvent) -> None: self.dispatch("resumed") def parse_application_command_permissions_update( - self, data: gateway.ApplicationCommandPermissionsUpdateEvent + self, data: gateway.ApplicationCommandPermissionsUpdateEvent ) -> None: app_command_perms = GuildApplicationCommandPermissions(data=data, state=self) self.dispatch("application_command_permissions_update", app_command_perms) @@ -779,11 +779,11 @@ def parse_message_create(self, data: gateway.MessageCreateEvent) -> None: # - or, they're the initial message of a forum channel thread (which uses MessageType.default) # This mirrors the current client and API behavior. if channel.__class__ is Thread and not ( - message.type is MessageType.thread_starter_message - or ( - type(channel.parent) in (ForumChannel, MediaChannel) # type: ignore - and channel.id == message.id - ) + message.type is MessageType.thread_starter_message + or ( + type(channel.parent) in (ForumChannel, MediaChannel) # type: ignore + and channel.id == message.id + ) ): channel.total_message_sent += 1 # type: ignore channel.message_count += 1 # type: ignore @@ -880,7 +880,7 @@ def parse_message_reaction_add(self, data: gateway.MessageReactionAddEvent) -> N self.dispatch("reaction_add", reaction, user) def parse_message_reaction_remove_all( - self, data: gateway.MessageReactionRemoveAllEvent + self, data: gateway.MessageReactionRemoveAllEvent ) -> None: raw = RawReactionClearEvent(data) self.dispatch("raw_reaction_clear", raw) @@ -918,7 +918,7 @@ def parse_message_reaction_remove(self, data: gateway.MessageReactionRemoveEvent self.dispatch("reaction_remove", reaction, user) def parse_message_reaction_remove_emoji( - self, data: gateway.MessageReactionRemoveEmojiEvent + self, data: gateway.MessageReactionRemoveEmojiEvent ) -> None: emoji = data["emoji"] emoji_id = utils._get_as_snowflake(emoji, "id") @@ -1388,18 +1388,18 @@ def is_guild_evicted(self, guild) -> bool: @overload async def chunk_guild( - self, guild: Guild, *, wait: Literal[False], cache: Optional[bool] = None + self, guild: Guild, *, wait: Literal[False], cache: Optional[bool] = None ) -> asyncio.Future[List[Member]]: ... @overload async def chunk_guild( - self, guild: Guild, *, wait: Literal[True] = True, cache: Optional[bool] = None + self, guild: Guild, *, wait: Literal[True] = True, cache: Optional[bool] = None ) -> List[Member]: ... async def chunk_guild( - self, guild: Guild, *, wait: bool = True, cache: Optional[bool] = None + self, guild: Guild, *, wait: bool = True, cache: Optional[bool] = None ) -> Union[List[Member], asyncio.Future[List[Member]]]: cache = cache or self.member_cache_flags.joined request = self._chunk_requests.get(guild.id) @@ -1552,7 +1552,7 @@ def parse_guild_role_update(self, data: gateway.GuildRoleUpdateEvent) -> None: ) def parse_guild_scheduled_event_create( - self, data: gateway.GuildScheduledEventCreateEvent + self, data: gateway.GuildScheduledEventCreateEvent ) -> None: scheduled_event = GuildScheduledEvent(state=self, data=data) guild = scheduled_event.guild @@ -1561,7 +1561,7 @@ def parse_guild_scheduled_event_create( self.dispatch("guild_scheduled_event_create", scheduled_event) def parse_guild_scheduled_event_update( - self, data: gateway.GuildScheduledEventUpdateEvent + self, data: gateway.GuildScheduledEventUpdateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) @@ -1586,7 +1586,7 @@ def parse_guild_scheduled_event_update( ) def parse_guild_scheduled_event_delete( - self, data: gateway.GuildScheduledEventDeleteEvent + self, data: gateway.GuildScheduledEventDeleteEvent ) -> None: scheduled_event = GuildScheduledEvent(state=self, data=data) guild = scheduled_event.guild @@ -1595,7 +1595,7 @@ def parse_guild_scheduled_event_delete( self.dispatch("guild_scheduled_event_delete", scheduled_event) def parse_guild_scheduled_event_user_add( - self, data: gateway.GuildScheduledEventUserAddEvent + self, data: gateway.GuildScheduledEventUserAddEvent ) -> None: payload = RawGuildScheduledEventUserActionEvent(data) self.dispatch("raw_guild_scheduled_event_subscribe", payload) @@ -1612,7 +1612,7 @@ def parse_guild_scheduled_event_user_add( self.dispatch("guild_scheduled_event_subscribe", event, user) def parse_guild_scheduled_event_user_remove( - self, data: gateway.GuildScheduledEventUserRemoveEvent + self, data: gateway.GuildScheduledEventUserRemoveEvent ) -> None: payload = RawGuildScheduledEventUserActionEvent(data) self.dispatch("raw_guild_scheduled_event_unsubscribe", payload) @@ -1842,7 +1842,7 @@ def parse_typing_start(self, data: gateway.TypingStartEvent) -> None: self.dispatch("typing", channel, member, timestamp) def parse_auto_moderation_rule_create( - self, data: gateway.AutoModerationRuleCreateEvent + self, data: gateway.AutoModerationRuleCreateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1856,7 +1856,7 @@ def parse_auto_moderation_rule_create( self.dispatch("automod_rule_create", rule) def parse_auto_moderation_rule_update( - self, data: gateway.AutoModerationRuleUpdateEvent + self, data: gateway.AutoModerationRuleUpdateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1870,7 +1870,7 @@ def parse_auto_moderation_rule_update( self.dispatch("automod_rule_update", rule) def parse_auto_moderation_rule_delete( - self, data: gateway.AutoModerationRuleDeleteEvent + self, data: gateway.AutoModerationRuleDeleteEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1884,7 +1884,7 @@ def parse_auto_moderation_rule_delete( self.dispatch("automod_rule_delete", rule) def parse_auto_moderation_action_execution( - self, data: gateway.AutoModerationActionExecutionEvent + self, data: gateway.AutoModerationActionExecutionEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1932,7 +1932,7 @@ def parse_entitlement_delete(self, data: gateway.EntitlementDelete) -> None: self.dispatch("entitlement_delete", entitlement) def _get_reaction_user( - self, channel: MessageableChannel, user_id: int + self, channel: MessageableChannel, user_id: int ) -> Optional[Union[User, Member]]: if isinstance(channel, (TextChannel, VoiceChannel, Thread, StageChannel)): return channel.guild.get_member(user_id) @@ -1941,7 +1941,7 @@ def _get_reaction_user( # methods to handle all sorts of different emoji formats def _get_emoji_from_data( - self, data: PartialEmojiPayload + self, data: PartialEmojiPayload ) -> Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]: """Convert partial emoji data to proper emoji. Returns unicode emojis as strings. @@ -1968,12 +1968,12 @@ def _get_emoji_from_data( get_reaction_emoji = _get_emoji_from_data def _get_emoji_from_fields( - self, - *, - name: Optional[str], - id: Optional[int], - animated: Optional[bool] = False, - ) -> Optional[Union[Emoji, ApplicationEmoji ,PartialEmoji]]: + self, + *, + name: Optional[str], + id: Optional[int], + animated: Optional[bool] = False, + ) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: """Convert partial emoji fields to proper emoji, if possible. If both `id` and `name` are nullish, returns `None`. @@ -2022,10 +2022,10 @@ def get_channel(self, id: Optional[int]) -> Optional[Union[Channel, Thread]]: return channel def create_message( - self, - *, - channel: MessageableChannel, - data: MessagePayload, + self, + *, + channel: MessageableChannel, + data: MessagePayload, ) -> Message: return Message(state=self, channel=channel, data=data) @@ -2037,11 +2037,12 @@ def create_webhook(self, data: WebhookPayload) -> Webhook: # since there're no events related to application command updates async def fetch_global_commands( - self, - *, - with_localizations: bool = True, + self, + *, + with_localizations: bool = True, ) -> List[APIApplicationCommand]: - results = await self.http.get_global_commands(self.application_id, with_localizations=with_localizations) # type: ignore + results = await self.http.get_global_commands(self.application_id, + with_localizations=with_localizations) # type: ignore return [application_command_factory(data) for data in results] async def fetch_global_command(self, command_id: int) -> APIApplicationCommand: @@ -2049,7 +2050,7 @@ async def fetch_global_command(self, command_id: int) -> APIApplicationCommand: return application_command_factory(result) async def create_global_command( - self, application_command: ApplicationCommand + self, application_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.upsert_global_command( self.application_id, application_command.to_dict() # type: ignore @@ -2059,7 +2060,7 @@ async def create_global_command( return cmd async def edit_global_command( - self, command_id: int, new_command: ApplicationCommand + self, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.edit_global_command( self.application_id, command_id, new_command.to_dict() # type: ignore @@ -2073,7 +2074,7 @@ async def delete_global_command(self, command_id: int) -> None: self._remove_global_application_command(command_id) async def bulk_overwrite_global_commands( - self, application_commands: List[ApplicationCommand] + self, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: payload = [cmd.to_dict() for cmd in application_commands] results = await self.http.bulk_upsert_global_commands(self.application_id, payload) # type: ignore @@ -2084,12 +2085,13 @@ async def bulk_overwrite_global_commands( # Application commands (guild) async def fetch_guild_commands( - self, - guild_id: int, - *, - with_localizations: bool = True, + self, + guild_id: int, + *, + with_localizations: bool = True, ) -> List[APIApplicationCommand]: - results = await self.http.get_guild_commands(self.application_id, guild_id, with_localizations=with_localizations) # type: ignore + results = await self.http.get_guild_commands(self.application_id, guild_id, + with_localizations=with_localizations) # type: ignore return [application_command_factory(data) for data in results] async def fetch_guild_command(self, guild_id: int, command_id: int) -> APIApplicationCommand: @@ -2097,7 +2099,7 @@ async def fetch_guild_command(self, guild_id: int, command_id: int) -> APIApplic return application_command_factory(result) async def create_guild_command( - self, guild_id: int, application_command: ApplicationCommand + self, guild_id: int, application_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.upsert_guild_command( self.application_id, guild_id, application_command.to_dict() # type: ignore @@ -2107,7 +2109,7 @@ async def create_guild_command( return cmd async def edit_guild_command( - self, guild_id: int, command_id: int, new_command: ApplicationCommand + self, guild_id: int, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.edit_guild_command( self.application_id, guild_id, command_id, new_command.to_dict() # type: ignore @@ -2123,7 +2125,7 @@ async def delete_guild_command(self, guild_id: int, command_id: int) -> None: self._remove_guild_application_command(guild_id, command_id) async def bulk_overwrite_guild_commands( - self, guild_id: int, application_commands: List[ApplicationCommand] + self, guild_id: int, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: payload = [cmd.to_dict() for cmd in application_commands] results = await self.http.bulk_upsert_guild_commands( @@ -2136,7 +2138,7 @@ async def bulk_overwrite_guild_commands( # Application command permissions async def bulk_fetch_command_permissions( - self, guild_id: int + self, guild_id: int ) -> List[GuildApplicationCommandPermissions]: array = await self.http.get_guild_application_command_permissions( self.application_id, guild_id # type: ignore @@ -2144,7 +2146,7 @@ async def bulk_fetch_command_permissions( return [GuildApplicationCommandPermissions(state=self, data=obj) for obj in array] async def fetch_command_permissions( - self, guild_id: int, command_id: int + self, guild_id: int, command_id: int ) -> GuildApplicationCommandPermissions: data = await self.http.get_application_command_permissions( self.application_id, guild_id, command_id # type: ignore @@ -2201,14 +2203,14 @@ def _update_member_references(self) -> None: msg.author = new_author async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - shard_id: Optional[int] = None, - nonce: Optional[str] = None, + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + shard_id: Optional[int] = None, + nonce: Optional[str] = None, ) -> None: ws = self._get_websocket(guild_id, shard_id=shard_id) await ws.request_chunks( diff --git a/disnake/threads.py b/disnake/threads.py index 8095bbc9a3..b608442db9 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -28,7 +28,7 @@ from .abc import Snowflake, SnowflakeTime from .channel import CategoryChannel, ForumChannel, MediaChannel, TextChannel - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .guild import Guild from .member import Member from .message import Message, PartialMessage @@ -1157,14 +1157,14 @@ def __init__( self, *, name: str, - emoji: Optional[Union[str, PartialEmoji, Emoji]] = None, + emoji: Optional[Union[str, PartialEmoji, ApplicationEmoji, Emoji]] = None, moderated: bool = False, ) -> None: self.id: int = 0 self.name: str = name self.moderated: bool = moderated - self.emoji: Optional[Union[Emoji, PartialEmoji]] = None + self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]] = None if emoji is None: self.emoji = None elif isinstance(emoji, str): diff --git a/disnake/welcome_screen.py b/disnake/welcome_screen.py index a2e2fa171c..1cd15946ed 100644 --- a/disnake/welcome_screen.py +++ b/disnake/welcome_screen.py @@ -8,7 +8,7 @@ from .partial_emoji import PartialEmoji, _EmojiTag if TYPE_CHECKING: - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .guild import Guild from .invite import PartialInviteGuild from .state import ConnectionState @@ -51,11 +51,11 @@ def __init__( *, id: int, description: str, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, ) -> None: self.id: int = id self.description: str = description - self.emoji: Optional[Union[Emoji, PartialEmoji]] = None + self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]] = None if emoji is None: self.emoji = None elif isinstance(emoji, str): From 44b6b40cac6465167c35c41d3604e16b0907d7d2 Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 21:33:38 +0800 Subject: [PATCH 07/15] fix: Maybe the last attempt to resolve pyright test issues --- disnake/abc.py | 4 ++-- disnake/channel.py | 12 ++++++------ disnake/components.py | 4 ++-- disnake/guild.py | 6 +++--- disnake/partial_emoji.py | 4 ++-- disnake/threads.py | 2 +- disnake/ui/action_row.py | 2 +- disnake/ui/button.py | 10 +++++----- disnake/ui/select/string.py | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/disnake/abc.py b/disnake/abc.py index c0a5211698..803cc600c3 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -67,7 +67,7 @@ from .channel import CategoryChannel, DMChannel, PartialMessageable from .client import Client from .embeds import Embed - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .enums import InviteTarget from .guild import Guild, GuildMessageable from .guild_scheduled_event import GuildScheduledEvent @@ -338,7 +338,7 @@ async def _edit( video_quality_mode: VideoQualityMode = MISSING, flags: ChannelFlags = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, reason: Optional[str] = None, diff --git a/disnake/channel.py b/disnake/channel.py index f654cda67c..1a84620b46 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -3932,7 +3932,7 @@ async def edit( flags: ChannelFlags = ..., require_tag: bool = ..., available_tags: Sequence[ForumTag] = ..., - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = ..., + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = ..., default_sort_order: Optional[ThreadSortOrder] = ..., default_layout: ThreadLayout = ..., reason: Optional[str] = ..., @@ -3955,7 +3955,7 @@ async def edit( flags: ChannelFlags = MISSING, require_tag: bool = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, reason: Optional[str] = None, @@ -4102,7 +4102,7 @@ async def clone( default_thread_slowmode_delay: Optional[int] = MISSING, default_auto_archive_duration: Optional[AnyThreadArchiveDuration] = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, overwrites: Mapping[Union[Role, Member], PermissionOverwrite] = MISSING, @@ -4362,7 +4362,7 @@ async def edit( flags: ChannelFlags = ..., require_tag: bool = ..., available_tags: Sequence[ForumTag] = ..., - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = ..., + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = ..., default_sort_order: Optional[ThreadSortOrder] = ..., reason: Optional[str] = ..., ) -> MediaChannel: @@ -4384,7 +4384,7 @@ async def edit( flags: ChannelFlags = MISSING, require_tag: bool = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, reason: Optional[str] = None, **kwargs: Never, @@ -4503,7 +4503,7 @@ async def clone( default_thread_slowmode_delay: Optional[int] = MISSING, default_auto_archive_duration: Optional[AnyThreadArchiveDuration] = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, overwrites: Mapping[Union[Role, Member], PermissionOverwrite] = MISSING, reason: Optional[str] = None, diff --git a/disnake/components.py b/disnake/components.py index 7614fd424b..e75f60d9ca 100644 --- a/disnake/components.py +++ b/disnake/components.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: from typing_extensions import Self, TypeAlias - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .types.components import ( ActionRow as ActionRowPayload, AnySelectMenu as AnySelectMenuPayload, @@ -546,7 +546,7 @@ def __init__( label: str, value: str = MISSING, description: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, default: bool = False, ) -> None: self.label = label diff --git a/disnake/guild.py b/disnake/guild.py index 301d926876..e10ecd0fae 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -40,7 +40,7 @@ _threaded_guild_channel_factory, ) from .colour import Colour -from .emoji import Emoji +from .emoji import Emoji, ApplicationEmoji from .enums import ( AuditLogAction, AutoModEventType, @@ -1643,7 +1643,7 @@ async def create_forum_channel( nsfw: bool = MISSING, overwrites: Dict[Union[Role, Member], PermissionOverwrite] = MISSING, available_tags: Optional[Sequence[ForumTag]] = None, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = None, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, default_sort_order: Optional[ThreadSortOrder] = None, default_layout: Optional[ThreadLayout] = None, reason: Optional[str] = None, @@ -1793,7 +1793,7 @@ async def create_media_channel( nsfw: bool = MISSING, overwrites: Dict[Union[Role, Member], PermissionOverwrite] = MISSING, available_tags: Optional[Sequence[ForumTag]] = None, - default_reaction: Optional[Union[str, Emoji, PartialEmoji]] = None, + default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, default_sort_order: Optional[ThreadSortOrder] = None, reason: Optional[str] = None, ) -> MediaChannel: diff --git a/disnake/partial_emoji.py b/disnake/partial_emoji.py index 92656bb314..dc9f70ab5d 100644 --- a/disnake/partial_emoji.py +++ b/disnake/partial_emoji.py @@ -15,7 +15,7 @@ from typing_extensions import Self - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .state import ConnectionState from .types.activity import ActivityEmoji as ActivityEmojiPayload from .types.emoji import Emoji as EmojiPayload, PartialEmoji as PartialEmojiPayload @@ -254,7 +254,7 @@ async def read(self) -> bytes: # (e.g. default reaction, tag emoji) @staticmethod def _emoji_to_name_id( - emoji: Optional[Union[str, Emoji, PartialEmoji]] + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] ) -> Tuple[Optional[str], Optional[int]]: if emoji is None: return None, None diff --git a/disnake/threads.py b/disnake/threads.py index b608442db9..d378408519 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -1225,7 +1225,7 @@ def with_changes( self, *, name: str = MISSING, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = MISSING, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, moderated: bool = MISSING, ) -> Self: """Returns a new instance with the given changes applied, diff --git a/disnake/ui/action_row.py b/disnake/ui/action_row.py index 21ea01cb74..ca9a3c41fe 100644 --- a/disnake/ui/action_row.py +++ b/disnake/ui/action_row.py @@ -245,7 +245,7 @@ def add_button( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, ) -> ButtonCompatibleActionRowT: """Add a button to the action row. Can only be used if the action row holds message components. diff --git a/disnake/ui/button.py b/disnake/ui/button.py index a961ba29ab..032bff70e3 100644 --- a/disnake/ui/button.py +++ b/disnake/ui/button.py @@ -92,7 +92,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: ... @@ -106,7 +106,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: ... @@ -119,7 +119,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: super().__init__() @@ -217,7 +217,7 @@ def emoji(self) -> Optional[PartialEmoji]: return self._underlying.emoji @emoji.setter - def emoji(self, value: Optional[Union[str, Emoji, PartialEmoji]]) -> None: + def emoji(self, value: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]) -> None: if value is not None: if isinstance(value, str): self._underlying.emoji = PartialEmoji.from_str(value) @@ -261,7 +261,7 @@ def button( custom_id: Optional[str] = None, disabled: bool = False, style: ButtonStyle = ButtonStyle.secondary, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> Callable[[ItemCallbackType[Button[V_co]]], DecoratedItem[Button[V_co]]]: ... diff --git a/disnake/ui/select/string.py b/disnake/ui/select/string.py index 3eeedc1f22..3c71129152 100644 --- a/disnake/ui/select/string.py +++ b/disnake/ui/select/string.py @@ -181,7 +181,7 @@ def add_option( label: str, value: str = MISSING, description: Optional[str] = None, - emoji: Optional[Union[str, Emoji, PartialEmoji]] = None, + emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, default: bool = False, ) -> None: """Adds an option to the select menu. From 8f3c26ee245e400f50f038771d1e085e42d7c4aa Mon Sep 17 00:00:00 2001 From: Mantou Date: Fri, 19 Jul 2024 21:45:11 +0800 Subject: [PATCH 08/15] fix: forgot to import ApplicationButton --- disnake/reaction.py | 4 ++-- disnake/state.py | 20 +++++++++----------- disnake/ui/action_row.py | 2 +- disnake/ui/button.py | 2 +- disnake/ui/select/string.py | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/disnake/reaction.py b/disnake/reaction.py index 0720759f6a..eb781da2eb 100644 --- a/disnake/reaction.py +++ b/disnake/reaction.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import Emoji + from .emoji import Emoji, ApplicationEmoji from .message import Message from .partial_emoji import PartialEmoji from .types.message import Reaction as ReactionPayload @@ -61,7 +61,7 @@ def __init__( *, message: Message, data: ReactionPayload, - emoji: Optional[Union[PartialEmoji, Emoji, str]] = None, + emoji: Optional[Union[PartialEmoji, Emoji, ApplicationEmoji,str]] = None, ) -> None: self.message: Message = message # _get_emoji_from_data won't return None diff --git a/disnake/state.py b/disnake/state.py index 2da4349702..0989634b36 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -2037,12 +2037,11 @@ def create_webhook(self, data: WebhookPayload) -> Webhook: # since there're no events related to application command updates async def fetch_global_commands( - self, - *, - with_localizations: bool = True, + self, + *, + with_localizations: bool = True, ) -> List[APIApplicationCommand]: - results = await self.http.get_global_commands(self.application_id, - with_localizations=with_localizations) # type: ignore + results = await self.http.get_global_commands(self.application_id, with_localizations=with_localizations) # type: ignore return [application_command_factory(data) for data in results] async def fetch_global_command(self, command_id: int) -> APIApplicationCommand: @@ -2085,13 +2084,12 @@ async def bulk_overwrite_global_commands( # Application commands (guild) async def fetch_guild_commands( - self, - guild_id: int, - *, - with_localizations: bool = True, + self, + guild_id: int, + *, + with_localizations: bool = True, ) -> List[APIApplicationCommand]: - results = await self.http.get_guild_commands(self.application_id, guild_id, - with_localizations=with_localizations) # type: ignore + results = await self.http.get_guild_commands(self.application_id, guild_id, with_localizations=with_localizations) # type: ignore return [application_command_factory(data) for data in results] async def fetch_guild_command(self, guild_id: int, command_id: int) -> APIApplicationCommand: diff --git a/disnake/ui/action_row.py b/disnake/ui/action_row.py index ca9a3c41fe..0d045d5330 100644 --- a/disnake/ui/action_row.py +++ b/disnake/ui/action_row.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ..emoji import Emoji + from ..emoji import Emoji, ApplicationEmoji from ..message import Message from ..partial_emoji import PartialEmoji from ..types.components import ActionRow as ActionRowPayload diff --git a/disnake/ui/button.py b/disnake/ui/button.py index 032bff70e3..79d9f91bea 100644 --- a/disnake/ui/button.py +++ b/disnake/ui/button.py @@ -31,7 +31,7 @@ if TYPE_CHECKING: from typing_extensions import ParamSpec, Self - from ..emoji import Emoji + from ..emoji import Emoji, ApplicationEmoji from .item import ItemCallbackType from .view import View diff --git a/disnake/ui/select/string.py b/disnake/ui/select/string.py index 3c71129152..d4972a69ca 100644 --- a/disnake/ui/select/string.py +++ b/disnake/ui/select/string.py @@ -24,7 +24,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ...emoji import Emoji + from ...emoji import Emoji, ApplicationEmoji from ...partial_emoji import PartialEmoji from ..item import DecoratedItem, ItemCallbackType, Object From 81f2c1e0bf5dca062f71a89be35204f6ebd3aef8 Mon Sep 17 00:00:00 2001 From: Mantou Date: Sat, 20 Jul 2024 16:01:03 +0800 Subject: [PATCH 09/15] docs: temporary emojis docs --- disnake/emoji.py | 22 ++++++++++++++-------- docs/api/emoji.rst | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/disnake/emoji.py b/disnake/emoji.py index 488eee894d..9c0c41d9fb 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -9,7 +9,7 @@ from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ("Emoji", "GuildEmoji", "ApplicationEmoji") +__all__ = ("BaseEmoji", "Emoji", "GuildEmoji", "ApplicationEmoji") if TYPE_CHECKING: from datetime import datetime @@ -23,10 +23,14 @@ class BaseEmoji(_EmojiTag, AssetMixin): - """Represents a custom emoji. + """Represents an abstract custom emoji. - Depending on the way this object was created, some of the attributes can - have a value of ``None``. + This is usually represented as a custom emoji. + + This isn’t meant to be used directly, instead use one of the concrete custom emoji types: + + - :class:`GuildEmoji` + - :class:`ApplicationEmoji` .. collapse:: operations @@ -146,6 +150,8 @@ class GuildEmoji(BaseEmoji): Depending on the way this object was created, some of the attributes can have a value of ``None``. + This is an alias for :class:`Emoji`. + .. collapse:: operations .. describe:: x == y @@ -256,7 +262,7 @@ async def delete(self, *, reason: Optional[str] = None) -> None: await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) async def edit( - self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None + self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None ) -> GuildEmoji: """|coro| @@ -385,9 +391,9 @@ async def delete(self) -> None: self._state._remove_emoji(self) async def edit( - self, - *, - name: str = MISSING, + self, + *, + name: str = MISSING, ) -> ApplicationEmoji: r"""|coro| Edits the application emoji. diff --git a/docs/api/emoji.rst b/docs/api/emoji.rst index 3b4756d85b..b14070637d 100644 --- a/docs/api/emoji.rst +++ b/docs/api/emoji.rst @@ -2,26 +2,51 @@ .. currentmodule:: disnake -Emoji -===== +Emojis +====== This section documents everything related to Discord :ddocs:`emoji `. Discord Models ---------------- +-------------- Emoji ~~~~~ -.. attributetable:: Emoji +.. autoclass:: Emoji + :members: + :inherited-members: + +BaseEmoji +~~~~~~~~~ + +.. attributetable:: BaseEmoji + +.. autoclass:: BaseEmoji + :members: + :inherited-members: + +GuildEmoji +~~~~~~~~~~ + +.. attributetable:: GuildEmoji + +.. autoclass:: GuildEmoji + :members: + :inherited-members: + +ApplicationEmoji +~~~~~~~~~~~~~~~~~ + +.. attributetable:: ApplicationEmoji -.. autoclass:: Emoji() +.. autoclass:: ApplicationEmoji :members: :inherited-members: Data Classes -------------- +------------ PartialEmoji ~~~~~~~~~~~~ @@ -35,4 +60,4 @@ PartialEmoji Events ------ -- :func:`on_guild_emojis_update(guild, before, after) ` +- :func:`on_guild_emojis_update(guild, before, after) ` \ No newline at end of file From 86f7c4a34b2040352a0e5db7f05cf9ebfa905630 Mon Sep 17 00:00:00 2001 From: Mantou Date: Sat, 20 Jul 2024 16:10:17 +0800 Subject: [PATCH 10/15] docs: try to solve docs problem --- disnake/emoji.py | 7 ++++++- docs/api/emoji.rst | 47 +++++++++++++++++++--------------------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/disnake/emoji.py b/disnake/emoji.py index 9c0c41d9fb..1554f59d8e 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -27,7 +27,7 @@ class BaseEmoji(_EmojiTag, AssetMixin): This is usually represented as a custom emoji. - This isn’t meant to be used directly, instead use one of the concrete custom emoji types: + This isn't meant to be used directly, instead use one of the concrete custom emoji types: - :class:`GuildEmoji` - :class:`ApplicationEmoji` @@ -311,6 +311,11 @@ async def edit( return GuildEmoji(guild=self.guild, data=data, state=self._state) +class Emoji(GuildEmoji): + def __init__(self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload): + super().__init__(guild=guild, state=state, data=data) + + Emoji = GuildEmoji diff --git a/docs/api/emoji.rst b/docs/api/emoji.rst index b14070637d..4ea7b62cd7 100644 --- a/docs/api/emoji.rst +++ b/docs/api/emoji.rst @@ -2,48 +2,39 @@ .. currentmodule:: disnake -Emojis -====== - -This section documents everything related to Discord -:ddocs:`emoji `. - -Discord Models --------------- - Emoji ~~~~~ -.. autoclass:: Emoji - :members: - :inherited-members: +.. autoclass:: disnake.Emoji + :members: + :inherited-members: BaseEmoji ~~~~~~~~~ -.. attributetable:: BaseEmoji +.. autoclass:: disnake.BaseEmoji + :members: + :inherited-members: -.. autoclass:: BaseEmoji - :members: - :inherited-members: +.. attributetable:: BaseEmoji GuildEmoji ~~~~~~~~~~ -.. attributetable:: GuildEmoji +.. autoclass:: disnake.GuildEmoji + :members: + :inherited-members: -.. autoclass:: GuildEmoji - :members: - :inherited-members: +.. attributetable:: GuildEmoji ApplicationEmoji ~~~~~~~~~~~~~~~~~ -.. attributetable:: ApplicationEmoji +.. autoclass:: disnake.ApplicationEmoji + :members: + :inherited-members: -.. autoclass:: ApplicationEmoji - :members: - :inherited-members: +.. attributetable:: ApplicationEmoji Data Classes ------------ @@ -51,11 +42,11 @@ Data Classes PartialEmoji ~~~~~~~~~~~~ -.. attributetable:: PartialEmoji +.. autoclass:: disnake.PartialEmoji + :members: + :inherited-members: -.. autoclass:: PartialEmoji - :members: - :inherited-members: +.. attributetable:: PartialEmoji Events ------ From 6f4687409017c6430e0f89f727ddfcc128ec5155 Mon Sep 17 00:00:00 2001 From: Mantou Date: Sat, 20 Jul 2024 16:12:40 +0800 Subject: [PATCH 11/15] fix: Remove the additional Emojis class --- disnake/emoji.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/disnake/emoji.py b/disnake/emoji.py index 1554f59d8e..38148e9c69 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -311,11 +311,6 @@ async def edit( return GuildEmoji(guild=self.guild, data=data, state=self._state) -class Emoji(GuildEmoji): - def __init__(self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload): - super().__init__(guild=guild, state=state, data=data) - - Emoji = GuildEmoji From ee42cab63289480b5239b77be56c2c53da7de3b4 Mon Sep 17 00:00:00 2001 From: Mantou Date: Sat, 20 Jul 2024 17:53:58 +0800 Subject: [PATCH 12/15] fix: Try to pass as many of the currently failing tests as possible. --- disnake/abc.py | 2 +- disnake/audit_logs.py | 2 +- disnake/channel.py | 4 +- disnake/client.py | 22 +- disnake/components.py | 2 +- disnake/emoji.py | 16 +- disnake/guild.py | 2 +- disnake/http.py | 4 +- disnake/message.py | 2 +- disnake/onboarding.py | 2 +- disnake/partial_emoji.py | 2 +- disnake/reaction.py | 4 +- disnake/state.py | 204 +++++++++--------- disnake/threads.py | 2 +- disnake/types/emoji.py | 2 +- disnake/ui/action_row.py | 4 +- disnake/ui/button.py | 8 +- disnake/ui/select/string.py | 6 +- disnake/welcome_screen.py | 2 +- docs/api/emoji.rst | 13 +- docs/conf.py | 2 +- docs/locale/ja/LC_MESSAGES/api.po | 8 +- .../locale/ja/LC_MESSAGES/ext/commands/api.po | 8 +- 23 files changed, 171 insertions(+), 152 deletions(-) diff --git a/disnake/abc.py b/disnake/abc.py index 803cc600c3..c021def827 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -67,7 +67,7 @@ from .channel import CategoryChannel, DMChannel, PartialMessageable from .client import Client from .embeds import Embed - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .enums import InviteTarget from .guild import Guild, GuildMessageable from .guild_scheduled_event import GuildScheduledEvent diff --git a/disnake/audit_logs.py b/disnake/audit_logs.py index 12b78e8a44..106759715f 100644 --- a/disnake/audit_logs.py +++ b/disnake/audit_logs.py @@ -43,7 +43,7 @@ from .app_commands import APIApplicationCommand from .automod import AutoModRule - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .guild import Guild from .guild_scheduled_event import GuildScheduledEvent from .integrations import PartialIntegration diff --git a/disnake/channel.py b/disnake/channel.py index 1a84620b46..c390fa19fb 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -69,7 +69,7 @@ from .abc import Snowflake, SnowflakeTime from .asset import AssetBytes from .embeds import Embed - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .guild import Guild, GuildChannel as GuildChannelType from .member import Member, VoiceState from .message import AllowedMentions, Message, PartialMessage @@ -3314,7 +3314,7 @@ def requires_tag(self) -> bool: return self.flags.require_tag @property - def default_reaction(self) -> Optional[Union[Emoji, ApplicationEmoji ,PartialEmoji]]: + def default_reaction(self) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: """Optional[Union[:class:`Emoji`, :class:`PartialEmoji`]]: The default emoji shown for reacting to threads. diff --git a/disnake/client.py b/disnake/client.py index bec283a3b3..4e5c23e0bb 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -373,6 +373,9 @@ class Client: application commands. .. versionadded:: 2.5 + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. + Defaults to ``False``. """ def __init__( @@ -567,7 +570,7 @@ def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: """The emojis that the connected client has. .. note:: - This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is + This only includes the application's emojis if :attr:`.cache_app_emojis` is ``True``. """ return self._connection.emojis @@ -1493,7 +1496,7 @@ def get_emoji(self, id: int, /) -> Optional[Union[GuildEmoji, ApplicationEmoji]] Returns ------- - Optional[:class:`.Emoji`] + Optional[Union[:class:`disnake.emoji.GuildEmoji`, :class:`disnake.emoji.ApplicationEmoji`]] The custom emoji or ``None`` if not found. """ return self._connection.get_emoji(id) @@ -3223,7 +3226,7 @@ async def create_entitlement( async def fetch_application_emojis(self) -> list[ApplicationEmoji]: r"""|coro| - Retrieves all custom :class:`ApplicationEmoji`\s from the application. + Retrieves all custom :class:`disnake.emoji.ApplicationEmoji`\s from the application. Raises ------ @@ -3232,17 +3235,18 @@ async def fetch_application_emojis(self) -> list[ApplicationEmoji]: Returns ------- - List[:class:`ApplicationEmoji`] + List[:class:`disnake.emoji.ApplicationEmoji`] The retrieved emojis. """ emojis = await self._connection.http.get_all_application_emojis(self.application_id) return [ - self._connection.store_application_emoji(self.application_id, e) for e in emojis['items'] + self._connection.store_application_emoji(self.application_id, e) + for e in emojis["items"] ] async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: """|coro| - Retrieves a custom :class:`ApplicationEmoji` from the application. + Retrieves a custom :class:`disnake.emoji.ApplicationEmoji` from the application. Parameters ---------- @@ -3251,7 +3255,7 @@ async def fetch_application_emoji(self, emoji_id: int, /) -> ApplicationEmoji: Returns ------- - :class:`ApplicationEmoji` + :class:`disnake.emoji.ApplicationEmoji` The retrieved emoji. Raises @@ -3271,7 +3275,7 @@ async def create_application_emoji( image: bytes, ) -> ApplicationEmoji: r"""|coro| - Creates a custom :class:`ApplicationEmoji` for the application. + Creates a custom :class:`disnake.emoji.ApplicationEmoji` for the application. There is currently a limit of 2000 emojis per application. Parameters @@ -3291,7 +3295,7 @@ async def create_application_emoji( Returns ------- - :class:`ApplicationEmoji` + :class:`disnake.emoji.ApplicationEmoji` The created emoji. """ img = utils._bytes_to_base64_data(image) diff --git a/disnake/components.py b/disnake/components.py index e75f60d9ca..081854308b 100644 --- a/disnake/components.py +++ b/disnake/components.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: from typing_extensions import Self, TypeAlias - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .types.components import ( ActionRow as ActionRowPayload, AnySelectMenu as AnySelectMenuPayload, diff --git a/disnake/emoji.py b/disnake/emoji.py index 38148e9c69..3bc95ca9da 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -197,7 +197,9 @@ class GuildEmoji(BaseEmoji): having the :attr:`~Permissions.manage_guild_expressions` permission. """ - def __init__(self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload): + def __init__( + self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload + ) -> None: self.guild_id: int = guild.id super().__init__(state=state, data=data) @@ -262,7 +264,7 @@ async def delete(self, *, reason: Optional[str] = None) -> None: await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) async def edit( - self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None + self, *, name: str = MISSING, roles: List[Snowflake] = MISSING, reason: Optional[str] = None ) -> GuildEmoji: """|coro| @@ -363,11 +365,11 @@ class ApplicationEmoji(BaseEmoji): The user that created the emoji. """ - def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload): + def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload) -> None: self.application_id: int = application_id super().__init__(state=state, data=data) - def __repr__(self): + def __repr__(self) -> str: return f"" def is_usable(self) -> bool: @@ -391,9 +393,9 @@ async def delete(self) -> None: self._state._remove_emoji(self) async def edit( - self, - *, - name: str = MISSING, + self, + *, + name: str = MISSING, ) -> ApplicationEmoji: r"""|coro| Edits the application emoji. diff --git a/disnake/guild.py b/disnake/guild.py index e10ecd0fae..52dd3e3b46 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -40,7 +40,7 @@ _threaded_guild_channel_factory, ) from .colour import Colour -from .emoji import Emoji, ApplicationEmoji +from .emoji import ApplicationEmoji, Emoji from .enums import ( AuditLogAction, AutoModEventType, diff --git a/disnake/http.py b/disnake/http.py index 69b9242d78..985d98fd4e 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -1709,7 +1709,9 @@ def edit_custom_emoji( ) return self.request(r, json=payload, reason=reason) - def get_all_application_emojis(self, application_id: Snowflake) -> Response[Dict[str, List[emoji.Emoji]]]: + def get_all_application_emojis( + self, application_id: Snowflake + ) -> Response[Dict[str, List[emoji.Emoji]]]: return self.request( Route("GET", "/applications/{application_id}/emojis", application_id=application_id) ) diff --git a/disnake/message.py b/disnake/message.py index 7503fe98ff..7cdef7a6aa 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -25,7 +25,7 @@ from . import utils from .components import ActionRow, MessageComponent, _component_factory from .embeds import Embed -from .emoji import Emoji, ApplicationEmoji +from .emoji import ApplicationEmoji, Emoji from .enums import ChannelType, InteractionType, MessageType, try_enum, try_enum_to_int from .errors import HTTPException from .file import File diff --git a/disnake/onboarding.py b/disnake/onboarding.py index c114649d38..97b42e72fc 100644 --- a/disnake/onboarding.py +++ b/disnake/onboarding.py @@ -7,7 +7,7 @@ from .mixins import Hashable if TYPE_CHECKING: - from .emoji import Emoji, PartialEmoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji, PartialEmoji from .guild import Guild, GuildChannel from .role import Role from .types.onboarding import ( diff --git a/disnake/partial_emoji.py b/disnake/partial_emoji.py index dc9f70ab5d..f9b03510b7 100644 --- a/disnake/partial_emoji.py +++ b/disnake/partial_emoji.py @@ -15,7 +15,7 @@ from typing_extensions import Self - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .state import ConnectionState from .types.activity import ActivityEmoji as ActivityEmojiPayload from .types.emoji import Emoji as EmojiPayload, PartialEmoji as PartialEmojiPayload diff --git a/disnake/reaction.py b/disnake/reaction.py index eb781da2eb..1663aa1d65 100644 --- a/disnake/reaction.py +++ b/disnake/reaction.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .message import Message from .partial_emoji import PartialEmoji from .types.message import Reaction as ReactionPayload @@ -61,7 +61,7 @@ def __init__( *, message: Message, data: ReactionPayload, - emoji: Optional[Union[PartialEmoji, Emoji, ApplicationEmoji,str]] = None, + emoji: Optional[Union[PartialEmoji, Emoji, ApplicationEmoji, str]] = None, ) -> None: self.message: Message = message # _get_emoji_from_data won't return None diff --git a/disnake/state.py b/disnake/state.py index 0989634b36..9c653f0f17 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -113,12 +113,12 @@ class ChunkRequest: def __init__( - self, - guild_id: int, - loop: asyncio.AbstractEventLoop, - resolver: Callable[[int], Any], - *, - cache: bool = True, + self, + guild_id: int, + loop: asyncio.AbstractEventLoop, + resolver: Callable[[int], Any], + *, + cache: bool = True, ) -> None: self.guild_id: int = guild_id self.resolver: Callable[[int], Any] = resolver @@ -187,24 +187,24 @@ class ConnectionState: _parsers: Dict[str, Callable[[Dict[str, Any]], None]] def __init__( - self, - *, - dispatch: Callable, - handlers: Dict[str, Callable], - hooks: Dict[str, Callable], - http: HTTPClient, - loop: asyncio.AbstractEventLoop, - max_messages: Optional[int] = 1000, - application_id: Optional[int] = None, - heartbeat_timeout: float = 60.0, - guild_ready_timeout: float = 2.0, - allowed_mentions: Optional[AllowedMentions] = None, - activity: Optional[BaseActivity] = None, - status: Optional[Union[str, Status]] = None, - intents: Optional[Intents] = None, - chunk_guilds_at_startup: Optional[bool] = None, - member_cache_flags: Optional[MemberCacheFlags] = None, - cache_app_emojis: bool = False, + self, + *, + dispatch: Callable, + handlers: Dict[str, Callable], + hooks: Dict[str, Callable], + http: HTTPClient, + loop: asyncio.AbstractEventLoop, + max_messages: Optional[int] = 1000, + application_id: Optional[int] = None, + heartbeat_timeout: float = 60.0, + guild_ready_timeout: float = 2.0, + allowed_mentions: Optional[AllowedMentions] = None, + activity: Optional[BaseActivity] = None, + status: Optional[Union[str, Status]] = None, + intents: Optional[Intents] = None, + chunk_guilds_at_startup: Optional[bool] = None, + member_cache_flags: Optional[MemberCacheFlags] = None, + cache_app_emojis: bool = False, ) -> None: self.loop: asyncio.AbstractEventLoop = loop self.http: HTTPClient = http @@ -288,7 +288,7 @@ def __init__( self.clear() def clear( - self, *, views: bool = True, application_commands: bool = True, modals: bool = True + self, *, views: bool = True, application_commands: bool = True, modals: bool = True ) -> None: self.user: ClientUser = MISSING # NOTE: without weakrefs, these user objects would otherwise be kept in memory indefinitely. @@ -322,7 +322,7 @@ def clear( self._messages: Optional[Deque[Message]] = None def process_chunk_requests( - self, guild_id: int, nonce: Optional[str], members: List[Member], complete: bool + self, guild_id: int, nonce: Optional[str], members: List[Member], complete: bool ) -> None: removed = [] for key, request in self._chunk_requests.items(): @@ -453,14 +453,14 @@ def _remove_guild(self, guild: Guild) -> None: del guild def _get_global_application_command( - self, application_command_id: int + self, application_command_id: int ) -> Optional[APIApplicationCommand]: return self._global_application_commands.get(application_command_id) def _add_global_application_command( - self, - application_command: APIApplicationCommand, - /, + self, + application_command: APIApplicationCommand, + /, ) -> None: if not application_command.id: AssertionError("The provided application command does not have an ID") @@ -473,14 +473,14 @@ def _clear_global_application_commands(self) -> None: self._global_application_commands.clear() def _get_guild_application_command( - self, guild_id: int, application_command_id: int + self, guild_id: int, application_command_id: int ) -> Optional[APIApplicationCommand]: granula = self._guild_application_commands.get(guild_id) if granula is not None: return granula.get(application_command_id) def _add_guild_application_command( - self, guild_id: int, application_command: APIApplicationCommand + self, guild_id: int, application_command: APIApplicationCommand ) -> None: if not application_command.id: AssertionError("The provided application command does not have an ID") @@ -503,14 +503,14 @@ def _clear_guild_application_commands(self, guild_id: int) -> None: self._guild_application_commands.pop(guild_id, None) def _get_global_command_named( - self, name: str, cmd_type: Optional[ApplicationCommandType] = None + self, name: str, cmd_type: Optional[ApplicationCommandType] = None ) -> Optional[APIApplicationCommand]: for cmd in self._global_application_commands.values(): if cmd.name == name and (cmd_type is None or cmd.type is cmd_type): return cmd def _get_guild_command_named( - self, guild_id: int, name: str, cmd_type: Optional[ApplicationCommandType] = None + self, guild_id: int, name: str, cmd_type: Optional[ApplicationCommandType] = None ) -> Optional[APIApplicationCommand]: granula = self._guild_application_commands.get(guild_id, {}) for cmd in granula.values(): @@ -597,14 +597,14 @@ def _add_guild_from_data(self, data: Union[GuildPayload, UnavailableGuildPayload def _guild_needs_chunking(self, guild: Guild) -> bool: # If presences are enabled then we get back the old guild.large behaviour return ( - self._chunk_guilds - and not guild.chunked - and not (self._intents.presences and not guild.large) + self._chunk_guilds + and not guild.chunked + and not (self._intents.presences and not guild.large) ) def _get_guild_channel( - self, - data: Union[MessagePayload, gateway.TypingStartEvent], + self, + data: Union[MessagePayload, gateway.TypingStartEvent], ) -> Tuple[Union[PartialChannel, Thread], Optional[Guild]]: channel_id = int(data["channel_id"]) try: @@ -627,13 +627,13 @@ def _get_guild_channel( return channel or PartialMessageable(state=self, id=channel_id), guild async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - nonce: Optional[str] = None, + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + nonce: Optional[str] = None, ) -> None: ws = self._get_websocket(guild_id) # This is ignored upstream await ws.request_chunks( @@ -641,13 +641,13 @@ async def chunker( ) async def query_members( - self, - guild: Guild, - query: Optional[str], - limit: int, - user_ids: Optional[List[int]], - cache: bool, - presences: bool, + self, + guild: Guild, + query: Optional[str], + limit: int, + user_ids: Optional[List[int]], + cache: bool, + presences: bool, ): guild_id = guild.id ws = self._get_websocket(guild_id) @@ -757,7 +757,7 @@ def parse_resumed(self, data: gateway.ResumedEvent) -> None: self.dispatch("resumed") def parse_application_command_permissions_update( - self, data: gateway.ApplicationCommandPermissionsUpdateEvent + self, data: gateway.ApplicationCommandPermissionsUpdateEvent ) -> None: app_command_perms = GuildApplicationCommandPermissions(data=data, state=self) self.dispatch("application_command_permissions_update", app_command_perms) @@ -779,11 +779,11 @@ def parse_message_create(self, data: gateway.MessageCreateEvent) -> None: # - or, they're the initial message of a forum channel thread (which uses MessageType.default) # This mirrors the current client and API behavior. if channel.__class__ is Thread and not ( - message.type is MessageType.thread_starter_message - or ( - type(channel.parent) in (ForumChannel, MediaChannel) # type: ignore - and channel.id == message.id - ) + message.type is MessageType.thread_starter_message + or ( + type(channel.parent) in (ForumChannel, MediaChannel) # type: ignore + and channel.id == message.id + ) ): channel.total_message_sent += 1 # type: ignore channel.message_count += 1 # type: ignore @@ -880,7 +880,7 @@ def parse_message_reaction_add(self, data: gateway.MessageReactionAddEvent) -> N self.dispatch("reaction_add", reaction, user) def parse_message_reaction_remove_all( - self, data: gateway.MessageReactionRemoveAllEvent + self, data: gateway.MessageReactionRemoveAllEvent ) -> None: raw = RawReactionClearEvent(data) self.dispatch("raw_reaction_clear", raw) @@ -918,7 +918,7 @@ def parse_message_reaction_remove(self, data: gateway.MessageReactionRemoveEvent self.dispatch("reaction_remove", reaction, user) def parse_message_reaction_remove_emoji( - self, data: gateway.MessageReactionRemoveEmojiEvent + self, data: gateway.MessageReactionRemoveEmojiEvent ) -> None: emoji = data["emoji"] emoji_id = utils._get_as_snowflake(emoji, "id") @@ -1388,18 +1388,18 @@ def is_guild_evicted(self, guild) -> bool: @overload async def chunk_guild( - self, guild: Guild, *, wait: Literal[False], cache: Optional[bool] = None + self, guild: Guild, *, wait: Literal[False], cache: Optional[bool] = None ) -> asyncio.Future[List[Member]]: ... @overload async def chunk_guild( - self, guild: Guild, *, wait: Literal[True] = True, cache: Optional[bool] = None + self, guild: Guild, *, wait: Literal[True] = True, cache: Optional[bool] = None ) -> List[Member]: ... async def chunk_guild( - self, guild: Guild, *, wait: bool = True, cache: Optional[bool] = None + self, guild: Guild, *, wait: bool = True, cache: Optional[bool] = None ) -> Union[List[Member], asyncio.Future[List[Member]]]: cache = cache or self.member_cache_flags.joined request = self._chunk_requests.get(guild.id) @@ -1552,7 +1552,7 @@ def parse_guild_role_update(self, data: gateway.GuildRoleUpdateEvent) -> None: ) def parse_guild_scheduled_event_create( - self, data: gateway.GuildScheduledEventCreateEvent + self, data: gateway.GuildScheduledEventCreateEvent ) -> None: scheduled_event = GuildScheduledEvent(state=self, data=data) guild = scheduled_event.guild @@ -1561,7 +1561,7 @@ def parse_guild_scheduled_event_create( self.dispatch("guild_scheduled_event_create", scheduled_event) def parse_guild_scheduled_event_update( - self, data: gateway.GuildScheduledEventUpdateEvent + self, data: gateway.GuildScheduledEventUpdateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) @@ -1586,7 +1586,7 @@ def parse_guild_scheduled_event_update( ) def parse_guild_scheduled_event_delete( - self, data: gateway.GuildScheduledEventDeleteEvent + self, data: gateway.GuildScheduledEventDeleteEvent ) -> None: scheduled_event = GuildScheduledEvent(state=self, data=data) guild = scheduled_event.guild @@ -1595,7 +1595,7 @@ def parse_guild_scheduled_event_delete( self.dispatch("guild_scheduled_event_delete", scheduled_event) def parse_guild_scheduled_event_user_add( - self, data: gateway.GuildScheduledEventUserAddEvent + self, data: gateway.GuildScheduledEventUserAddEvent ) -> None: payload = RawGuildScheduledEventUserActionEvent(data) self.dispatch("raw_guild_scheduled_event_subscribe", payload) @@ -1612,7 +1612,7 @@ def parse_guild_scheduled_event_user_add( self.dispatch("guild_scheduled_event_subscribe", event, user) def parse_guild_scheduled_event_user_remove( - self, data: gateway.GuildScheduledEventUserRemoveEvent + self, data: gateway.GuildScheduledEventUserRemoveEvent ) -> None: payload = RawGuildScheduledEventUserActionEvent(data) self.dispatch("raw_guild_scheduled_event_unsubscribe", payload) @@ -1842,7 +1842,7 @@ def parse_typing_start(self, data: gateway.TypingStartEvent) -> None: self.dispatch("typing", channel, member, timestamp) def parse_auto_moderation_rule_create( - self, data: gateway.AutoModerationRuleCreateEvent + self, data: gateway.AutoModerationRuleCreateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1856,7 +1856,7 @@ def parse_auto_moderation_rule_create( self.dispatch("automod_rule_create", rule) def parse_auto_moderation_rule_update( - self, data: gateway.AutoModerationRuleUpdateEvent + self, data: gateway.AutoModerationRuleUpdateEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1870,7 +1870,7 @@ def parse_auto_moderation_rule_update( self.dispatch("automod_rule_update", rule) def parse_auto_moderation_rule_delete( - self, data: gateway.AutoModerationRuleDeleteEvent + self, data: gateway.AutoModerationRuleDeleteEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1884,7 +1884,7 @@ def parse_auto_moderation_rule_delete( self.dispatch("automod_rule_delete", rule) def parse_auto_moderation_action_execution( - self, data: gateway.AutoModerationActionExecutionEvent + self, data: gateway.AutoModerationActionExecutionEvent ) -> None: guild = self._get_guild(int(data["guild_id"])) if guild is None: @@ -1932,7 +1932,7 @@ def parse_entitlement_delete(self, data: gateway.EntitlementDelete) -> None: self.dispatch("entitlement_delete", entitlement) def _get_reaction_user( - self, channel: MessageableChannel, user_id: int + self, channel: MessageableChannel, user_id: int ) -> Optional[Union[User, Member]]: if isinstance(channel, (TextChannel, VoiceChannel, Thread, StageChannel)): return channel.guild.get_member(user_id) @@ -1941,7 +1941,7 @@ def _get_reaction_user( # methods to handle all sorts of different emoji formats def _get_emoji_from_data( - self, data: PartialEmojiPayload + self, data: PartialEmojiPayload ) -> Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]: """Convert partial emoji data to proper emoji. Returns unicode emojis as strings. @@ -1968,11 +1968,11 @@ def _get_emoji_from_data( get_reaction_emoji = _get_emoji_from_data def _get_emoji_from_fields( - self, - *, - name: Optional[str], - id: Optional[int], - animated: Optional[bool] = False, + self, + *, + name: Optional[str], + id: Optional[int], + animated: Optional[bool] = False, ) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: """Convert partial emoji fields to proper emoji, if possible. If both `id` and `name` are nullish, returns `None`. @@ -1999,7 +1999,9 @@ def _get_emoji_from_fields( animated=animated or False, ) - def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> Union[Emoji, ApplicationEmoji, PartialEmoji, str]: + def _upgrade_partial_emoji( + self, emoji: PartialEmoji + ) -> Union[Emoji, ApplicationEmoji, PartialEmoji, str]: emoji_id = emoji.id if not emoji_id: return emoji.name @@ -2022,10 +2024,10 @@ def get_channel(self, id: Optional[int]) -> Optional[Union[Channel, Thread]]: return channel def create_message( - self, - *, - channel: MessageableChannel, - data: MessagePayload, + self, + *, + channel: MessageableChannel, + data: MessagePayload, ) -> Message: return Message(state=self, channel=channel, data=data) @@ -2049,7 +2051,7 @@ async def fetch_global_command(self, command_id: int) -> APIApplicationCommand: return application_command_factory(result) async def create_global_command( - self, application_command: ApplicationCommand + self, application_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.upsert_global_command( self.application_id, application_command.to_dict() # type: ignore @@ -2059,7 +2061,7 @@ async def create_global_command( return cmd async def edit_global_command( - self, command_id: int, new_command: ApplicationCommand + self, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.edit_global_command( self.application_id, command_id, new_command.to_dict() # type: ignore @@ -2073,7 +2075,7 @@ async def delete_global_command(self, command_id: int) -> None: self._remove_global_application_command(command_id) async def bulk_overwrite_global_commands( - self, application_commands: List[ApplicationCommand] + self, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: payload = [cmd.to_dict() for cmd in application_commands] results = await self.http.bulk_upsert_global_commands(self.application_id, payload) # type: ignore @@ -2097,7 +2099,7 @@ async def fetch_guild_command(self, guild_id: int, command_id: int) -> APIApplic return application_command_factory(result) async def create_guild_command( - self, guild_id: int, application_command: ApplicationCommand + self, guild_id: int, application_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.upsert_guild_command( self.application_id, guild_id, application_command.to_dict() # type: ignore @@ -2107,7 +2109,7 @@ async def create_guild_command( return cmd async def edit_guild_command( - self, guild_id: int, command_id: int, new_command: ApplicationCommand + self, guild_id: int, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: result = await self.http.edit_guild_command( self.application_id, guild_id, command_id, new_command.to_dict() # type: ignore @@ -2123,7 +2125,7 @@ async def delete_guild_command(self, guild_id: int, command_id: int) -> None: self._remove_guild_application_command(guild_id, command_id) async def bulk_overwrite_guild_commands( - self, guild_id: int, application_commands: List[ApplicationCommand] + self, guild_id: int, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: payload = [cmd.to_dict() for cmd in application_commands] results = await self.http.bulk_upsert_guild_commands( @@ -2136,7 +2138,7 @@ async def bulk_overwrite_guild_commands( # Application command permissions async def bulk_fetch_command_permissions( - self, guild_id: int + self, guild_id: int ) -> List[GuildApplicationCommandPermissions]: array = await self.http.get_guild_application_command_permissions( self.application_id, guild_id # type: ignore @@ -2144,7 +2146,7 @@ async def bulk_fetch_command_permissions( return [GuildApplicationCommandPermissions(state=self, data=obj) for obj in array] async def fetch_command_permissions( - self, guild_id: int, command_id: int + self, guild_id: int, command_id: int ) -> GuildApplicationCommandPermissions: data = await self.http.get_application_command_permissions( self.application_id, guild_id, command_id # type: ignore @@ -2201,14 +2203,14 @@ def _update_member_references(self) -> None: msg.author = new_author async def chunker( - self, - guild_id: int, - query: str = "", - limit: int = 0, - presences: bool = False, - *, - shard_id: Optional[int] = None, - nonce: Optional[str] = None, + self, + guild_id: int, + query: str = "", + limit: int = 0, + presences: bool = False, + *, + shard_id: Optional[int] = None, + nonce: Optional[str] = None, ) -> None: ws = self._get_websocket(guild_id, shard_id=shard_id) await ws.request_chunks( diff --git a/disnake/threads.py b/disnake/threads.py index d378408519..024d35cc0c 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -28,7 +28,7 @@ from .abc import Snowflake, SnowflakeTime from .channel import CategoryChannel, ForumChannel, MediaChannel, TextChannel - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .guild import Guild from .member import Member from .message import Message, PartialMessage diff --git a/disnake/types/emoji.py b/disnake/types/emoji.py index 6a09c95933..c5e085a233 100644 --- a/disnake/types/emoji.py +++ b/disnake/types/emoji.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT -from typing import Optional, TypedDict, List +from typing import List, Optional, TypedDict from .snowflake import Snowflake, SnowflakeList from .user import User diff --git a/disnake/ui/action_row.py b/disnake/ui/action_row.py index 0d045d5330..2a67770241 100644 --- a/disnake/ui/action_row.py +++ b/disnake/ui/action_row.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ..emoji import Emoji, ApplicationEmoji + from ..emoji import ApplicationEmoji, Emoji from ..message import Message from ..partial_emoji import PartialEmoji from ..types.components import ActionRow as ActionRowPayload @@ -275,7 +275,7 @@ def add_button( Whether the button is disabled or not. label: Optional[:class:`str`] The label of the button, if any. - emoji: Optional[Union[:class:`.PartialEmoji`, :class:`.Emoji`, :class:`str`]] + emoji: Optional[Union[:class:`.PartialEmoji`, :class:`.GuildEmoji`, :class:`.ApplicationEmoji`, :class:`str`]] The emoji of the button, if available. Raises diff --git a/disnake/ui/button.py b/disnake/ui/button.py index 79d9f91bea..4ed98b16c3 100644 --- a/disnake/ui/button.py +++ b/disnake/ui/button.py @@ -31,7 +31,7 @@ if TYPE_CHECKING: from typing_extensions import ParamSpec, Self - from ..emoji import Emoji, ApplicationEmoji + from ..emoji import ApplicationEmoji, Emoji from .item import ItemCallbackType from .view import View @@ -62,7 +62,7 @@ class Button(Item[V_co]): Whether the button is disabled. label: Optional[:class:`str`] The label of the button, if any. - emoji: Optional[Union[:class:`.PartialEmoji`, :class:`.Emoji`, :class:`str`]] + emoji: Optional[Union[:class:`.PartialEmoji`, :class:`.GuildEmoji`, :class:`.ApplicationEmoji`, :class:`str`]] The emoji of the button, if available. row: Optional[:class:`int`] The relative row this button belongs to. A Discord component can only have 5 @@ -309,9 +309,9 @@ def button( The style of the button. Defaults to :attr:`.ButtonStyle.grey`. disabled: :class:`bool` Whether the button is disabled. Defaults to ``False``. - emoji: Optional[Union[:class:`str`, :class:`.Emoji`, :class:`.PartialEmoji`]] + emoji: Optional[Union[:class:`str`, :class:`.GuildEmoji`, :class:`.ApplicationEmoji`, :class:`.PartialEmoji`]] The emoji of the button. This can be in string form or a :class:`.PartialEmoji` - or a full :class:`.Emoji`. + or a full :class:`.GuildEmoji`, :class:`.ApplicationEmoji`,. row: Optional[:class:`int`] The relative row this button belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you'd diff --git a/disnake/ui/select/string.py b/disnake/ui/select/string.py index d4972a69ca..e46f12e570 100644 --- a/disnake/ui/select/string.py +++ b/disnake/ui/select/string.py @@ -24,7 +24,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ...emoji import Emoji, ApplicationEmoji + from ...emoji import ApplicationEmoji, Emoji from ...partial_emoji import PartialEmoji from ..item import DecoratedItem, ItemCallbackType, Object @@ -200,9 +200,9 @@ def add_option( description: Optional[:class:`str`] An additional description of the option, if any. Can only be up to 100 characters. - emoji: Optional[Union[:class:`str`, :class:`.Emoji`, :class:`.PartialEmoji`]] + emoji: Optional[Union[:class:`str`, :class:`.GuildEmoji`, :class:`.ApplicationEmoji`, :class:`.PartialEmoji`]] The emoji of the option, if available. This can either be a string representing - the custom or unicode emoji or an instance of :class:`.PartialEmoji` or :class:`.Emoji`. + the custom or unicode emoji or an instance of :class:`.PartialEmoji` or :class:`.GuildEmoji`, :class:`.ApplicationEmoji`. default: :class:`bool` Whether this option is selected by default. diff --git a/disnake/welcome_screen.py b/disnake/welcome_screen.py index 1cd15946ed..8797ef1ccd 100644 --- a/disnake/welcome_screen.py +++ b/disnake/welcome_screen.py @@ -8,7 +8,7 @@ from .partial_emoji import PartialEmoji, _EmojiTag if TYPE_CHECKING: - from .emoji import Emoji, ApplicationEmoji + from .emoji import ApplicationEmoji, Emoji from .guild import Guild from .invite import PartialInviteGuild from .state import ConnectionState diff --git a/docs/api/emoji.rst b/docs/api/emoji.rst index 4ea7b62cd7..5a89646453 100644 --- a/docs/api/emoji.rst +++ b/docs/api/emoji.rst @@ -2,10 +2,19 @@ .. currentmodule:: disnake +Emojis +====== + +This section documents everything related to Discord +:ddocs:`emoji `. + +Discord Models +--------------- + Emoji ~~~~~ -.. autoclass:: disnake.Emoji +.. autoclass:: Emoji :members: :inherited-members: @@ -51,4 +60,4 @@ PartialEmoji Events ------ -- :func:`on_guild_emojis_update(guild, before, after) ` \ No newline at end of file +- :func:`on_guild_emojis_update(guild, before, after) ` diff --git a/docs/conf.py b/docs/conf.py index 5944191079..782004e475 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -78,7 +78,7 @@ .. |maybecoro| replace:: This function *could be a* |coroutine_link|_. .. |coroutine_link| replace:: *coroutine* .. |components_type| replace:: Union[:class:`disnake.ui.ActionRow`, :class:`disnake.ui.WrappedComponent`, List[Union[:class:`disnake.ui.ActionRow`, :class:`disnake.ui.WrappedComponent`, List[:class:`disnake.ui.WrappedComponent`]]]] -.. |resource_type| replace:: Union[:class:`bytes`, :class:`.Asset`, :class:`.Emoji`, :class:`.PartialEmoji`, :class:`.StickerItem`, :class:`.Sticker`] +.. |resource_type| replace:: Union[:class:`bytes`, :class:`.Asset`, :class:`disnake.emoji.ApplicationEmoji`, :class:`disnake.emoji.GuildEmoji`, :class:`.StickerItem`, :class:`.Sticker`] .. _coroutine_link: https://docs.python.org/3/library/asyncio-task.html#coroutine """ diff --git a/docs/locale/ja/LC_MESSAGES/api.po b/docs/locale/ja/LC_MESSAGES/api.po index 44f7348e9a..baa488be13 100644 --- a/docs/locale/ja/LC_MESSAGES/api.po +++ b/docs/locale/ja/LC_MESSAGES/api.po @@ -666,11 +666,11 @@ msgstr ":class:`.Guild`" #: disnake.Client.emojis:1 of #, fuzzy msgid "The emojis that the connected client has." -msgstr "List[:class:`.Emoji`] -- 接続したクライアントがアクセスできる絵文字。" +msgstr "List[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]] -- 接続したクライアントがアクセスできる絵文字。" #: disnake.Client.emojis:3 of #, fuzzy -msgid "List[:class:`.Emoji`]" +msgid "List[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]" msgstr ":class:`.Webhook`" #: disnake.Client.cached_messages:1 of @@ -1347,14 +1347,14 @@ msgstr ":class:`~disnake.User`" #: disnake.Client.get_emoji:1 of #, fuzzy msgid "Returns an emoji with the given ID." -msgstr "Optional[:class:`.Emoji`]: 与えられたIDを持つ絵文字を返します。" +msgstr "Optional[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]: 与えられたIDを持つ絵文字を返します。" #: disnake.Client.get_emoji:6 of msgid "The custom emoji or ``None`` if not found." msgstr "" #: disnake.Client.get_emoji:7 of -msgid "Optional[:class:`.Emoji`]" +msgid "Optional[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]" msgstr "" #: disnake.Client.get_all_channels:1 of diff --git a/docs/locale/ja/LC_MESSAGES/ext/commands/api.po b/docs/locale/ja/LC_MESSAGES/ext/commands/api.po index f822bbb6f6..b2ee08ff3a 100644 --- a/docs/locale/ja/LC_MESSAGES/ext/commands/api.po +++ b/docs/locale/ja/LC_MESSAGES/ext/commands/api.po @@ -1063,11 +1063,11 @@ msgstr ":exc:`.HTTPException` -- 招待の取り消しに失敗した。" #: disnake.ext.commands.Bot.emojis:1 of #, fuzzy msgid "The emojis that the connected client has." -msgstr "List[:class:`.Emoji`] -- 接続したクライアントがアクセスできる絵文字。" +msgstr "List[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]] -- 接続したクライアントがアクセスできる絵文字。" #: disnake.ext.commands.Bot.emojis:3 of #, fuzzy -msgid "List[:class:`.Emoji`]" +msgid "List[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]" msgstr ":class:`.Guild`" #: disnake.ext.commands.Bot.event:1 of @@ -1598,7 +1598,7 @@ msgid "The custom emoji or ``None`` if not found." msgstr "" #: disnake.ext.commands.Bot.get_emoji:7 of -msgid "Optional[:class:`.Emoji`]" +msgid "Optional[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]" msgstr "" #: disnake.ext.commands.Bot.get_guild:1 of @@ -6021,7 +6021,7 @@ msgstr "" #~ "from the internal list of commands." #~ msgstr "" -#~ msgid "Optional[:class:`.Emoji`]: Returns an emoji with the given ID." +#~ msgid "Optional[Union[:class:`GuildEmoji`, :class:`ApplicationEmoji`]]: Returns an emoji with the given ID." #~ msgstr "" #~ msgid "Optional[:class:`.Guild`]: Returns a guild with the given ID." From 1ca8f16924f3b55719e6c71de50f05f39c3cf5eb Mon Sep 17 00:00:00 2001 From: Mantou Date: Mon, 22 Jul 2024 15:34:27 +0800 Subject: [PATCH 13/15] refactor: Modified the code to comply with the review suggestions --- disnake/abc.py | 4 ++-- disnake/audit_logs.py | 6 +++--- disnake/channel.py | 16 ++++++++-------- disnake/client.py | 6 +++--- disnake/components.py | 4 ++-- disnake/emoji.py | 13 ++++++++----- disnake/guild.py | 6 +++--- disnake/message.py | 6 +++--- disnake/onboarding.py | 4 ++-- disnake/partial_emoji.py | 4 ++-- disnake/reaction.py | 4 ++-- disnake/state.py | 18 ++++++++---------- disnake/threads.py | 8 ++++---- disnake/ui/action_row.py | 4 ++-- disnake/ui/button.py | 12 ++++++------ disnake/ui/select/string.py | 4 ++-- disnake/welcome_screen.py | 6 +++--- 17 files changed, 63 insertions(+), 62 deletions(-) diff --git a/disnake/abc.py b/disnake/abc.py index c021def827..6d69fbf2c6 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -67,7 +67,7 @@ from .channel import CategoryChannel, DMChannel, PartialMessageable from .client import Client from .embeds import Embed - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .enums import InviteTarget from .guild import Guild, GuildMessageable from .guild_scheduled_event import GuildScheduledEvent @@ -338,7 +338,7 @@ async def _edit( video_quality_mode: VideoQualityMode = MISSING, flags: ChannelFlags = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, reason: Optional[str] = None, diff --git a/disnake/audit_logs.py b/disnake/audit_logs.py index 106759715f..8d623d66ab 100644 --- a/disnake/audit_logs.py +++ b/disnake/audit_logs.py @@ -43,7 +43,7 @@ from .app_commands import APIApplicationCommand from .automod import AutoModRule - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji, Emoji from .guild import Guild from .guild_scheduled_event import GuildScheduledEvent from .integrations import PartialIntegration @@ -280,7 +280,7 @@ def _transform_automod_trigger_metadata( def _transform_default_reaction( entry: AuditLogEntry, data: Optional[DefaultReactionPayload] -) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: +) -> Optional[Union[AnyEmoji, PartialEmoji]]: if data is None: return None return entry._state._get_emoji_from_fields( @@ -817,7 +817,7 @@ def _convert_target_invite(self, target_id: int) -> Invite: def _convert_target_webhook(self, target_id: int) -> Union[Webhook, Object]: return self._webhooks.get(target_id) or Object(id=target_id) - def _convert_target_emoji(self, target_id: int) -> Union[Emoji, ApplicationEmoji, Object]: + def _convert_target_emoji(self, target_id: int) -> Union[AnyEmoji, Object]: return self._state.get_emoji(target_id) or Object(id=target_id) def _convert_target_message(self, target_id: int) -> Union[Member, User, Object, None]: diff --git a/disnake/channel.py b/disnake/channel.py index c390fa19fb..716d69f229 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -69,7 +69,7 @@ from .abc import Snowflake, SnowflakeTime from .asset import AssetBytes from .embeds import Embed - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .guild import Guild, GuildChannel as GuildChannelType from .member import Member, VoiceState from .message import AllowedMentions, Message, PartialMessage @@ -3314,7 +3314,7 @@ def requires_tag(self) -> bool: return self.flags.require_tag @property - def default_reaction(self) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: + def default_reaction(self) -> Optional[Union[AnyEmoji, PartialEmoji]]: """Optional[Union[:class:`Emoji`, :class:`PartialEmoji`]]: The default emoji shown for reacting to threads. @@ -3932,7 +3932,7 @@ async def edit( flags: ChannelFlags = ..., require_tag: bool = ..., available_tags: Sequence[ForumTag] = ..., - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = ..., + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = ..., default_sort_order: Optional[ThreadSortOrder] = ..., default_layout: ThreadLayout = ..., reason: Optional[str] = ..., @@ -3955,7 +3955,7 @@ async def edit( flags: ChannelFlags = MISSING, require_tag: bool = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, reason: Optional[str] = None, @@ -4102,7 +4102,7 @@ async def clone( default_thread_slowmode_delay: Optional[int] = MISSING, default_auto_archive_duration: Optional[AnyThreadArchiveDuration] = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, default_layout: ThreadLayout = MISSING, overwrites: Mapping[Union[Role, Member], PermissionOverwrite] = MISSING, @@ -4362,7 +4362,7 @@ async def edit( flags: ChannelFlags = ..., require_tag: bool = ..., available_tags: Sequence[ForumTag] = ..., - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = ..., + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = ..., default_sort_order: Optional[ThreadSortOrder] = ..., reason: Optional[str] = ..., ) -> MediaChannel: @@ -4384,7 +4384,7 @@ async def edit( flags: ChannelFlags = MISSING, require_tag: bool = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, reason: Optional[str] = None, **kwargs: Never, @@ -4503,7 +4503,7 @@ async def clone( default_thread_slowmode_delay: Optional[int] = MISSING, default_auto_archive_duration: Optional[AnyThreadArchiveDuration] = MISSING, available_tags: Sequence[ForumTag] = MISSING, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, default_sort_order: Optional[ThreadSortOrder] = MISSING, overwrites: Mapping[Union[Role, Member], PermissionOverwrite] = MISSING, reason: Optional[str] = None, diff --git a/disnake/client.py b/disnake/client.py index 4e5c23e0bb..dbbe26be52 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -46,7 +46,7 @@ from .application_role_connection import ApplicationRoleConnectionMetadata from .backoff import ExponentialBackoff from .channel import PartialMessageable, _threaded_channel_factory -from .emoji import ApplicationEmoji, GuildEmoji +from .emoji import AnyEmoji, ApplicationEmoji from .entitlement import Entitlement from .enums import ApplicationCommandType, ChannelType, Event, Status from .errors import ( @@ -566,7 +566,7 @@ def guilds(self) -> List[Guild]: return self._connection.guilds @property - def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: + def emojis(self) -> List[AnyEmoji]: """The emojis that the connected client has. .. note:: @@ -1486,7 +1486,7 @@ def get_user(self, id: int, /) -> Optional[User]: """ return self._connection.get_user(id) - def get_emoji(self, id: int, /) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: + def get_emoji(self, id: int, /) -> Optional[AnyEmoji]: """Returns an emoji with the given ID. Parameters diff --git a/disnake/components.py b/disnake/components.py index 081854308b..ba647c2d50 100644 --- a/disnake/components.py +++ b/disnake/components.py @@ -25,7 +25,7 @@ if TYPE_CHECKING: from typing_extensions import Self, TypeAlias - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .types.components import ( ActionRow as ActionRowPayload, AnySelectMenu as AnySelectMenuPayload, @@ -546,7 +546,7 @@ def __init__( label: str, value: str = MISSING, description: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, default: bool = False, ) -> None: self.label = label diff --git a/disnake/emoji.py b/disnake/emoji.py index 3bc95ca9da..31123309a4 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -9,7 +9,7 @@ from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ("BaseEmoji", "Emoji", "GuildEmoji", "ApplicationEmoji") +__all__ = ("BaseEmoji", "Emoji", "GuildEmoji", "ApplicationEmoji", "AnyEmoji") if TYPE_CHECKING: from datetime import datetime @@ -67,8 +67,6 @@ class BaseEmoji(_EmojiTag, AssetMixin): Whether the emoji is animated or not. managed: :class:`bool` Whether the emoji is managed by a Twitch integration. - guild_id: :class:`int` - The guild ID the emoji belongs to. available: :class:`bool` Whether the emoji is available for use. user: Optional[:class:`User`] @@ -84,8 +82,6 @@ class BaseEmoji(_EmojiTag, AssetMixin): "id", "name", "_roles", - "guild_id", - "application_id", "user", "available", ) @@ -197,6 +193,8 @@ class GuildEmoji(BaseEmoji): having the :attr:`~Permissions.manage_guild_expressions` permission. """ + __slots__: Tuple[str, ...] = BaseEmoji.__slots__ + ("guild_id",) + def __init__( self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload ) -> None: @@ -365,6 +363,8 @@ class ApplicationEmoji(BaseEmoji): The user that created the emoji. """ + __slots__: Tuple[str, ...] = BaseEmoji.__slots__ + ("application_id",) + def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload) -> None: self.application_id: int = application_id super().__init__(state=state, data=data) @@ -426,3 +426,6 @@ async def edit( self.application_id, self.id, payload=payload ) return self._state.store_application_emoji(self.application_id, data) + + +AnyEmoji = Union[GuildEmoji, ApplicationEmoji] diff --git a/disnake/guild.py b/disnake/guild.py index 52dd3e3b46..eb6b0b16eb 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -40,7 +40,7 @@ _threaded_guild_channel_factory, ) from .colour import Colour -from .emoji import ApplicationEmoji, Emoji +from .emoji import AnyEmoji, Emoji from .enums import ( AuditLogAction, AutoModEventType, @@ -1643,7 +1643,7 @@ async def create_forum_channel( nsfw: bool = MISSING, overwrites: Dict[Union[Role, Member], PermissionOverwrite] = MISSING, available_tags: Optional[Sequence[ForumTag]] = None, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, default_sort_order: Optional[ThreadSortOrder] = None, default_layout: Optional[ThreadLayout] = None, reason: Optional[str] = None, @@ -1793,7 +1793,7 @@ async def create_media_channel( nsfw: bool = MISSING, overwrites: Dict[Union[Role, Member], PermissionOverwrite] = MISSING, available_tags: Optional[Sequence[ForumTag]] = None, - default_reaction: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + default_reaction: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, default_sort_order: Optional[ThreadSortOrder] = None, reason: Optional[str] = None, ) -> MediaChannel: diff --git a/disnake/message.py b/disnake/message.py index 7cdef7a6aa..d255c59617 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -25,7 +25,7 @@ from . import utils from .components import ActionRow, MessageComponent, _component_factory from .embeds import Embed -from .emoji import ApplicationEmoji, Emoji +from .emoji import AnyEmoji from .enums import ChannelType, InteractionType, MessageType, try_enum, try_enum_to_int from .errors import HTTPException from .file import File @@ -76,7 +76,7 @@ from .ui.action_row import Components, MessageUIComponent from .ui.view import View - EmojiInputType = Union[Emoji, ApplicationEmoji, PartialEmoji, str] + EmojiInputType = Union[AnyEmoji, PartialEmoji, str] __all__ = ( "Attachment", @@ -93,7 +93,7 @@ def convert_emoji_reaction(emoji: Union[EmojiInputType, Reaction]) -> str: if isinstance(emoji, Reaction): emoji = emoji.emoji - if isinstance(emoji, Emoji) or isinstance(emoji, ApplicationEmoji): + if isinstance(emoji, AnyEmoji): return f"{emoji.name}:{emoji.id}" if isinstance(emoji, PartialEmoji): return emoji._as_reaction() diff --git a/disnake/onboarding.py b/disnake/onboarding.py index 97b42e72fc..e081f256a4 100644 --- a/disnake/onboarding.py +++ b/disnake/onboarding.py @@ -7,7 +7,7 @@ from .mixins import Hashable if TYPE_CHECKING: - from .emoji import ApplicationEmoji, Emoji, PartialEmoji + from .emoji import AnyEmoji, PartialEmoji from .guild import Guild, GuildChannel from .role import Role from .types.onboarding import ( @@ -170,7 +170,7 @@ def __init__(self, *, guild: Guild, data: OnboardingPromptOptionPayload) -> None else frozenset() ) - self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji, str]] + self.emoji: Optional[Union[AnyEmoji, PartialEmoji, str]] if emoji_data := data.get("emoji"): self.emoji = guild._state.get_reaction_emoji(emoji_data) else: diff --git a/disnake/partial_emoji.py b/disnake/partial_emoji.py index f9b03510b7..59a9fa8f25 100644 --- a/disnake/partial_emoji.py +++ b/disnake/partial_emoji.py @@ -15,7 +15,7 @@ from typing_extensions import Self - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .state import ConnectionState from .types.activity import ActivityEmoji as ActivityEmojiPayload from .types.emoji import Emoji as EmojiPayload, PartialEmoji as PartialEmojiPayload @@ -254,7 +254,7 @@ async def read(self) -> bytes: # (e.g. default reaction, tag emoji) @staticmethod def _emoji_to_name_id( - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] ) -> Tuple[Optional[str], Optional[int]]: if emoji is None: return None, None diff --git a/disnake/reaction.py b/disnake/reaction.py index 1663aa1d65..6c3925e8a3 100644 --- a/disnake/reaction.py +++ b/disnake/reaction.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji, Emoji from .message import Message from .partial_emoji import PartialEmoji from .types.message import Reaction as ReactionPayload @@ -61,7 +61,7 @@ def __init__( *, message: Message, data: ReactionPayload, - emoji: Optional[Union[PartialEmoji, Emoji, ApplicationEmoji, str]] = None, + emoji: Optional[Union[PartialEmoji, AnyEmoji, str]] = None, ) -> None: self.message: Message = message # _get_emoji_from_data won't return None diff --git a/disnake/state.py b/disnake/state.py index 9c653f0f17..3cb979c0c6 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -44,7 +44,7 @@ VoiceChannel, _guild_channel_factory, ) -from .emoji import ApplicationEmoji, Emoji, GuildEmoji +from .emoji import AnyEmoji, ApplicationEmoji, GuildEmoji from .entitlement import Entitlement from .enums import ApplicationCommandType, ChannelType, ComponentType, MessageType, Status, try_enum from .flags import ApplicationFlags, Intents, MemberCacheFlags @@ -296,7 +296,7 @@ def clear( # - the weakref slot + object in user objects likely results in a small increase in memory usage # - accesses on `_users` are slower, e.g. `__getitem__` takes ~1us with weakrefs and ~0.2us without self._users: weakref.WeakValueDictionary[int, User] = weakref.WeakValueDictionary() - self._emojis: Dict[int, Union[GuildEmoji, ApplicationEmoji]] = {} + self._emojis: Dict[int, AnyEmoji] = {} self._stickers: Dict[int, GuildSticker] = {} self._guilds: Dict[int, Guild] = {} @@ -518,18 +518,18 @@ def _get_guild_command_named( return cmd @property - def emojis(self) -> List[Union[GuildEmoji, ApplicationEmoji]]: + def emojis(self) -> List[AnyEmoji]: return list(self._emojis.values()) @property def stickers(self) -> List[GuildSticker]: return list(self._stickers.values()) - def get_emoji(self, emoji_id: Optional[int]) -> Optional[Union[GuildEmoji, ApplicationEmoji]]: + def get_emoji(self, emoji_id: Optional[int]) -> Optional[AnyEmoji]: # the keys of self._emojis are ints return self._emojis.get(emoji_id) # type: ignore - def _remove_emoji(self, emoji: Union[GuildEmoji, ApplicationEmoji]) -> None: + def _remove_emoji(self, emoji: AnyEmoji) -> None: self._emojis.pop(emoji.id, None) def get_sticker(self, sticker_id: Optional[int]) -> Optional[GuildSticker]: @@ -1942,7 +1942,7 @@ def _get_reaction_user( def _get_emoji_from_data( self, data: PartialEmojiPayload - ) -> Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]: + ) -> Optional[Union[str, AnyEmoji, PartialEmoji]]: """Convert partial emoji data to proper emoji. Returns unicode emojis as strings. @@ -1973,7 +1973,7 @@ def _get_emoji_from_fields( name: Optional[str], id: Optional[int], animated: Optional[bool] = False, - ) -> Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]]: + ) -> Optional[Union[AnyEmoji, PartialEmoji]]: """Convert partial emoji fields to proper emoji, if possible. If both `id` and `name` are nullish, returns `None`. @@ -1999,9 +1999,7 @@ def _get_emoji_from_fields( animated=animated or False, ) - def _upgrade_partial_emoji( - self, emoji: PartialEmoji - ) -> Union[Emoji, ApplicationEmoji, PartialEmoji, str]: + def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> Union[AnyEmoji, PartialEmoji, str]: emoji_id = emoji.id if not emoji_id: return emoji.name diff --git a/disnake/threads.py b/disnake/threads.py index 024d35cc0c..ae609a6790 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -28,7 +28,7 @@ from .abc import Snowflake, SnowflakeTime from .channel import CategoryChannel, ForumChannel, MediaChannel, TextChannel - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .guild import Guild from .member import Member from .message import Message, PartialMessage @@ -1157,14 +1157,14 @@ def __init__( self, *, name: str, - emoji: Optional[Union[str, PartialEmoji, ApplicationEmoji, Emoji]] = None, + emoji: Optional[Union[str, PartialEmoji, AnyEmoji]] = None, moderated: bool = False, ) -> None: self.id: int = 0 self.name: str = name self.moderated: bool = moderated - self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]] = None + self.emoji: Optional[Union[AnyEmoji, PartialEmoji]] = None if emoji is None: self.emoji = None elif isinstance(emoji, str): @@ -1225,7 +1225,7 @@ def with_changes( self, *, name: str = MISSING, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = MISSING, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = MISSING, moderated: bool = MISSING, ) -> Self: """Returns a new instance with the given changes applied, diff --git a/disnake/ui/action_row.py b/disnake/ui/action_row.py index 2a67770241..ef9337b582 100644 --- a/disnake/ui/action_row.py +++ b/disnake/ui/action_row.py @@ -40,7 +40,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ..emoji import ApplicationEmoji, Emoji + from ..emoji import AnyEmoji from ..message import Message from ..partial_emoji import PartialEmoji from ..types.components import ActionRow as ActionRowPayload @@ -245,7 +245,7 @@ def add_button( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, ) -> ButtonCompatibleActionRowT: """Add a button to the action row. Can only be used if the action row holds message components. diff --git a/disnake/ui/button.py b/disnake/ui/button.py index 4ed98b16c3..e22d2b0206 100644 --- a/disnake/ui/button.py +++ b/disnake/ui/button.py @@ -31,7 +31,7 @@ if TYPE_CHECKING: from typing_extensions import ParamSpec, Self - from ..emoji import ApplicationEmoji, Emoji + from ..emoji import AnyEmoji from .item import ItemCallbackType from .view import View @@ -92,7 +92,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: ... @@ -106,7 +106,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: ... @@ -119,7 +119,7 @@ def __init__( disabled: bool = False, custom_id: Optional[str] = None, url: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> None: super().__init__() @@ -217,7 +217,7 @@ def emoji(self) -> Optional[PartialEmoji]: return self._underlying.emoji @emoji.setter - def emoji(self, value: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]]) -> None: + def emoji(self, value: Optional[Union[str, AnyEmoji, PartialEmoji]]) -> None: if value is not None: if isinstance(value, str): self._underlying.emoji = PartialEmoji.from_str(value) @@ -261,7 +261,7 @@ def button( custom_id: Optional[str] = None, disabled: bool = False, style: ButtonStyle = ButtonStyle.secondary, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, row: Optional[int] = None, ) -> Callable[[ItemCallbackType[Button[V_co]]], DecoratedItem[Button[V_co]]]: ... diff --git a/disnake/ui/select/string.py b/disnake/ui/select/string.py index e46f12e570..07198b685b 100644 --- a/disnake/ui/select/string.py +++ b/disnake/ui/select/string.py @@ -24,7 +24,7 @@ if TYPE_CHECKING: from typing_extensions import Self - from ...emoji import ApplicationEmoji, Emoji + from ...emoji import AnyEmoji from ...partial_emoji import PartialEmoji from ..item import DecoratedItem, ItemCallbackType, Object @@ -181,7 +181,7 @@ def add_option( label: str, value: str = MISSING, description: Optional[str] = None, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, default: bool = False, ) -> None: """Adds an option to the select menu. diff --git a/disnake/welcome_screen.py b/disnake/welcome_screen.py index 8797ef1ccd..28f9058e0f 100644 --- a/disnake/welcome_screen.py +++ b/disnake/welcome_screen.py @@ -8,7 +8,7 @@ from .partial_emoji import PartialEmoji, _EmojiTag if TYPE_CHECKING: - from .emoji import ApplicationEmoji, Emoji + from .emoji import AnyEmoji from .guild import Guild from .invite import PartialInviteGuild from .state import ConnectionState @@ -51,11 +51,11 @@ def __init__( *, id: int, description: str, - emoji: Optional[Union[str, Emoji, ApplicationEmoji, PartialEmoji]] = None, + emoji: Optional[Union[str, AnyEmoji, PartialEmoji]] = None, ) -> None: self.id: int = id self.description: str = description - self.emoji: Optional[Union[Emoji, ApplicationEmoji, PartialEmoji]] = None + self.emoji: Optional[Union[AnyEmoji, PartialEmoji]] = None if emoji is None: self.emoji = None elif isinstance(emoji, str): From f019663dc1230a82e828c783014f20c173fa0665 Mon Sep 17 00:00:00 2001 From: Mantou Date: Mon, 22 Jul 2024 15:40:07 +0800 Subject: [PATCH 14/15] fix: defines overlapping slots. --- disnake/emoji.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/disnake/emoji.py b/disnake/emoji.py index 31123309a4..9dc4a2255a 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -193,7 +193,7 @@ class GuildEmoji(BaseEmoji): having the :attr:`~Permissions.manage_guild_expressions` permission. """ - __slots__: Tuple[str, ...] = BaseEmoji.__slots__ + ("guild_id",) + __slots__: Tuple[str, ...] = ("guild_id",) def __init__( self, *, guild: Union[Guild, GuildPreview], state: ConnectionState, data: EmojiPayload @@ -363,7 +363,7 @@ class ApplicationEmoji(BaseEmoji): The user that created the emoji. """ - __slots__: Tuple[str, ...] = BaseEmoji.__slots__ + ("application_id",) + __slots__: Tuple[str, ...] = ("application_id",) def __init__(self, *, application_id: int, state: ConnectionState, data: EmojiPayload) -> None: self.application_id: int = application_id From c5949c42fcc375febab57abb4b046e3f1d63c159 Mon Sep 17 00:00:00 2001 From: Mantou Date: Mon, 22 Jul 2024 15:42:46 +0800 Subject: [PATCH 15/15] fix: Subscripted generics cannot be used with class and instance checks --- disnake/message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/disnake/message.py b/disnake/message.py index d255c59617..a588ff3f5a 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -25,7 +25,7 @@ from . import utils from .components import ActionRow, MessageComponent, _component_factory from .embeds import Embed -from .emoji import AnyEmoji +from .emoji import AnyEmoji, BaseEmoji from .enums import ChannelType, InteractionType, MessageType, try_enum, try_enum_to_int from .errors import HTTPException from .file import File @@ -93,7 +93,7 @@ def convert_emoji_reaction(emoji: Union[EmojiInputType, Reaction]) -> str: if isinstance(emoji, Reaction): emoji = emoji.emoji - if isinstance(emoji, AnyEmoji): + if isinstance(emoji, BaseEmoji): return f"{emoji.name}:{emoji.id}" if isinstance(emoji, PartialEmoji): return emoji._as_reaction()