From dc9fec5ec9832ab6cb324803284fb756310d34c3 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Fri, 19 Jul 2024 00:04:20 +0100 Subject: [PATCH 01/24] add routes --- discord/http.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/discord/http.py b/discord/http.py index 65c1dab0eb..0c4be3d29f 100644 --- a/discord/http.py +++ b/discord/http.py @@ -1878,6 +1878,65 @@ 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: bytes, + ) -> 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]]: From 847cc4fd21be428139ef420a95f029e89407aeaa Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Fri, 19 Jul 2024 00:10:51 +0100 Subject: [PATCH 02/24] unfinished methods, needs rework --- discord/client.py | 108 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/discord/client.py b/discord/client.py index 4cfaef59cf..713f4788db 100644 --- a/discord/client.py +++ b/discord/client.py @@ -328,7 +328,11 @@ def guilds(self) -> list[Guild]: @property def emojis(self) -> list[Emoji]: - """The emojis that the connected client has.""" + """The guild emojis that the connected client has. + + .. note:: + + This does not include application emojis; use :func:`fetch_emojis` instead.""" return self._connection.emojis @property @@ -2123,3 +2127,105 @@ def store_url(self) -> str: .. versionadded:: 2.6 """ return f"https://discord.com/application-directory/{self.application_id}/store" + + async def fetch_emojis(self) -> list[Emoji]: + r"""|coro| + + Retrieves all custom :class:`Emoji`\s from the application. + + Raises + --------- + HTTPException + An error occurred fetching the emojis. + + Returns + -------- + List[:class:`Emoji`] + The retrieved emojis. + """ + data = await self._state.http.get_all_application_emojis(self.application_id) + return [Emoji(guild=None, state=self._state, data=d) for d in data] + + async def fetch_emoji(self, emoji_id: int, /) -> Emoji: + """|coro| + + Retrieves a custom :class:`Emoji` from the application. + + Parameters + ---------- + emoji_id: :class:`int` + The emoji's ID. + + Returns + ------- + :class:`Emoji` + The retrieved emoji. + + Raises + ------ + NotFound + The emoji requested could not be found. + HTTPException + An error occurred fetching the emoji. + """ + data = await self._state.http.get_application_emoji(self.application_id, emoji_id) + return Emoji(guild=None, state=self._state, data=data) + + async def create_emoji( + self, + *, + name: str, + image: bytes, + ) -> Emoji: + r"""|coro| + + Creates a custom :class:`Emoji` 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:`Emoji` + The created emoji. + """ + + img = utils._bytes_to_base64_data(image) + data = await self._state.http.create_application_emoji( + self.application_id, name, img + ) + return self._state.store_emoji(None, data) + + async def delete_emoji( + self, emoji: Snowflake, *, reason: str | None = None + ) -> None: + """|coro| + + Deletes the custom :class:`Emoji` from the application. + + Parameters + ---------- + emoji: :class:`abc.Snowflake` + The emoji you are deleting. + + Raises + ------ + HTTPException + An error occurred deleting the emoji. + """ + + await self._state.http.delete_application_emoji(self.application_id, emoji.id) From b8c8dd2c7fb259b5b7e39405f3d8965869a29009 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 00:28:47 +0000 Subject: [PATCH 03/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/client.py | 7 +++++-- discord/http.py | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/discord/client.py b/discord/client.py index 713f4788db..2cd0ce7fb5 100644 --- a/discord/client.py +++ b/discord/client.py @@ -332,7 +332,8 @@ def emojis(self) -> list[Emoji]: .. note:: - This does not include application emojis; use :func:`fetch_emojis` instead.""" + This does not include application emojis; use :func:`fetch_emojis` instead. + """ return self._connection.emojis @property @@ -2168,7 +2169,9 @@ async def fetch_emoji(self, emoji_id: int, /) -> Emoji: HTTPException An error occurred fetching the emoji. """ - data = await self._state.http.get_application_emoji(self.application_id, emoji_id) + data = await self._state.http.get_application_emoji( + self.application_id, emoji_id + ) return Emoji(guild=None, state=self._state, data=data) async def create_emoji( diff --git a/discord/http.py b/discord/http.py index 0c4be3d29f..2461b4f5cf 100644 --- a/discord/http.py +++ b/discord/http.py @@ -1878,9 +1878,15 @@ 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[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( @@ -1906,7 +1912,11 @@ def create_application_emoji( "image": image, } - r = Route("POST", "/applications/{application_id}/emojis", application_id=application_id) + r = Route( + "POST", + "/applications/{application_id}/emojis", + application_id=application_id, + ) return self.request(r, json=payload) def delete_application_emoji( From 607bc10b2418708959265f4073e06364bb35d237 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Fri, 19 Jul 2024 05:17:43 +0100 Subject: [PATCH 04/24] new classes --- discord/client.py | 29 +++-- discord/emoji.py | 267 ++++++++++++++++++++++++++++++++++---------- discord/state.py | 28 ++++- docs/api/models.rst | 10 +- 4 files changed, 262 insertions(+), 72 deletions(-) diff --git a/discord/client.py b/discord/client.py index 2cd0ce7fb5..7ef9c47886 100644 --- a/discord/client.py +++ b/discord/client.py @@ -41,7 +41,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 Emoji, AppEmoji from .enums import ChannelType, Status from .errors import * from .flags import ApplicationFlags, Intents @@ -199,6 +199,16 @@ class Client: To enable these events, this must be set to ``True``. Defaults to ``False``. .. versionadded:: 2.0 + cache_app_emojis: :class:`bool` + Whether to automatically fetch and cache the application's emojis on startup and when fetching. Defaults to ``False``. + + .. warning:: + + There are no events related to application emojis - if any are created/deleted on the + Developer Dashboard while the client is running, the cache will not be updated until you manually + run :func:`fetch_emojis`. + + .. versionadded:: 2.7 Attributes ----------- @@ -327,12 +337,12 @@ def guilds(self) -> list[Guild]: return self._connection.guilds @property - def emojis(self) -> list[Emoji]: - """The guild emojis that the connected client has. + def emojis(self) -> list[Emoji | AppEmoji]: + """The emojis that the connected client has. .. note:: - This does not include application emojis; use :func:`fetch_emojis` instead. + This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is ``True``. """ return self._connection.emojis @@ -2141,11 +2151,14 @@ async def fetch_emojis(self) -> list[Emoji]: Returns -------- - List[:class:`Emoji`] + List[:class:`AppEmoji`] The retrieved emojis. """ data = await self._state.http.get_all_application_emojis(self.application_id) - return [Emoji(guild=None, state=self._state, data=d) for d in data] + if self._state.cache_app_emojis: + return [self._state.store_app_emoji(self.application_id, d) for d in data["items"]] + else: + return [AppEmoji(application_id=self.application_id, state=self._state, data=d) for d in data["items"]] async def fetch_emoji(self, emoji_id: int, /) -> Emoji: """|coro| @@ -2211,7 +2224,7 @@ async def create_emoji( data = await self._state.http.create_application_emoji( self.application_id, name, img ) - return self._state.store_emoji(None, data) + return self._state.store_app_emoji(self.application_id, data) async def delete_emoji( self, emoji: Snowflake, *, reason: str | None = None @@ -2232,3 +2245,5 @@ async def delete_emoji( """ await self._state.http.delete_application_emoji(self.application_id, emoji.id) + if self._state.cache_app_emojis and self._state.get_emoji(emoji.id): + self._state.remove_emoji(emoji) diff --git a/discord/emoji.py b/discord/emoji.py index cbb51eee57..aad46af99f 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -32,7 +32,7 @@ from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ("Emoji",) +__all__ = ("Emoji", "GuildEmoji", "AppEmoji",) if TYPE_CHECKING: from datetime import datetime @@ -44,55 +44,7 @@ from .types.emoji import Emoji as EmojiPayload -class Emoji(_EmojiTag, AssetMixin): - """Represents a custom emoji. - - 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. - 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 the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and - having the :attr:`~Permissions.manage_emojis` permission. - """ +class BaseEmoji(_EmojiTag, AssetMixin): __slots__: tuple[str, ...] = ( "require_colons", @@ -102,13 +54,13 @@ class Emoji(_EmojiTag, AssetMixin): "name", "_roles", "guild_id", + "application_id", "_state", "user", "available", ) - def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): - self.guild_id: int = guild.id + def __init__(self, *, state: ConnectionState, data: EmojiPayload): self._state: ConnectionState = state self._from_data(data) @@ -140,8 +92,8 @@ def __str__(self) -> str: def __repr__(self) -> str: return ( - "" + "" ) def __eq__(self, other: Any) -> bool: @@ -161,6 +113,66 @@ 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 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. + 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 the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and + having the :attr:`~Permissions.manage_emojis` permission. + """ + + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): + self.guild_id: int = guild.id + super().__init__(state, data) + + def __repr__(self) -> str: + return ( + "" + ) + @property def roles(self) -> list[Role]: """A :class:`list` of roles that is allowed to use this emoji. @@ -221,7 +233,7 @@ async def edit( name: str = MISSING, roles: list[Snowflake] = MISSING, reason: str | None = None, - ) -> Emoji: + ) -> GuildEmoji: r"""|coro| Edits the custom emoji. @@ -250,7 +262,7 @@ async def edit( Returns -------- - :class:`Emoji` + :class:`GuildEmoji` The newly updated emoji. """ @@ -263,4 +275,145 @@ 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 AppEmoji(BaseEmoji): + """Represents a custom emoji from an application. + + Depending on the way this object was created, some attributes can + have a value of ``None``. + + .. versionadded:: 2.7 + + .. 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, data) + + def __repr__(self) -> str: + return ( + "" + ) + + @property + def guild(self) -> Guild: + """The guild this emoji belongs to. This is always `None` for :class:`AppEmoji`.""" + return None + + @property + def roles(self) -> list[Role]: + """A :class:`list` of roles that is allowed to use this emoji. This is always empty for :class:`AppEmoji`. + """ + return [] + + def is_usable(self) -> bool: + """Whether the bot can use this emoji. + """ + return self.application_id == self._state.application_id + + async def delete(self, *, reason: str | None = None) -> 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, + ) -> AppEmoji: + 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:`AppEmoji` + 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 + ) + if self._state.cache_app_emojis: + return self._state.store_app_emoji(self.application_id, data) + else: + return AppEmoji(application_id=self.application_id, data=data, state=self._state) diff --git a/discord/state.py b/discord/state.py index c8d8d4dced..fed45adb78 100644 --- a/discord/state.py +++ b/discord/state.py @@ -49,7 +49,7 @@ from .automod import AutoModRule from .channel import * from .channel import _channel_factory -from .emoji import Emoji +from .emoji import Emoji, GuildEmoji, AppEmoji from .enums import ChannelType, InteractionType, ScheduledEventStatus, Status, try_enum from .flags import ApplicationFlags, Intents, MemberCacheFlags from .guild import Guild @@ -251,6 +251,8 @@ def __init__( self.store_user = self.create_user # type: ignore self.deref_user = self.deref_user_no_intents # type: ignore + self.cache_app_emojis: bool = options.get("cache_app_emojis", False) + self.parsers = parsers = {} for attr, func in inspect.getmembers(self): if attr.startswith("parse_"): @@ -374,10 +376,16 @@ def get_user(self, id: int | None) -> User | None: # 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_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: + # the id will be present here + emoji_id = int(data["id"]) # type: ignore + self._emojis[emoji_id] = emoji = AppEmoji(application_id=application_id, state=self, data=data) return emoji def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: @@ -413,7 +421,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) for sticker in guild.stickers: self._stickers.pop(sticker.id, None) @@ -421,17 +429,20 @@ def _remove_guild(self, guild: Guild) -> None: del guild @property - def emojis(self) -> list[Emoji]: + def emojis(self) -> list[GuildEmoji | AppEmoji]: return list(self._emojis.values()) @property def stickers(self) -> list[GuildSticker]: return list(self._stickers.values()) - def get_emoji(self, emoji_id: int | None) -> Emoji | None: + def get_emoji(self, emoji_id: int | None) -> GuildEmoji | AppEmoji | None: # the keys of self._emojis are ints return self._emojis.get(emoji_id) # type: ignore + def _remove_emoji(self, emoji: GuildEmoji | AppEmoji) -> None: + self._emojis.pop(emoji.id, None) + def get_sticker(self, sticker_id: int | None) -> GuildSticker | None: # the keys of self._stickers are ints return self._stickers.get(sticker_id) # type: ignore @@ -2085,6 +2096,11 @@ async def _delay_ready(self) -> None: self.dispatch("guild_join", guild) 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_app_emoji(self.application_id, e) # remove the state try: diff --git a/docs/api/models.rst b/docs/api/models.rst index bea6b3c0de..0238e2fc77 100644 --- a/docs/api/models.rst +++ b/docs/api/models.rst @@ -388,9 +388,15 @@ Interactions Emoji ----- -.. attributetable:: Emoji +.. attributetable:: GuildEmoji -.. autoclass:: Emoji() +.. autoclass:: GuildEmoji() + :members: + :inherited-members: + +.. attributetable:: AppEmoji + +.. autoclass:: AppEmoji() :members: :inherited-members: From 833695d01517c3d8258a7d57a64ecd7521110055 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 04:18:55 +0000 Subject: [PATCH 05/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/client.py | 14 ++++++++++---- discord/emoji.py | 35 +++++++++++++++++++---------------- discord/state.py | 8 +++++--- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/discord/client.py b/discord/client.py index 7ef9c47886..7461727d29 100644 --- a/discord/client.py +++ b/discord/client.py @@ -41,7 +41,7 @@ from .application_role_connection import ApplicationRoleConnectionMetadata from .backoff import ExponentialBackoff from .channel import PartialMessageable, _threaded_channel_factory -from .emoji import Emoji, AppEmoji +from .emoji import AppEmoji, Emoji from .enums import ChannelType, Status from .errors import * from .flags import ApplicationFlags, Intents @@ -204,7 +204,7 @@ class Client: .. warning:: - There are no events related to application emojis - if any are created/deleted on the + There are no events related to application emojis - if any are created/deleted on the Developer Dashboard while the client is running, the cache will not be updated until you manually run :func:`fetch_emojis`. @@ -2156,9 +2156,15 @@ async def fetch_emojis(self) -> list[Emoji]: """ data = await self._state.http.get_all_application_emojis(self.application_id) if self._state.cache_app_emojis: - return [self._state.store_app_emoji(self.application_id, d) for d in data["items"]] + return [ + self._state.store_app_emoji(self.application_id, d) + for d in data["items"] + ] else: - return [AppEmoji(application_id=self.application_id, state=self._state, data=d) for d in data["items"]] + return [ + AppEmoji(application_id=self.application_id, state=self._state, data=d) + for d in data["items"] + ] async def fetch_emoji(self, emoji_id: int, /) -> Emoji: """|coro| diff --git a/discord/emoji.py b/discord/emoji.py index aad46af99f..b7777872cd 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -32,7 +32,11 @@ from .user import User from .utils import MISSING, SnowflakeList, snowflake_time -__all__ = ("Emoji", "GuildEmoji", "AppEmoji",) +__all__ = ( + "Emoji", + "GuildEmoji", + "AppEmoji", +) if TYPE_CHECKING: from datetime import datetime @@ -92,8 +96,7 @@ def __str__(self) -> str: def __repr__(self) -> str: return ( - "" + "" ) def __eq__(self, other: Any) -> bool: @@ -113,6 +116,7 @@ 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. @@ -277,8 +281,10 @@ async def edit( ) return GuildEmoji(guild=self.guild, data=data, state=self._state) + Emoji = GuildEmoji + class AppEmoji(BaseEmoji): """Represents a custom emoji from an application. @@ -330,15 +336,14 @@ class AppEmoji(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, data) def __repr__(self) -> str: - return ( - "" - ) + return "" @property def guild(self) -> Guild: @@ -347,13 +352,11 @@ def guild(self) -> Guild: @property def roles(self) -> list[Role]: - """A :class:`list` of roles that is allowed to use this emoji. This is always empty for :class:`AppEmoji`. - """ + """A :class:`list` of roles that is allowed to use this emoji. This is always empty for :class:`AppEmoji`.""" return [] def is_usable(self) -> bool: - """Whether the bot can use this emoji. - """ + """Whether the bot can use this emoji.""" return self.application_id == self._state.application_id async def delete(self, *, reason: str | None = None) -> None: @@ -371,9 +374,7 @@ async def delete(self, *, reason: str | None = None) -> None: An error occurred deleting the emoji. """ - await self._state.http.delete_application_emoji( - self.application_id, self.id - ) + 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) @@ -416,4 +417,6 @@ async def edit( if self._state.cache_app_emojis: return self._state.store_app_emoji(self.application_id, data) else: - return AppEmoji(application_id=self.application_id, data=data, state=self._state) + return AppEmoji( + application_id=self.application_id, data=data, state=self._state + ) diff --git a/discord/state.py b/discord/state.py index fed45adb78..5f1eaa9950 100644 --- a/discord/state.py +++ b/discord/state.py @@ -49,7 +49,7 @@ from .automod import AutoModRule from .channel import * from .channel import _channel_factory -from .emoji import Emoji, GuildEmoji, AppEmoji +from .emoji import AppEmoji, Emoji, GuildEmoji from .enums import ChannelType, InteractionType, ScheduledEventStatus, Status, try_enum from .flags import ApplicationFlags, Intents, MemberCacheFlags from .guild import Guild @@ -385,7 +385,9 @@ def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: def store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: # the id will be present here emoji_id = int(data["id"]) # type: ignore - self._emojis[emoji_id] = emoji = AppEmoji(application_id=application_id, state=self, data=data) + self._emojis[emoji_id] = emoji = AppEmoji( + application_id=application_id, state=self, data=data + ) return emoji def store_sticker(self, guild: Guild, data: GuildStickerPayload) -> GuildSticker: @@ -2096,7 +2098,7 @@ async def _delay_ready(self) -> None: self.dispatch("guild_join", guild) 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", []): From 79497e71f3fced37cebcd2e004306122f5de6abc Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Fri, 19 Jul 2024 05:39:38 +0100 Subject: [PATCH 06/24] refinements --- discord/client.py | 44 +++++++++++++++++++------------------------- discord/emoji.py | 9 ++------- discord/state.py | 10 ++++++---- 3 files changed, 27 insertions(+), 36 deletions(-) diff --git a/discord/client.py b/discord/client.py index 7461727d29..417736da2b 100644 --- a/discord/client.py +++ b/discord/client.py @@ -41,7 +41,7 @@ from .application_role_connection import ApplicationRoleConnectionMetadata from .backoff import ExponentialBackoff from .channel import PartialMessageable, _threaded_channel_factory -from .emoji import AppEmoji, Emoji +from .emoji import AppEmoji, GuildEmoji from .enums import ChannelType, Status from .errors import * from .flags import ApplicationFlags, Intents @@ -337,7 +337,7 @@ def guilds(self) -> list[Guild]: return self._connection.guilds @property - def emojis(self) -> list[Emoji | AppEmoji]: + def emojis(self) -> list[GuildEmoji | AppEmoji]: """The emojis that the connected client has. .. note:: @@ -1002,7 +1002,7 @@ def get_user(self, id: int, /) -> User | None: """ return self._connection.get_user(id) - def get_emoji(self, id: int, /) -> Emoji | None: + def get_emoji(self, id: int, /) -> GuildEmoji | AppEmoji | None: """Returns an emoji with the given ID. Parameters @@ -1012,7 +1012,7 @@ def get_emoji(self, id: int, /) -> Emoji | None: Returns ------- - Optional[:class:`.Emoji`] + Optional[:class:`.GuildEmoji` | :class:`.AppEmoji`] The custom emoji or ``None`` if not found. """ return self._connection.get_emoji(id) @@ -2139,10 +2139,10 @@ def store_url(self) -> str: """ return f"https://discord.com/application-directory/{self.application_id}/store" - async def fetch_emojis(self) -> list[Emoji]: + async def fetch_emojis(self) -> list[AppEmoji]: r"""|coro| - Retrieves all custom :class:`Emoji`\s from the application. + Retrieves all custom :class:`AppEmoji`\s from the application. Raises --------- @@ -2155,21 +2155,15 @@ async def fetch_emojis(self) -> list[Emoji]: The retrieved emojis. """ data = await self._state.http.get_all_application_emojis(self.application_id) - if self._state.cache_app_emojis: - return [ - self._state.store_app_emoji(self.application_id, d) - for d in data["items"] - ] - else: - return [ - AppEmoji(application_id=self.application_id, state=self._state, data=d) - for d in data["items"] - ] + return [ + self._state.maybe_store_app_emoji(self.application_id, d) + for d in data["items"] + ] - async def fetch_emoji(self, emoji_id: int, /) -> Emoji: + async def fetch_emoji(self, emoji_id: int, /) -> AppEmoji: """|coro| - Retrieves a custom :class:`Emoji` from the application. + Retrieves a custom :class:`AppEmoji` from the application. Parameters ---------- @@ -2178,7 +2172,7 @@ async def fetch_emoji(self, emoji_id: int, /) -> Emoji: Returns ------- - :class:`Emoji` + :class:`AppEmoji` The retrieved emoji. Raises @@ -2191,17 +2185,17 @@ async def fetch_emoji(self, emoji_id: int, /) -> Emoji: data = await self._state.http.get_application_emoji( self.application_id, emoji_id ) - return Emoji(guild=None, state=self._state, data=data) + return self._state.maybe_store_app_emoji(self.application_id, data) async def create_emoji( self, *, name: str, image: bytes, - ) -> Emoji: + ) -> AppEmoji: r"""|coro| - Creates a custom :class:`Emoji` for the application. + Creates a custom :class:`AppEmoji` for the application. There is currently a limit of 2000 emojis per application. @@ -2222,7 +2216,7 @@ async def create_emoji( Returns -------- - :class:`Emoji` + :class:`AppEmoji` The created emoji. """ @@ -2230,14 +2224,14 @@ async def create_emoji( data = await self._state.http.create_application_emoji( self.application_id, name, img ) - return self._state.store_app_emoji(self.application_id, data) + return self._state.maybe_store_app_emoji(self.application_id, data) async def delete_emoji( self, emoji: Snowflake, *, reason: str | None = None ) -> None: """|coro| - Deletes the custom :class:`Emoji` from the application. + Deletes the custom :class:`AppEmoji` from the application. Parameters ---------- diff --git a/discord/emoji.py b/discord/emoji.py index b7777872cd..0e3355d790 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -359,7 +359,7 @@ def is_usable(self) -> bool: """Whether the bot can use this emoji.""" return self.application_id == self._state.application_id - async def delete(self, *, reason: str | None = None) -> None: + async def delete(self) -> None: """|coro| Deletes the application emoji. @@ -414,9 +414,4 @@ async def edit( data = await self._state.http.edit_application_emoji( self.application_id, self.id, payload=payload ) - if self._state.cache_app_emojis: - return self._state.store_app_emoji(self.application_id, data) - else: - return AppEmoji( - application_id=self.application_id, data=data, state=self._state - ) + return self._state.maybe_store_app_emoji(self.application_id, data) \ No newline at end of file diff --git a/discord/state.py b/discord/state.py index 5f1eaa9950..b3bedfaff2 100644 --- a/discord/state.py +++ b/discord/state.py @@ -382,12 +382,14 @@ 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_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: + def maybe_store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: # the id will be present here - emoji_id = int(data["id"]) # type: ignore - self._emojis[emoji_id] = emoji = AppEmoji( + emoji = AppEmoji( 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: @@ -2102,7 +2104,7 @@ async def _delay_ready(self) -> None: 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_app_emoji(self.application_id, e) + self.maybe_store_app_emoji(self.application_id, e) # remove the state try: From 6e5338e2b1f35d08b3b8113df1cec6a1755fbe1b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 04:40:23 +0000 Subject: [PATCH 07/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/emoji.py | 2 +- discord/state.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/discord/emoji.py b/discord/emoji.py index 0e3355d790..442a77c94b 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -414,4 +414,4 @@ async def edit( data = await self._state.http.edit_application_emoji( self.application_id, self.id, payload=payload ) - return self._state.maybe_store_app_emoji(self.application_id, data) \ No newline at end of file + return self._state.maybe_store_app_emoji(self.application_id, data) diff --git a/discord/state.py b/discord/state.py index b3bedfaff2..6ac1b51cb9 100644 --- a/discord/state.py +++ b/discord/state.py @@ -382,11 +382,11 @@ def store_emoji(self, guild: Guild, data: EmojiPayload) -> GuildEmoji: self._emojis[emoji_id] = emoji = GuildEmoji(guild=guild, state=self, data=data) return emoji - def maybe_store_app_emoji(self, application_id: int, data: EmojiPayload) -> AppEmoji: + def maybe_store_app_emoji( + self, application_id: int, data: EmojiPayload + ) -> AppEmoji: # the id will be present here - emoji = AppEmoji( - application_id=application_id, state=self, data=data - ) + emoji = AppEmoji(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 From 0aa1f8e76c79b37908da91e2307d0657edf53cb4 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:03:04 +0100 Subject: [PATCH 08/24] fix kwargs --- discord/emoji.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/emoji.py b/discord/emoji.py index 442a77c94b..8ab234611c 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -169,7 +169,7 @@ class GuildEmoji(BaseEmoji): def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): self.guild_id: int = guild.id - super().__init__(state, data) + super().__init__(state=state, data=data) def __repr__(self) -> str: return ( @@ -340,7 +340,7 @@ def __init__( self, *, application_id: int, state: ConnectionState, data: EmojiPayload ): self.application_id: int = application_id - super().__init__(state, data) + super().__init__(state=state, data=data) def __repr__(self) -> str: return "" From e9fae0fc562c6bab61a1a38bd9588417f5126a88 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:06:05 +0100 Subject: [PATCH 09/24] _state -> _connection --- discord/client.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/discord/client.py b/discord/client.py index 417736da2b..7893abf7ed 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2154,9 +2154,9 @@ async def fetch_emojis(self) -> list[AppEmoji]: List[:class:`AppEmoji`] The retrieved emojis. """ - data = await self._state.http.get_all_application_emojis(self.application_id) + data = await self._connection.http.get_all_application_emojis(self.application_id) return [ - self._state.maybe_store_app_emoji(self.application_id, d) + self._connection.maybe_store_app_emoji(self.application_id, d) for d in data["items"] ] @@ -2182,10 +2182,10 @@ async def fetch_emoji(self, emoji_id: int, /) -> AppEmoji: HTTPException An error occurred fetching the emoji. """ - data = await self._state.http.get_application_emoji( + data = await self._connection.http.get_application_emoji( self.application_id, emoji_id ) - return self._state.maybe_store_app_emoji(self.application_id, data) + return self._connection.maybe_store_app_emoji(self.application_id, data) async def create_emoji( self, @@ -2221,10 +2221,10 @@ async def create_emoji( """ img = utils._bytes_to_base64_data(image) - data = await self._state.http.create_application_emoji( + data = await self._connection.http.create_application_emoji( self.application_id, name, img ) - return self._state.maybe_store_app_emoji(self.application_id, data) + return self._connection.maybe_store_app_emoji(self.application_id, data) async def delete_emoji( self, emoji: Snowflake, *, reason: str | None = None @@ -2244,6 +2244,6 @@ async def delete_emoji( An error occurred deleting the emoji. """ - await self._state.http.delete_application_emoji(self.application_id, emoji.id) - if self._state.cache_app_emojis and self._state.get_emoji(emoji.id): - self._state.remove_emoji(emoji) + await self._connection.http.delete_application_emoji(self.application_id, emoji.id) + if self._connection.cache_app_emojis and self._connection.get_emoji(emoji.id): + self._connection.remove_emoji(emoji) From f2e81c76b53be0b9850bba5d2c1a49c3e2a8fd7e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:06:28 +0000 Subject: [PATCH 10/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/client.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/discord/client.py b/discord/client.py index 7893abf7ed..d45dd6a7ed 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2154,7 +2154,9 @@ async def fetch_emojis(self) -> list[AppEmoji]: List[:class:`AppEmoji`] The retrieved emojis. """ - data = await self._connection.http.get_all_application_emojis(self.application_id) + data = await self._connection.http.get_all_application_emojis( + self.application_id + ) return [ self._connection.maybe_store_app_emoji(self.application_id, d) for d in data["items"] @@ -2244,6 +2246,8 @@ async def delete_emoji( An error occurred deleting the emoji. """ - await self._connection.http.delete_application_emoji(self.application_id, emoji.id) + await self._connection.http.delete_application_emoji( + self.application_id, emoji.id + ) if self._connection.cache_app_emojis and self._connection.get_emoji(emoji.id): self._connection.remove_emoji(emoji) From 3f04a98f6c6f261928c66e257c20632c96cee716 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:33:33 +0100 Subject: [PATCH 11/24] cache on ready --- discord/state.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/discord/state.py b/discord/state.py index 6ac1b51cb9..2fd575f769 100644 --- a/discord/state.py +++ b/discord/state.py @@ -643,6 +643,11 @@ async def _delay_ready(self) -> None: except AttributeError: pass # already been deleted somehow + 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.maybe_store_app_emoji(self.application_id, e) + except asyncio.CancelledError: pass else: From 1244e4f19778677206725f99c9d349125176c94a Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:42:35 +0100 Subject: [PATCH 12/24] full cache --- discord/client.py | 17 ++++++++++++++++- discord/state.py | 10 +++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/discord/client.py b/discord/client.py index d45dd6a7ed..3f6b8bfb17 100644 --- a/discord/client.py +++ b/discord/client.py @@ -342,10 +342,25 @@ def emojis(self) -> list[GuildEmoji | AppEmoji]: .. note:: - This only includes the application's emojis if :attr:`~Client.cache_app_emojis` is ``True``. + This only includes the application's emojis if `cache_app_emojis` is ``True``. """ return self._connection.emojis + @property + def guild_emojis(self) -> list[GuildEmoji]: + """The :class:`~discord.GuildEmoji` that the connected client has.""" + return [e for e in self.emojis if isinstance(e, GuildEmoji)] + + @property + def app_emojis(self) -> list[AppEmoji]: + """The :class:`~discord.AppEmoji` that the connected client has. + + .. note:: + + This is only available if `cache_app_emojis` is ``True``. + """ + return [e for e in self.emojis if isinstance(e, AppEmoji)] + @property def stickers(self) -> list[GuildSticker]: """The stickers that the connected client has. diff --git a/discord/state.py b/discord/state.py index 2fd575f769..8a0d9b2204 100644 --- a/discord/state.py +++ b/discord/state.py @@ -602,6 +602,11 @@ async def query_members( raise async def _delay_ready(self) -> None: + + 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.maybe_store_app_emoji(self.application_id, e) try: states = [] while True: @@ -643,11 +648,6 @@ async def _delay_ready(self) -> None: except AttributeError: pass # already been deleted somehow - 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.maybe_store_app_emoji(self.application_id, e) - except asyncio.CancelledError: pass else: From 5d389f9fa12dd0b5a9bf34a98c8b0535cd618564 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:49:03 +0100 Subject: [PATCH 13/24] remove delete reason --- discord/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/client.py b/discord/client.py index 3f6b8bfb17..5005fe3bb8 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2244,7 +2244,7 @@ async def create_emoji( return self._connection.maybe_store_app_emoji(self.application_id, data) async def delete_emoji( - self, emoji: Snowflake, *, reason: str | None = None + self, emoji: Snowflake ) -> None: """|coro| From 42d3887cc3c0daf2c29885a83fbc7933c89975af Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:49:32 +0000 Subject: [PATCH 14/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/client.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/discord/client.py b/discord/client.py index 5005fe3bb8..08ad9048b6 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2243,9 +2243,7 @@ async def create_emoji( ) return self._connection.maybe_store_app_emoji(self.application_id, data) - async def delete_emoji( - self, emoji: Snowflake - ) -> None: + async def delete_emoji(self, emoji: Snowflake) -> None: """|coro| Deletes the custom :class:`AppEmoji` from the application. From 7b46217dc7e3b9d93083ba7939099c84657c68bc Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:47:51 +0100 Subject: [PATCH 15/24] adjust slots --- discord/emoji.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/discord/emoji.py b/discord/emoji.py index 8ab234611c..32d6a8f2c2 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -56,9 +56,6 @@ class BaseEmoji(_EmojiTag, AssetMixin): "managed", "id", "name", - "_roles", - "guild_id", - "application_id", "_state", "user", "available", @@ -75,7 +72,6 @@ def _from_data(self, emoji: EmojiPayload): self.name: str = emoji["name"] # type: ignore self.animated: bool = emoji.get("animated", False) self.available: bool = emoji.get("available", True) - self._roles: SnowflakeList = SnowflakeList(map(int, emoji.get("roles", []))) user = emoji.get("user") self.user: User | None = User(state=self._state, data=user) if user else None @@ -167,8 +163,14 @@ class GuildEmoji(BaseEmoji): having the :attr:`~Permissions.manage_emojis` permission. """ + __slots__: tuple[str, ...] = ( + "_roles", + "guild_id", + ) + def __init__(self, *, guild: Guild, state: ConnectionState, data: EmojiPayload): self.guild_id: int = guild.id + self._roles: SnowflakeList = SnowflakeList(map(int, data.get("roles", []))) super().__init__(state=state, data=data) def __repr__(self) -> str: @@ -336,6 +338,10 @@ class AppEmoji(BaseEmoji): The user that created the emoji. """ + __slots__: tuple[str, ...] = ( + "application_id", + ) + def __init__( self, *, application_id: int, state: ConnectionState, data: EmojiPayload ): From d14413fb0a3715c864a74be4c6f2e8f099419c44 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 19:48:17 +0000 Subject: [PATCH 16/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/emoji.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/discord/emoji.py b/discord/emoji.py index 32d6a8f2c2..c0455b4a00 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -338,9 +338,7 @@ class AppEmoji(BaseEmoji): The user that created the emoji. """ - __slots__: tuple[str, ...] = ( - "application_id", - ) + __slots__: tuple[str, ...] = ("application_id",) def __init__( self, *, application_id: int, state: ConnectionState, data: EmojiPayload From c01e384f0a7c259416930fa8429c92036463e0b8 Mon Sep 17 00:00:00 2001 From: plun1331 Date: Tue, 10 Sep 2024 13:02:39 -0700 Subject: [PATCH 17/24] Update discord/emoji.py Signed-off-by: plun1331 --- discord/emoji.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/emoji.py b/discord/emoji.py index c0455b4a00..2448b2f9e5 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -92,7 +92,7 @@ def __str__(self) -> str: def __repr__(self) -> str: return ( - "" + f"" ) def __eq__(self, other: Any) -> bool: From 0381a6e7ee399208cf71883fa2fbb0ed1f76a3a5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:03:02 +0000 Subject: [PATCH 18/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/emoji.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/discord/emoji.py b/discord/emoji.py index 2448b2f9e5..417751fce8 100644 --- a/discord/emoji.py +++ b/discord/emoji.py @@ -91,9 +91,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 From 4ccf9b1f3b4a6986848ed908b29ccb78855e29e7 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:45:15 +0100 Subject: [PATCH 19/24] update all references to the Emoji class --- discord/abc.py | 8 +++---- discord/audit_logs.py | 6 ++--- discord/channel.py | 12 +++++----- discord/components.py | 8 +++---- discord/ext/commands/converter.py | 8 +++---- discord/ext/pages/pagination.py | 12 +++++----- discord/flags.py | 2 +- discord/guild.py | 40 +++++++++++++++---------------- discord/message.py | 20 ++++++++-------- discord/onboarding.py | 8 +++---- discord/poll.py | 16 ++++++------- discord/reaction.py | 8 +++---- discord/state.py | 6 ++--- discord/ui/button.py | 18 +++++++------- discord/ui/select.py | 8 +++---- discord/welcome_screen.py | 6 ++--- docs/api/enums.rst | 4 ++-- docs/api/events.rst | 6 ++--- docs/ext/commands/commands.rst | 4 ++-- docs/faq.rst | 2 +- 20 files changed, 101 insertions(+), 101 deletions(-) diff --git a/discord/abc.py b/discord/abc.py index d699f44702..2eccbfbebe 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -513,7 +513,7 @@ async def _edit( except KeyError: pass else: - if isinstance(default_reaction_emoji, _EmojiTag): # Emoji, PartialEmoji + if isinstance(default_reaction_emoji, _EmojiTag): # GuildEmoji, PartialEmoji default_reaction_emoji = default_reaction_emoji._to_partial() elif isinstance(default_reaction_emoji, int): default_reaction_emoji = PartialEmoji( @@ -523,7 +523,7 @@ async def _edit( default_reaction_emoji = PartialEmoji.from_str(default_reaction_emoji) else: raise InvalidArgument( - "default_reaction_emoji must be of type: Emoji | int | str" + "default_reaction_emoji must be of type: GuildEmoji | int | str" ) options["default_reaction_emoji"] = ( @@ -1792,7 +1792,7 @@ def can_send(self, *objects) -> bool: "Message": "send_messages", "Embed": "embed_links", "File": "attach_files", - "Emoji": "use_external_emojis", + "GuildEmoji": "use_external_emojis", "GuildSticker": "use_external_stickers", } # Can't use channel = await self._get_channel() since its async @@ -1817,7 +1817,7 @@ def can_send(self, *objects) -> bool: mapping.get(type(obj).__name__) or mapping[obj.__name__] ) - if type(obj).__name__ == "Emoji": + if type(obj).__name__ == "GuildEmoji": if ( obj._to_partial().is_unicode_emoji or obj.guild_id == channel.guild.id diff --git a/discord/audit_logs.py b/discord/audit_logs.py index 7497e8c37a..e2ff277dfe 100644 --- a/discord/audit_logs.py +++ b/discord/audit_logs.py @@ -47,7 +47,7 @@ import datetime from . import abc - from .emoji import Emoji + from .emoji import GuildEmoji from .guild import Guild from .member import Member from .role import Role @@ -617,7 +617,7 @@ def target( | User | Role | Invite - | Emoji + | GuildEmoji | StageInstance | GuildSticker | Thread @@ -689,7 +689,7 @@ def _convert_target_invite(self, target_id: int) -> Invite: pass return obj - def _convert_target_emoji(self, target_id: int) -> Emoji | Object: + def _convert_target_emoji(self, target_id: int) -> GuildEmoji | Object: return self._state.get_emoji(target_id) or Object(id=target_id) def _convert_target_message(self, target_id: int) -> Member | User | None: diff --git a/discord/channel.py b/discord/channel.py index 27230a380f..d70083d9f7 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -32,7 +32,7 @@ from . import utils from .asset import Asset -from .emoji import Emoji +from .emoji import GuildEmoji from .enums import ( ChannelType, EmbeddedActivity, @@ -143,7 +143,7 @@ def __init__( self.emoji = PartialEmoji.from_str(emoji) else: raise TypeError( - "emoji must be a Emoji, PartialEmoji, or str and not" + "emoji must be a GuildEmoji, PartialEmoji, or str and not" f" {emoji.__class__!r}" ) @@ -1018,7 +1018,7 @@ class ForumChannel(_TextChannel): The initial slowmode delay to set on newly created threads in this channel. .. versionadded:: 2.3 - default_reaction_emoji: Optional[:class:`str` | :class:`discord.Emoji`] + default_reaction_emoji: Optional[:class:`str` | :class:`discord.GuildEmoji`] The default forum reaction emoji. .. versionadded:: 2.5 @@ -1087,7 +1087,7 @@ async def edit( default_auto_archive_duration: ThreadArchiveDuration = ..., default_thread_slowmode_delay: int = ..., default_sort_order: SortOrder = ..., - default_reaction_emoji: Emoji | int | str | None = ..., + default_reaction_emoji: GuildEmoji | int | str | None = ..., available_tags: list[ForumTag] = ..., require_tag: bool = ..., overwrites: Mapping[Role | Member | Snowflake, PermissionOverwrite] = ..., @@ -1138,10 +1138,10 @@ async def edit(self, *, reason=None, **options): The default sort order type to use to order posts in this channel. .. versionadded:: 2.3 - default_reaction_emoji: Optional[:class:`discord.Emoji` | :class:`int` | :class:`str`] + default_reaction_emoji: Optional[:class:`discord.GuildEmoji` | :class:`int` | :class:`str`] The default reaction emoji. Can be a unicode emoji or a custom emoji in the forms: - :class:`Emoji`, snowflake ID, string representation (eg. ''). + :class:`GuildEmoji`, snowflake ID, string representation (eg. ''). .. versionadded:: 2.5 available_tags: List[:class:`ForumTag`] diff --git a/discord/components.py b/discord/components.py index d85fc4b07c..cd4874896e 100644 --- a/discord/components.py +++ b/discord/components.py @@ -32,7 +32,7 @@ from .utils import MISSING, get_slots if TYPE_CHECKING: - from .emoji import Emoji + from .emoji import GuildEmoji, AppEmoji from .types.components import ActionRow as ActionRowPayload from .types.components import ButtonComponent as ButtonComponentPayload from .types.components import Component as ComponentPayload @@ -412,7 +412,7 @@ def __init__( label: str, value: str = MISSING, description: str | None = None, - emoji: str | Emoji | PartialEmoji | None = None, + emoji: str | GuildEmoji | AppEmoji | PartialEmoji | None = None, default: bool = False, ) -> None: if len(label) > 100: @@ -444,7 +444,7 @@ def __str__(self) -> str: return base @property - def emoji(self) -> str | Emoji | PartialEmoji | None: + def emoji(self) -> str | GuildEmoji | AppEmoji | PartialEmoji | None: """The emoji of the option, if available.""" return self._emoji @@ -457,7 +457,7 @@ def emoji(self, value) -> None: value = value._to_partial() else: raise TypeError( - "expected emoji to be str, Emoji, or PartialEmoji not" + "expected emoji to be str, GuildEmoji, AppEmoji, or PartialEmoji, not" f" {value.__class__}" ) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index 3ed53fa1d0..e60ac89b34 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -805,8 +805,8 @@ async def convert(self, ctx: Context, argument: str) -> discord.Guild: return result -class EmojiConverter(IDConverter[discord.Emoji]): - """Converts to a :class:`~discord.Emoji`. +class EmojiConverter(IDConverter[discord.GuildEmoji]): + """Converts to a :class:`~discord.GuildEmoji`. All lookups are done for the local guild first, if available. If that lookup fails, then it checks the client's global cache. @@ -821,7 +821,7 @@ class EmojiConverter(IDConverter[discord.Emoji]): Raise :exc:`.EmojiNotFound` instead of generic :exc:`.BadArgument` """ - async def convert(self, ctx: Context, argument: str) -> discord.Emoji: + async def convert(self, ctx: Context, argument: str) -> discord.GuildEmoji: match = self._get_id_match(argument) or re.match( r"$", argument ) @@ -1111,7 +1111,7 @@ def is_generic_type(tp: Any, *, _GenericAlias: type = _GenericAlias) -> bool: discord.Colour: ColourConverter, discord.VoiceChannel: VoiceChannelConverter, discord.StageChannel: StageChannelConverter, - discord.Emoji: EmojiConverter, + discord.GuildEmoji: EmojiConverter, discord.PartialEmoji: PartialEmojiConverter, discord.CategoryChannel: CategoryChannelConverter, discord.ForumChannel: ForumChannelConverter, diff --git a/discord/ext/pages/pagination.py b/discord/ext/pages/pagination.py index d3f2d32800..15efdba6d1 100644 --- a/discord/ext/pages/pagination.py +++ b/discord/ext/pages/pagination.py @@ -54,7 +54,7 @@ class PaginatorButton(discord.ui.Button): label: :class:`str` The label shown on the button. Defaults to a capitalized version of ``button_type`` (e.g. "Next", "Prev", etc.) - emoji: Union[:class:`str`, :class:`discord.Emoji`, :class:`discord.PartialEmoji`] + emoji: Union[:class:`str`, :class:`discord.GuildEmoji`, :class:`discord.AppEmoji`, :class:`discord.PartialEmoji`] The emoji shown on the button in front of the label. disabled: :class:`bool` Whether to initially show the button as disabled. @@ -72,7 +72,7 @@ def __init__( self, button_type: str, label: str = None, - emoji: str | discord.Emoji | discord.PartialEmoji = None, + emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = None, style: discord.ButtonStyle = discord.ButtonStyle.green, disabled: bool = False, custom_id: str = None, @@ -89,7 +89,7 @@ def __init__( ) self.button_type = button_type self.label = label if label or emoji else button_type.capitalize() - self.emoji: str | discord.Emoji | discord.PartialEmoji = emoji + self.emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = emoji self.style = style self.disabled = disabled self.loop_label = self.label if not loop_label else loop_label @@ -242,7 +242,7 @@ class PageGroup: Also used as the SelectOption value. description: Optional[:class:`str`] The description shown on the corresponding PaginatorMenu dropdown option. - emoji: Union[:class:`str`, :class:`discord.Emoji`, :class:`discord.PartialEmoji`] + emoji: Union[:class:`str`, :class:`discord.GuildEmoji`, :class:`discord.AppEmoji`, :class:`discord.PartialEmoji`] The emoji shown on the corresponding PaginatorMenu dropdown option. default: Optional[:class:`bool`] Whether the page group should be the default page group initially shown when the paginator response is sent. @@ -278,7 +278,7 @@ def __init__( pages: list[str] | list[Page] | list[list[discord.Embed] | discord.Embed], label: str, description: str | None = None, - emoji: str | discord.Emoji | discord.PartialEmoji = None, + emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = None, default: bool | None = None, show_disabled: bool | None = None, show_indicator: bool | None = None, @@ -294,7 +294,7 @@ def __init__( ): self.label = label self.description: str | None = description - self.emoji: str | discord.Emoji | discord.PartialEmoji = emoji + self.emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = emoji self.pages: list[str] | list[list[discord.Embed] | discord.Embed] = pages self.default: bool | None = default self.show_disabled = show_disabled diff --git a/discord/flags.py b/discord/flags.py index 8a1ac8fd7e..1a6af50c72 100644 --- a/discord/flags.py +++ b/discord/flags.py @@ -769,7 +769,7 @@ def emojis_and_stickers(self): This also corresponds to the following attributes and classes in terms of cache: - - :class:`Emoji` + - :class:`GuildEmoji` - :class:`GuildSticker` - :meth:`Client.get_emoji` - :meth:`Client.get_sticker` diff --git a/discord/guild.py b/discord/guild.py index 75fcc7c5c7..4610e98790 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -46,7 +46,7 @@ from .channel import * from .channel import _guild_channel_factory, _threaded_guild_channel_factory from .colour import Colour -from .emoji import Emoji, PartialEmoji, _EmojiTag +from .emoji import GuildEmoji, PartialEmoji, _EmojiTag from .enums import ( AuditLogAction, AutoModEventType, @@ -161,7 +161,7 @@ class Guild(Hashable): ---------- name: :class:`str` The guild name. - emojis: Tuple[:class:`Emoji`, ...] + emojis: Tuple[:class:`GuildEmoji`, ...] All emojis that the guild owns. stickers: Tuple[:class:`GuildSticker`, ...] All stickers that the guild owns. @@ -476,7 +476,7 @@ def _from_data(self, guild: GuildPayload) -> None: self._roles[role.id] = role self.mfa_level: MFALevel = guild.get("mfa_level") - self.emojis: tuple[Emoji, ...] = tuple( + self.emojis: tuple[GuildEmoji, ...] = tuple( map(lambda d: state.store_emoji(self, d), guild.get("emojis", [])) ) self.stickers: tuple[GuildSticker, ...] = tuple( @@ -1404,7 +1404,7 @@ async def create_forum_channel( slowmode_delay: int = MISSING, nsfw: bool = MISSING, overwrites: dict[Role | Member, PermissionOverwrite] = MISSING, - default_reaction_emoji: Emoji | int | str = MISSING, + default_reaction_emoji: GuildEmoji | int | str = MISSING, ) -> ForumChannel: """|coro| @@ -1446,10 +1446,10 @@ async def create_forum_channel( To mark the channel as NSFW or not. reason: Optional[:class:`str`] The reason for creating this channel. Shows up on the audit log. - default_reaction_emoji: Optional[:class:`Emoji` | :class:`int` | :class:`str`] + default_reaction_emoji: Optional[:class:`GuildEmoji` | :class:`int` | :class:`str`] The default reaction emoji. Can be a unicode emoji or a custom emoji in the forms: - :class:`Emoji`, snowflake ID, string representation (eg. ''). + :class:`GuildEmoji`, snowflake ID, string representation (eg. ''). .. versionadded:: v2.5 @@ -1502,7 +1502,7 @@ async def create_forum_channel( options["nsfw"] = nsfw if default_reaction_emoji is not MISSING: - if isinstance(default_reaction_emoji, _EmojiTag): # Emoji, PartialEmoji + if isinstance(default_reaction_emoji, _EmojiTag): # GuildEmoji, PartialEmoji default_reaction_emoji = default_reaction_emoji._to_partial() elif isinstance(default_reaction_emoji, int): default_reaction_emoji = PartialEmoji( @@ -1512,7 +1512,7 @@ async def create_forum_channel( default_reaction_emoji = PartialEmoji.from_str(default_reaction_emoji) else: raise InvalidArgument( - "default_reaction_emoji must be of type: Emoji | int | str" + "default_reaction_emoji must be of type: GuildEmoji | int | str" ) options["default_reaction_emoji"] = ( @@ -2662,10 +2662,10 @@ async def delete_sticker( """ await self._state.http.delete_guild_sticker(self.id, sticker.id, reason) - async def fetch_emojis(self) -> list[Emoji]: + async def fetch_emojis(self) -> list[GuildEmoji]: r"""|coro| - Retrieves all custom :class:`Emoji`\s from the guild. + Retrieves all custom :class:`GuildEmoji`\s from the guild. .. note:: @@ -2678,16 +2678,16 @@ async def fetch_emojis(self) -> list[Emoji]: Returns -------- - List[:class:`Emoji`] + List[:class:`GuildEmoji`] The retrieved emojis. """ data = await self._state.http.get_all_custom_emojis(self.id) - return [Emoji(guild=self, state=self._state, data=d) for d in data] + return [GuildEmoji(guild=self, state=self._state, data=d) for d in data] - async def fetch_emoji(self, emoji_id: int, /) -> Emoji: + async def fetch_emoji(self, emoji_id: int, /) -> GuildEmoji: """|coro| - Retrieves a custom :class:`Emoji` from the guild. + Retrieves a custom :class:`GuildEmoji` from the guild. .. note:: @@ -2701,7 +2701,7 @@ async def fetch_emoji(self, emoji_id: int, /) -> Emoji: Returns ------- - :class:`Emoji` + :class:`GuildEmoji` The retrieved emoji. Raises @@ -2712,7 +2712,7 @@ async def fetch_emoji(self, emoji_id: int, /) -> Emoji: An error occurred fetching the emoji. """ data = await self._state.http.get_custom_emoji(self.id, emoji_id) - return Emoji(guild=self, state=self._state, data=data) + return GuildEmoji(guild=self, state=self._state, data=data) async def create_custom_emoji( self, @@ -2721,10 +2721,10 @@ async def create_custom_emoji( image: bytes, roles: list[Role] = MISSING, reason: str | None = None, - ) -> Emoji: + ) -> GuildEmoji: r"""|coro| - Creates a custom :class:`Emoji` for the guild. + Creates a custom :class:`GuildEmoji` for the guild. There is currently a limit of 50 static and animated emojis respectively per guild, unless the guild has the ``MORE_EMOJI`` feature which extends the limit to 200. @@ -2753,7 +2753,7 @@ async def create_custom_emoji( Returns -------- - :class:`Emoji` + :class:`GuildEmoji` The created emoji. """ @@ -2769,7 +2769,7 @@ async def delete_emoji( ) -> None: """|coro| - Deletes the custom :class:`Emoji` from the guild. + Deletes the custom :class:`GuildEmoji` from the guild. You must have :attr:`~Permissions.manage_emojis` permission to do this. diff --git a/discord/message.py b/discord/message.py index 56d1cec968..b9927aa9b6 100644 --- a/discord/message.py +++ b/discord/message.py @@ -45,7 +45,7 @@ from .channel import PartialMessageable from .components import _component_factory from .embeds import Embed -from .emoji import Emoji +from .emoji import GuildEmoji, AppEmoji from .enums import ChannelType, MessageType, try_enum from .errors import InvalidArgument from .file import File @@ -93,7 +93,7 @@ from .user import User MR = TypeVar("MR", bound="MessageReference") - EmojiInputType = Union[Emoji, PartialEmoji, str] + EmojiInputType = Union[GuildEmoji, AppEmoji, PartialEmoji, str] __all__ = ( "Attachment", @@ -109,7 +109,7 @@ def convert_emoji_reaction(emoji): if isinstance(emoji, Reaction): emoji = emoji.emoji - if isinstance(emoji, Emoji): + if isinstance(emoji, (GuildEmoji, AppEmoji)): return f"{emoji.name}:{emoji.id}" if isinstance(emoji, PartialEmoji): return emoji._as_reaction() @@ -119,7 +119,7 @@ def convert_emoji_reaction(emoji): return emoji.strip("<>") raise InvalidArgument( - "emoji argument must be str, Emoji, or Reaction not" + "emoji argument must be str, GuildEmoji, AppEmoji, or Reaction not" f" {emoji.__class__.__name__}." ) @@ -1723,7 +1723,7 @@ async def add_reaction(self, emoji: EmojiInputType) -> None: Add a reaction to the message. - The emoji may be a unicode emoji or a custom guild :class:`Emoji`. + The emoji may be a unicode emoji, a custom :class:`GuildEmoji`, or an :class:`AppEmoji`. You must have the :attr:`~Permissions.read_message_history` permission to use this. If nobody else has reacted to the message using this @@ -1731,7 +1731,7 @@ async def add_reaction(self, emoji: EmojiInputType) -> None: Parameters ---------- - emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] + emoji: Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] The emoji to react with. Raises @@ -1756,7 +1756,7 @@ async def remove_reaction( Remove a reaction by the member from the message. - The emoji may be a unicode emoji or a custom guild :class:`Emoji`. + The emoji may be a unicode emoji, a custom :class:`GuildEmoji`, or an :class:`AppEmoji`. If the reaction is not your own (i.e. ``member`` parameter is not you) then the :attr:`~Permissions.manage_messages` permission is needed. @@ -1766,7 +1766,7 @@ async def remove_reaction( Parameters ---------- - emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] + emoji: Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] The emoji to remove. member: :class:`abc.Snowflake` The member for which to remove the reaction. @@ -1797,7 +1797,7 @@ async def clear_reaction(self, emoji: EmojiInputType | Reaction) -> None: Clears a specific reaction from the message. - The emoji may be a unicode emoji or a custom guild :class:`Emoji`. + The emoji may be a unicode emoji, a custom :class:`GuildEmoji`, or an :class:`AppEmoji`. You need the :attr:`~Permissions.manage_messages` permission to use this. @@ -1805,7 +1805,7 @@ async def clear_reaction(self, emoji: EmojiInputType | Reaction) -> None: Parameters ---------- - emoji: Union[:class:`Emoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] + emoji: Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`Reaction`, :class:`PartialEmoji`, :class:`str`] The emoji to clear. Raises diff --git a/discord/onboarding.py b/discord/onboarding.py index bd98bbfdde..cf6a721a00 100644 --- a/discord/onboarding.py +++ b/discord/onboarding.py @@ -33,7 +33,7 @@ if TYPE_CHECKING: from .abc import Snowflake from .channel import ForumChannel, TextChannel, VoiceChannel - from .emoji import Emoji + from .emoji import GuildEmoji from .guild import Guild from .object import Object from .partial_emoji import PartialEmoji @@ -62,7 +62,7 @@ class PromptOption: The channels assigned to the user when they select this option. roles: List[:class:`Snowflake`] The roles assigned to the user when they select this option. - emoji: Union[:class:`Emoji`, :class:`PartialEmoji`] + emoji: Union[:class:`GuildEmoji`, :class:`PartialEmoji`] The emoji displayed with the option. title: :class:`str` The option's title. @@ -76,7 +76,7 @@ def __init__( channels: list[Snowflake] | None = None, roles: list[Snowflake] | None = None, description: str | None = None, - emoji: Emoji | PartialEmoji | None = None, + emoji: GuildEmoji | PartialEmoji | None = None, id: int | None = None, ): # ID is required when making edits, but it can be any snowflake that isn't already used by another prompt during edits @@ -85,7 +85,7 @@ def __init__( self.channels: list[Snowflake] = channels or [] self.roles: list[Snowflake] = roles or [] self.description: str | None = description or None - self.emoji: Emoji | PartialEmoji | None = emoji + self.emoji: GuildEmoji | PartialEmoji | None = emoji def __repr__(self): return f"" diff --git a/discord/poll.py b/discord/poll.py index 25c964cfec..12dfc59ea5 100644 --- a/discord/poll.py +++ b/discord/poll.py @@ -43,7 +43,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import Emoji + from .emoji import GuildEmoji, AppEmoji from .message import Message, PartialMessage from .types.poll import Poll as PollPayload from .types.poll import PollAnswer as PollAnswerPayload @@ -62,13 +62,13 @@ class PollMedia: text: :class:`str` The question/answer text. May have up to 300 characters for questions and 55 characters for answers. - emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]] + emoji: Optional[Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`PartialEmoji`, :class:`str`]] The answer's emoji. """ - def __init__(self, text: str, emoji: Emoji | PartialEmoji | str | None = None): + def __init__(self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None): self.text: str = text - self.emoji: Emoji | PartialEmoji | str | None = emoji + self.emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = emoji def to_dict(self) -> PollMediaPayload: dict_ = { @@ -124,7 +124,7 @@ class PollAnswer: The relevant media for this answer. """ - def __init__(self, text: str, emoji: Emoji | PartialEmoji | str | None = None): + def __init__(self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None): self.media = PollMedia(text, emoji) self.id = None self._poll = None @@ -135,7 +135,7 @@ def text(self) -> str: return self.media.text @property - def emoji(self) -> Emoji | PartialEmoji | None: + def emoji(self) -> GuildEmoji | AppEmoji | PartialEmoji | None: """The answer's emoji. Shortcut for :attr:`PollMedia.emoji`.""" return self.media.emoji @@ -446,7 +446,7 @@ def get_answer(self, id) -> PollAnswer | None: return utils.get(self.answers, id=id) def add_answer( - self, text: str, *, emoji: Emoji | PartialEmoji | str | None = None + self, text: str, *, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None ) -> Poll: """Add an answer to this poll. @@ -457,7 +457,7 @@ def add_answer( ---------- text: :class:`str` The answer text. Maximum 55 characters. - emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]] + emoji: Optional[Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`PartialEmoji`, :class:`str`]] The answer's emoji. Raises diff --git a/discord/reaction.py b/discord/reaction.py index 2726e8984f..1279204970 100644 --- a/discord/reaction.py +++ b/discord/reaction.py @@ -35,7 +35,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import Emoji + from .emoji import GuildEmoji, AppEmoji from .message import Message from .partial_emoji import PartialEmoji from .types.message import Reaction as ReactionPayload @@ -70,7 +70,7 @@ class Reaction: Attributes ---------- - emoji: Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`] + emoji: Union[:class:`GuildEmoji`, :class:`AppEmoji`, :class:`PartialEmoji`, :class:`str`] The reaction emoji. May be a custom emoji, or a unicode emoji. count: :class:`int` The combined total of normal and super reactions for this emoji. @@ -100,10 +100,10 @@ def __init__( *, message: Message, data: ReactionPayload, - emoji: PartialEmoji | Emoji | str | None = None, + emoji: PartialEmoji | GuildEmoji | AppEmoji | str | None = None, ): self.message: Message = message - self.emoji: PartialEmoji | Emoji | str = ( + self.emoji: PartialEmoji | GuildEmoji | AppEmoji | str = ( emoji or message._state.get_reaction_emoji(data["emoji"]) ) self.count: int = data.get("count", 1) diff --git a/discord/state.py b/discord/state.py index c6a40504ba..1625fddf91 100644 --- a/discord/state.py +++ b/discord/state.py @@ -275,7 +275,7 @@ def clear(self, *, views: bool = True) -> None: # using __del__. Testing this for memory leaks led to no discernible leaks, # though more testing will have to be done. self._users: dict[int, User] = {} - self._emojis: dict[int, Emoji] = {} + self._emojis: dict[int, (GuildEmoji, AppEmoji)] = {} self._stickers: dict[int, GuildSticker] = {} self._guilds: dict[int, Guild] = {} self._polls: dict[int, Poll] = {} @@ -1952,7 +1952,7 @@ def _get_reaction_user( return channel.guild.get_member(user_id) return self.get_user(user_id) - def get_reaction_emoji(self, data) -> Emoji | PartialEmoji: + def get_reaction_emoji(self, data) -> GuildEmoji | AppEmoji | PartialEmoji: emoji_id = utils._get_as_snowflake(data, "id") if not emoji_id: @@ -1968,7 +1968,7 @@ def get_reaction_emoji(self, data) -> Emoji | PartialEmoji: name=data["name"], ) - def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> Emoji | PartialEmoji | str: + def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> GuildEmoji | AppEmoji | PartialEmoji | str: emoji_id = emoji.id if not emoji_id: return emoji.name diff --git a/discord/ui/button.py b/discord/ui/button.py index 5487fd6b73..2388105d8c 100644 --- a/discord/ui/button.py +++ b/discord/ui/button.py @@ -40,7 +40,7 @@ ) if TYPE_CHECKING: - from ..emoji import Emoji + from ..emoji import GuildEmoji, AppEmoji from .view import View B = TypeVar("B", bound="Button") @@ -65,7 +65,7 @@ class Button(Item[V]): Whether the button is disabled or not. label: Optional[:class:`str`] The label of the button, if any. Maximum of 80 chars. - emoji: Optional[Union[:class:`.PartialEmoji`, :class:`.Emoji`, :class:`str`]] + emoji: Optional[Union[:class:`.PartialEmoji`, :class:`GuildEmoji`, :class:`AppEmoji`, :class:`str`]] The emoji of the button, if available. sku_id: Optional[Union[:class:`int`]] The ID of the SKU this button refers to. @@ -95,7 +95,7 @@ def __init__( disabled: bool = False, custom_id: str | None = None, url: str | None = None, - emoji: str | Emoji | PartialEmoji | None = None, + emoji: str | GuildEmoji | AppEmoji | PartialEmoji | None = None, sku_id: int | None = None, row: int | None = None, ): @@ -132,7 +132,7 @@ def __init__( emoji = emoji._to_partial() else: raise TypeError( - "expected emoji to be str, Emoji, or PartialEmoji not" + "expected emoji to be str, GuildEmoji, AppEmoji, or PartialEmoji not" f" {emoji.__class__}" ) @@ -210,7 +210,7 @@ def emoji(self) -> PartialEmoji | None: return self._underlying.emoji @emoji.setter - def emoji(self, value: str | Emoji | PartialEmoji | None): # type: ignore + def emoji(self, value: str | GuildEmoji | AppEmoji | PartialEmoji | None): # type: ignore if value is None: self._underlying.emoji = None elif isinstance(value, str): @@ -219,7 +219,7 @@ def emoji(self, value: str | Emoji | PartialEmoji | None): # type: ignore self._underlying.emoji = value._to_partial() else: raise TypeError( - "expected str, Emoji, or PartialEmoji, received" + "expected str, GuildEmoji, AppEmoji, or PartialEmoji, received" f" {value.__class__} instead" ) @@ -275,7 +275,7 @@ def button( custom_id: str | None = None, disabled: bool = False, style: ButtonStyle = ButtonStyle.secondary, - emoji: str | Emoji | PartialEmoji | None = None, + emoji: str | GuildEmoji | AppEmoji | PartialEmoji | None = None, row: int | None = None, ) -> Callable[[ItemCallbackType], ItemCallbackType]: """A decorator that attaches a button to a component. @@ -302,9 +302,9 @@ def button( The style of the button. Defaults to :attr:`.ButtonStyle.grey`. disabled: :class:`bool` Whether the button is disabled or not. Defaults to ``False``. - emoji: Optional[Union[:class:`str`, :class:`.Emoji`, :class:`.PartialEmoji`]] + emoji: Optional[Union[:class:`str`, :class:`GuildEmoji`, :class:`AppEmoji`, :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` or :class:`AppEmoji`. 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/discord/ui/select.py b/discord/ui/select.py index fb55d39d1d..bab868d3f1 100644 --- a/discord/ui/select.py +++ b/discord/ui/select.py @@ -31,7 +31,7 @@ from ..channel import _threaded_guild_channel_factory from ..components import SelectMenu, SelectOption -from ..emoji import Emoji +from ..emoji import GuildEmoji, AppEmoji from ..enums import ChannelType, ComponentType from ..errors import InvalidArgument from ..interactions import Interaction @@ -260,7 +260,7 @@ def add_option( label: str, value: str = MISSING, description: str | None = None, - emoji: str | Emoji | PartialEmoji | None = None, + emoji: str | GuildEmoji | AppEmoji | PartialEmoji | None = None, default: bool = False, ): """Adds an option to the select menu. @@ -279,9 +279,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:`AppEmoji`, :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`, :class:`GuildEmoji`, or :class:`AppEmoji`. default: :class:`bool` Whether this option is selected by default. diff --git a/discord/welcome_screen.py b/discord/welcome_screen.py index 7e709ab7a6..cb0d1eea0a 100644 --- a/discord/welcome_screen.py +++ b/discord/welcome_screen.py @@ -32,7 +32,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import Emoji + from .emoji import GuildEmoji from .guild import Guild from .partial_emoji import PartialEmoji from .types.welcome_screen import WelcomeScreen as WelcomeScreenPayload @@ -58,7 +58,7 @@ class WelcomeScreenChannel: The channel that is being referenced. description: :class:`str` The description of the channel that is shown on the welcome screen. - emoji: Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`] + emoji: Union[:class:`GuildEmoji`, :class:`PartialEmoji`, :class:`str`] The emoji of the channel that is shown on welcome screen. """ @@ -66,7 +66,7 @@ def __init__( self, channel: Snowflake, description: str, - emoji: Emoji | PartialEmoji | str, + emoji: GuildEmoji | PartialEmoji | str, ): self.channel = channel self.description = description diff --git a/docs/api/enums.rst b/docs/api/enums.rst index c734e2fd1e..cd48a85cf5 100644 --- a/docs/api/enums.rst +++ b/docs/api/enums.rst @@ -1190,7 +1190,7 @@ of :class:`enum.Enum`. An emoji was created. When this is the action, the type of :attr:`~AuditLogEntry.target` is - the :class:`Emoji` or :class:`Object` with the emoji ID. + the :class:`GuildEmoji` or :class:`Object` with the emoji ID. Possible attributes for :class:`AuditLogDiff`: @@ -1201,7 +1201,7 @@ of :class:`enum.Enum`. An emoji was updated. This triggers when the name has changed. When this is the action, the type of :attr:`~AuditLogEntry.target` is - the :class:`Emoji` or :class:`Object` with the emoji ID. + the :class:`GuildEmoji` or :class:`Object` with the emoji ID. Possible attributes for :class:`AuditLogDiff`: diff --git a/docs/api/events.rst b/docs/api/events.rst index 1b011fa1f4..51652ad925 100644 --- a/docs/api/events.rst +++ b/docs/api/events.rst @@ -518,16 +518,16 @@ Guilds .. function:: on_guild_emojis_update(guild, before, after) - Called when a :class:`Guild` adds or removes an :class:`Emoji`. + Called when a :class:`Guild` adds or removes an :class:`GuildEmoji`. This requires :attr:`Intents.emojis_and_stickers` to be enabled. :param guild: The guild who got their emojis updated. :type guild: :class:`Guild` :param before: A list of emojis before the update. - :type before: Sequence[:class:`Emoji`] + :type before: Sequence[:class:`GuildEmoji`] :param after: A list of emojis after the update. - :type after: Sequence[:class:`Emoji`] + :type after: Sequence[:class:`GuildEmoji`] .. function:: on_guild_stickers_update(guild, before, after) diff --git a/docs/ext/commands/commands.rst b/docs/ext/commands/commands.rst index c907e2a1b4..686f95f047 100644 --- a/docs/ext/commands/commands.rst +++ b/docs/ext/commands/commands.rst @@ -394,7 +394,7 @@ A lot of discord models work out of the gate as a parameter: - :class:`Role` - :class:`Game` - :class:`Colour` -- :class:`Emoji` +- :class:`GuildEmoji` - :class:`PartialEmoji` - :class:`Thread` (since v2.0) @@ -437,7 +437,7 @@ converter is given below: +--------------------------+-------------------------------------------------+ | :class:`Colour` | :class:`~ext.commands.ColourConverter` | +--------------------------+-------------------------------------------------+ -| :class:`Emoji` | :class:`~ext.commands.EmojiConverter` | +| :class:`GuildEmoji` | :class:`~ext.commands.EmojiConverter` | +--------------------------+-------------------------------------------------+ | :class:`PartialEmoji` | :class:`~ext.commands.PartialEmojiConverter` | +--------------------------+-------------------------------------------------+ diff --git a/docs/faq.rst b/docs/faq.rst index dd6ee78e17..bf8bfe82d0 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -199,7 +199,7 @@ Quick example: :: In case you want to use emoji that come from a message, you already get their code points in the content without needing to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands. -For custom emoji, you should pass an instance of :class:`Emoji`. You can also pass a ``'<:name:id>'`` string, but if you +For custom emoji, you should pass an instance of :class:`GuildEmoji` or :class:`AppEmoji`. You can also pass a ``'<:name:id>'`` string, but if you can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/ :func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections. From 1bf8195195b56043d6cf450e60351dc93246e2d8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:45:43 +0000 Subject: [PATCH 20/24] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/abc.py | 4 +++- discord/components.py | 2 +- discord/ext/pages/pagination.py | 16 ++++++++++++---- discord/guild.py | 4 +++- discord/message.py | 2 +- discord/poll.py | 15 +++++++++++---- discord/reaction.py | 2 +- discord/state.py | 4 +++- discord/ui/button.py | 2 +- discord/ui/select.py | 2 +- 10 files changed, 37 insertions(+), 16 deletions(-) diff --git a/discord/abc.py b/discord/abc.py index 2eccbfbebe..7e9d462b89 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -513,7 +513,9 @@ async def _edit( except KeyError: pass else: - if isinstance(default_reaction_emoji, _EmojiTag): # GuildEmoji, PartialEmoji + if isinstance( + default_reaction_emoji, _EmojiTag + ): # GuildEmoji, PartialEmoji default_reaction_emoji = default_reaction_emoji._to_partial() elif isinstance(default_reaction_emoji, int): default_reaction_emoji = PartialEmoji( diff --git a/discord/components.py b/discord/components.py index cd4874896e..c80eb5a57c 100644 --- a/discord/components.py +++ b/discord/components.py @@ -32,7 +32,7 @@ from .utils import MISSING, get_slots if TYPE_CHECKING: - from .emoji import GuildEmoji, AppEmoji + from .emoji import AppEmoji, GuildEmoji from .types.components import ActionRow as ActionRowPayload from .types.components import ButtonComponent as ButtonComponentPayload from .types.components import Component as ComponentPayload diff --git a/discord/ext/pages/pagination.py b/discord/ext/pages/pagination.py index 15efdba6d1..c7e77fc9de 100644 --- a/discord/ext/pages/pagination.py +++ b/discord/ext/pages/pagination.py @@ -72,7 +72,9 @@ def __init__( self, button_type: str, label: str = None, - emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = None, + emoji: ( + str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji + ) = None, style: discord.ButtonStyle = discord.ButtonStyle.green, disabled: bool = False, custom_id: str = None, @@ -89,7 +91,9 @@ def __init__( ) self.button_type = button_type self.label = label if label or emoji else button_type.capitalize() - self.emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = emoji + self.emoji: ( + str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji + ) = emoji self.style = style self.disabled = disabled self.loop_label = self.label if not loop_label else loop_label @@ -278,7 +282,9 @@ def __init__( pages: list[str] | list[Page] | list[list[discord.Embed] | discord.Embed], label: str, description: str | None = None, - emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = None, + emoji: ( + str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji + ) = None, default: bool | None = None, show_disabled: bool | None = None, show_indicator: bool | None = None, @@ -294,7 +300,9 @@ def __init__( ): self.label = label self.description: str | None = description - self.emoji: str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji = emoji + self.emoji: ( + str | discord.GuildEmoji | discord.AppEmoji | discord.PartialEmoji + ) = emoji self.pages: list[str] | list[list[discord.Embed] | discord.Embed] = pages self.default: bool | None = default self.show_disabled = show_disabled diff --git a/discord/guild.py b/discord/guild.py index 4610e98790..0bad4082e0 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -1502,7 +1502,9 @@ async def create_forum_channel( options["nsfw"] = nsfw if default_reaction_emoji is not MISSING: - if isinstance(default_reaction_emoji, _EmojiTag): # GuildEmoji, PartialEmoji + if isinstance( + default_reaction_emoji, _EmojiTag + ): # GuildEmoji, PartialEmoji default_reaction_emoji = default_reaction_emoji._to_partial() elif isinstance(default_reaction_emoji, int): default_reaction_emoji = PartialEmoji( diff --git a/discord/message.py b/discord/message.py index b9927aa9b6..88bd73a5cc 100644 --- a/discord/message.py +++ b/discord/message.py @@ -45,7 +45,7 @@ from .channel import PartialMessageable from .components import _component_factory from .embeds import Embed -from .emoji import GuildEmoji, AppEmoji +from .emoji import AppEmoji, GuildEmoji from .enums import ChannelType, MessageType, try_enum from .errors import InvalidArgument from .file import File diff --git a/discord/poll.py b/discord/poll.py index 12dfc59ea5..087d2833f6 100644 --- a/discord/poll.py +++ b/discord/poll.py @@ -43,7 +43,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import GuildEmoji, AppEmoji + from .emoji import AppEmoji, GuildEmoji from .message import Message, PartialMessage from .types.poll import Poll as PollPayload from .types.poll import PollAnswer as PollAnswerPayload @@ -66,7 +66,9 @@ class PollMedia: The answer's emoji. """ - def __init__(self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None): + def __init__( + self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None + ): self.text: str = text self.emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = emoji @@ -124,7 +126,9 @@ class PollAnswer: The relevant media for this answer. """ - def __init__(self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None): + def __init__( + self, text: str, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None + ): self.media = PollMedia(text, emoji) self.id = None self._poll = None @@ -446,7 +450,10 @@ def get_answer(self, id) -> PollAnswer | None: return utils.get(self.answers, id=id) def add_answer( - self, text: str, *, emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None + self, + text: str, + *, + emoji: GuildEmoji | AppEmoji | PartialEmoji | str | None = None, ) -> Poll: """Add an answer to this poll. diff --git a/discord/reaction.py b/discord/reaction.py index 1279204970..8a2e000c8c 100644 --- a/discord/reaction.py +++ b/discord/reaction.py @@ -35,7 +35,7 @@ if TYPE_CHECKING: from .abc import Snowflake - from .emoji import GuildEmoji, AppEmoji + from .emoji import AppEmoji, GuildEmoji from .message import Message from .partial_emoji import PartialEmoji from .types.message import Reaction as ReactionPayload diff --git a/discord/state.py b/discord/state.py index 1625fddf91..172017ab7d 100644 --- a/discord/state.py +++ b/discord/state.py @@ -1968,7 +1968,9 @@ def get_reaction_emoji(self, data) -> GuildEmoji | AppEmoji | PartialEmoji: name=data["name"], ) - def _upgrade_partial_emoji(self, emoji: PartialEmoji) -> GuildEmoji | AppEmoji | PartialEmoji | str: + def _upgrade_partial_emoji( + self, emoji: PartialEmoji + ) -> GuildEmoji | AppEmoji | PartialEmoji | str: emoji_id = emoji.id if not emoji_id: return emoji.name diff --git a/discord/ui/button.py b/discord/ui/button.py index 2388105d8c..42d4af8d08 100644 --- a/discord/ui/button.py +++ b/discord/ui/button.py @@ -40,7 +40,7 @@ ) if TYPE_CHECKING: - from ..emoji import GuildEmoji, AppEmoji + from ..emoji import AppEmoji, GuildEmoji from .view import View B = TypeVar("B", bound="Button") diff --git a/discord/ui/select.py b/discord/ui/select.py index bab868d3f1..496446e61c 100644 --- a/discord/ui/select.py +++ b/discord/ui/select.py @@ -31,7 +31,7 @@ from ..channel import _threaded_guild_channel_factory from ..components import SelectMenu, SelectOption -from ..emoji import GuildEmoji, AppEmoji +from ..emoji import AppEmoji, GuildEmoji from ..enums import ChannelType, ComponentType from ..errors import InvalidArgument from ..interactions import Interaction From b937eaa710ea91cfb63ee0d6fa3268215e0b2bac Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:47:49 +0100 Subject: [PATCH 21/24] misc --- discord/client.py | 2 -- discord/state.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/discord/client.py b/discord/client.py index bb52ce1b05..8ece21cf94 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2233,8 +2233,6 @@ async def create_emoji( Raises ------- - Forbidden - You are not allowed to create emojis. HTTPException An error occurred creating an emoji. diff --git a/discord/state.py b/discord/state.py index 172017ab7d..cf74d99285 100644 --- a/discord/state.py +++ b/discord/state.py @@ -49,7 +49,7 @@ from .automod import AutoModRule from .channel import * from .channel import _channel_factory -from .emoji import AppEmoji, Emoji, GuildEmoji +from .emoji import AppEmoji, GuildEmoji from .enums import ChannelType, InteractionType, ScheduledEventStatus, Status, try_enum from .flags import ApplicationFlags, Intents, MemberCacheFlags from .guild import Guild From 9b018ebb1d5876ff214eec66db725cbc472b816c Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:51:01 +0100 Subject: [PATCH 22/24] cl --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0be148b48..14ae48b6d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ These changes are available on the `master` branch, but have not yet been releas `tags`. ([#2520](https://github.com/Pycord-Development/pycord/pull/2520)) - Added `Member.guild_banner` and `Member.display_banner` properties. ([#2556](https://github.com/Pycord-Development/pycord/pull/2556)) +- Added support for Application Emojis. + ([#2501](https://github.com/Pycord-Development/pycord/pull/2501)) +- Added `cache_app_emojis` parameter to `Client`. + ([#2501](https://github.com/Pycord-Development/pycord/pull/2501)) ### Changed @@ -30,6 +34,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2496](https://github.com/Pycord-Development/pycord/pull/2496)) - ⚠️ **This Version Removes Support For Python 3.8** ⚠️ ([#2521](https://github.com/Pycord-Development/pycord/pull/2521)) +- `Emoji` has been renamed to `GuildEmoji`. + ([#2501](https://github.com/Pycord-Development/pycord/pull/2501)) ### Deprecated From 6f97d3ab38a5893bdf2061d056f2f3d97497ed9d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 03:26:25 +0000 Subject: [PATCH 23/24] style(pre-commit): auto fixes from pre-commit.com hooks --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c1d19a15b..0e04b92e02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,6 @@ These changes are available on the `master` branch, but have not yet been releas - Fixed the `is_owner()` `user` type hint: `User` -> `User | Member`. ([#2593](https://github.com/Pycord-Development/pycord/pull/2593)) - ### Changed - Renamed `cover` property of `ScheduledEvent` and `cover` argument of From d8f7ee4fd70411cef3154489511b95c36d9954b8 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Fri, 4 Oct 2024 04:32:33 +0100 Subject: [PATCH 24/24] add deprecation --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e04b92e02..d683b85017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,8 @@ These changes are available on the `master` branch, but have not yet been releas - Deprecated `AppInfo.summary` in favor of `AppInfo.description`. ([#2520](https://github.com/Pycord-Development/pycord/pull/2520)) +- Deprecated `Emoji` in favor of `GuildEmoji` + ([#2501](https://github.com/Pycord-Development/pycord/pull/2501)) ## [2.6.1] - 2024-09-15