Skip to content

Commit b1cf42c

Browse files
authored
Merge branch 'master' into overlap
Signed-off-by: Lumouille <[email protected]>
2 parents bee78d3 + 4392105 commit b1cf42c

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
@@ -60,6 +60,8 @@ These changes are available on the `master` branch, but have not yet been releas
6060
- Added the ability to pass an `overlap` parameter to the `loop` decorator and `Loop`
6161
class, allowing concurrent iterations if enabled.
6262
([#2765](https://github.com/Pycord-Development/pycord/pull/2765))
63+
- Added support for type hinting slash command options with `typing.Annotated`.
64+
([#2782](https://github.com/Pycord-Development/pycord/pull/2782))
6365
- Added conversion to `Member` in `MentionableConverter`.
6466
([#2775](https://github.com/Pycord-Development/pycord/pull/2775))
6567
- 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)