Skip to content

Commit 4392105

Browse files
LumabotsJustaSqu1dDorukyumPaillat-devpre-commit-ci[bot]
authored
feat(commands): add support for typing.Literal[...] as command choices (#2782)
* fix: add support for Literal type in typing annotations for Discord choices * Update CHANGELOG.md * Update CHANGELOG.md Signed-off-by: Lumouille <[email protected]> * Update CHANGELOG.md Co-authored-by: JustaSqu1d <[email protected]> Signed-off-by: Lumouille <[email protected]> * refactor: move condition to method * docs: update changelog * fix: ensure all literal values are of the same type in SlashCommand options * Update discord/commands/core.py Co-authored-by: Paillat <[email protected]> Signed-off-by: Lumouille <[email protected]> * Update discord/commands/core.py Co-authored-by: Paillat <[email protected]> Signed-off-by: Lumouille <[email protected]> * style(pre-commit): auto fixes from pre-commit.com hooks --------- Signed-off-by: Lumouille <[email protected]> Co-authored-by: JustaSqu1d <[email protected]> Co-authored-by: Dorukyum <[email protected]> Co-authored-by: Paillat <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent dd7d5a6 commit 4392105

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ These changes are available on the `master` branch, but have not yet been releas
5757
([#2714](https://github.com/Pycord-Development/pycord/pull/2714))
5858
- Added the ability to pass a `datetime.time` object to `format_dt`.
5959
([#2747](https://github.com/Pycord-Development/pycord/pull/2747))
60+
- Added support for type hinting slash command options with `typing.Annotated`.
61+
([#2782](https://github.com/Pycord-Development/pycord/pull/2782))
6062
- Added conversion to `Member` in `MentionableConverter`.
6163
([#2775](https://github.com/Pycord-Development/pycord/pull/2775))
6264
- Added `discord.Interaction.created_at`.

discord/commands/core.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@
7373
from .options import Option, OptionChoice
7474

7575
if sys.version_info >= (3, 11):
76-
from typing import Annotated, get_args, get_origin
76+
from typing import Annotated, Literal, get_args, get_origin
7777
else:
78-
from typing_extensions import Annotated, get_args, get_origin
78+
from typing_extensions import Annotated, Literal, get_args, get_origin
7979

8080
__all__ = (
8181
"_BaseCommand",
@@ -806,6 +806,26 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]:
806806
if option == inspect.Parameter.empty:
807807
option = str
808808

809+
if self._is_typing_literal(option):
810+
literal_values = get_args(option)
811+
if not all(isinstance(v, (str, int, float)) for v in literal_values):
812+
raise TypeError(
813+
"Literal values for choices must be str, int, or float."
814+
)
815+
816+
value_type = type(literal_values[0])
817+
if not all(isinstance(v, value_type) for v in literal_values):
818+
raise TypeError(
819+
"All Literal values for choices must be of the same type."
820+
)
821+
822+
option = Option(
823+
value_type,
824+
choices=[
825+
OptionChoice(name=str(v), value=v) for v in literal_values
826+
],
827+
)
828+
809829
if self._is_typing_annotated(option):
810830
type_hint = get_args(option)[0]
811831
metadata = option.__metadata__
@@ -908,6 +928,9 @@ def _is_typing_union(self, annotation):
908928
def _is_typing_optional(self, annotation):
909929
return self._is_typing_union(annotation) and type(None) in annotation.__args__ # type: ignore
910930

931+
def _is_typing_literal(self, annotation):
932+
return get_origin(annotation) is Literal
933+
911934
def _is_typing_annotated(self, annotation):
912935
return get_origin(annotation) is Annotated
913936

0 commit comments

Comments
 (0)