diff --git a/CHANGELOG.md b/CHANGELOG.md index 46d996a6d2..bc82ef3cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2714](https://github.com/Pycord-Development/pycord/pull/2714)) - Added the ability to pass a `datetime.time` object to `format_dt` ([#2747](https://github.com/Pycord-Development/pycord/pull/2747)) +- Added support for `Literal[...]` to define command choices. + ([#2782](https://github.com/Pycord-Development/pycord/pull/2782)) ### Fixed diff --git a/discord/commands/core.py b/discord/commands/core.py index bee43341fd..386266b38f 100644 --- a/discord/commands/core.py +++ b/discord/commands/core.py @@ -73,9 +73,9 @@ from .options import Option, OptionChoice if sys.version_info >= (3, 11): - from typing import Annotated, get_args, get_origin + from typing import Annotated, Literal, get_args, get_origin else: - from typing_extensions import Annotated, get_args, get_origin + from typing_extensions import Annotated, Literal, get_args, get_origin __all__ = ( "_BaseCommand", @@ -805,6 +805,18 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]: option = p_obj.annotation if option == inspect.Parameter.empty: option = str + if get_origin(option) is Literal: + literal_values = get_args(option) + if not all(isinstance(v, (str, int, float)) for v in literal_values): + raise TypeError( + "Literal values must be str, int, or float for Discord choices." + ) + option = Option( + str, + choices=[ + OptionChoice(name=str(v), value=str(v)) for v in literal_values + ], + ) if self._is_typing_annotated(option): type_hint = get_args(option)[0]