From 78e00911786cce4daaeaadcc9685c3950d19621a Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:11:26 +0300 Subject: [PATCH 1/5] Add Unicode emoji support to PartialEmojiConverter PartialEmojiConverter now recognizes standard Unicode emojis using a new UNICODE_EMOJIS set loaded from emojis.json. The emoji mapping and set are moved to discord.utils for reuse, and references in partial_emoji.py are updated accordingly. --- discord/ext/commands/converter.py | 18 ++++++++++++++++-- discord/partial_emoji.py | 8 +------- discord/utils.py | 12 ++++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index e60ac89b34..62f0e86b33 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -43,6 +43,7 @@ import discord from .errors import * +from discord.utils import UNICODE_EMOJIS if TYPE_CHECKING: from discord.message import PartialMessageableChannel @@ -851,7 +852,8 @@ async def convert(self, ctx: Context, argument: str) -> discord.GuildEmoji: class PartialEmojiConverter(Converter[discord.PartialEmoji]): """Converts to a :class:`~discord.PartialEmoji`. - This is done by extracting the animated flag, name and ID from the emoji. + This is done by extracting the animated flag, name, and ID for custom emojis, + or by using the standard Unicode emojis supported by Discord. .. versionchanged:: 1.5 Raise :exc:`.PartialEmojiConversionFailure` instead of generic :exc:`.BadArgument` @@ -872,6 +874,14 @@ async def convert(self, ctx: Context, argument: str) -> discord.PartialEmoji: id=emoji_id, ) + if argument in UNICODE_EMOJIS: + return discord.PartialEmoji.with_state( + ctx.bot._connection, + animated=False, + name=argument, + id=None, + ) + raise PartialEmojiConversionFailure(argument) @@ -1094,7 +1104,11 @@ def get_converter(param: inspect.Parameter) -> Any: def is_generic_type(tp: Any, *, _GenericAlias: type = _GenericAlias) -> bool: - return isinstance(tp, type) and issubclass(tp, Generic) or isinstance(tp, _GenericAlias) # type: ignore + return ( + isinstance(tp, type) + and issubclass(tp, Generic) + or isinstance(tp, _GenericAlias) + ) # type: ignore CONVERTER_MAPPING: dict[type[Any], Any] = { diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py index cabe26249f..5b2a528c38 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -34,12 +34,6 @@ from .asset import Asset, AssetMixin from .errors import InvalidArgument -with ( - importlib.resources.files(__package__) - .joinpath("emojis.json") - .open(encoding="utf-8") as f -): - EMOJIS_MAP = json.load(f) __all__ = ("PartialEmoji",) @@ -152,7 +146,7 @@ def from_str(cls: type[PE], value: str) -> PE: """ if value.startswith(":") and value.endswith(":") and len(value) > 2: name = value[1:-1] - if unicode_emoji := EMOJIS_MAP.get(name): + if unicode_emoji := utils.EMOJIS_MAP.get(name): return cls(name=unicode_emoji, id=None, animated=False) match = cls._CUSTOM_EMOJI_RE.match(value) if match is not None: diff --git a/discord/utils.py b/discord/utils.py index b509162cf0..ec9e61e76a 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -35,6 +35,7 @@ import re import sys import types +import importlib.resources import unicodedata import warnings from base64 import b64encode @@ -97,10 +98,21 @@ "generate_snowflake", "basic_autocomplete", "filter_params", + "EMOJIS_MAP", + "UNICODE_EMOJIS", ) DISCORD_EPOCH = 1420070400000 +with ( + importlib.resources.files(__package__) + .joinpath("emojis.json") + .open(encoding="utf-8") as f +): + EMOJIS_MAP = json.load(f) + +UNICODE_EMOJIS = set(EMOJIS_MAP) + class _MissingSentinel: def __eq__(self, other) -> bool: From de84bec1ee2c3c556438db7094f89bc4a8d9369d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 08:16:54 +0000 Subject: [PATCH 2/5] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/ext/commands/converter.py | 2 +- discord/partial_emoji.py | 3 --- discord/utils.py | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index bf69cb2d77..d2129bfe74 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -42,9 +42,9 @@ import discord from discord.partial_emoji import EMOJIS_MAP +from discord.utils import UNICODE_EMOJIS from .errors import * -from discord.utils import UNICODE_EMOJIS if TYPE_CHECKING: from discord.message import PartialMessageableChannel diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py index 5b2a528c38..50e50d311c 100644 --- a/discord/partial_emoji.py +++ b/discord/partial_emoji.py @@ -25,8 +25,6 @@ from __future__ import annotations -import importlib.resources -import json import re from typing import TYPE_CHECKING, Any, TypedDict, TypeVar @@ -34,7 +32,6 @@ from .asset import Asset, AssetMixin from .errors import InvalidArgument - __all__ = ("PartialEmoji",) if TYPE_CHECKING: diff --git a/discord/utils.py b/discord/utils.py index ec9e61e76a..08b26a7419 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -30,12 +30,12 @@ import collections.abc import datetime import functools +import importlib.resources import itertools import json import re import sys import types -import importlib.resources import unicodedata import warnings from base64 import b64encode From c7c198432803ec36f62c305be1b6d80cee90e0ab Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:18:22 +0300 Subject: [PATCH 3/5] Update converter.py Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/ext/commands/converter.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index d2129bfe74..7fc9d7cb57 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -875,6 +875,14 @@ async def convert(self, ctx: Context, argument: str) -> discord.PartialEmoji: id=emoji_id, ) + if argument in UNICODE_EMOJIS: + return discord.PartialEmoji.with_state( + ctx.bot._connection, + animated=False, + name=argument, + id=None, + ) + raise PartialEmojiConversionFailure(argument) From 3d204f519c65c4086caa47d664730f6fdcc95268 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:20:02 +0300 Subject: [PATCH 4/5] Update converter.py --- discord/ext/commands/converter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index 7fc9d7cb57..ca5a109f3f 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -41,7 +41,6 @@ ) import discord -from discord.partial_emoji import EMOJIS_MAP from discord.utils import UNICODE_EMOJIS from .errors import * From bbf2ed6f433182194a1a79c68a50eb81ea216047 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:23:22 +0300 Subject: [PATCH 5/5] fix(utils): update UNICODE_EMOJIS to use values from EMOJIS_MAP --- discord/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/utils.py b/discord/utils.py index 08b26a7419..2f9f94a35a 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -111,7 +111,7 @@ ): EMOJIS_MAP = json.load(f) -UNICODE_EMOJIS = set(EMOJIS_MAP) +UNICODE_EMOJIS = set(EMOJIS_MAP.values()) class _MissingSentinel: