Skip to content

Commit 7c10a40

Browse files
authored
Merge branch 'master' into channel
Signed-off-by: Lumouille <[email protected]>
2 parents e126d12 + 4392105 commit 7c10a40

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
@@ -59,6 +59,8 @@ These changes are available on the `master` branch, but have not yet been releas
5959
([#2747](https://github.com/Pycord-Development/pycord/pull/2747))
6060
- Added various missing channel parameters and allow `default_reaction_emoji` to be
6161
`None`. ([#2772](https://github.com/Pycord-Development/pycord/pull/2772))
62+
- Added support for type hinting slash command options with `typing.Annotated`.
63+
([#2782](https://github.com/Pycord-Development/pycord/pull/2782))
6264
- Added conversion to `Member` in `MentionableConverter`.
6365
([#2775](https://github.com/Pycord-Development/pycord/pull/2775))
6466
- 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)