|
73 | 73 | from .options import Option, OptionChoice
|
74 | 74 |
|
75 | 75 | 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 |
77 | 77 | else:
|
78 |
| - from typing_extensions import Annotated, get_args, get_origin |
| 78 | + from typing_extensions import Annotated, Literal, get_args, get_origin |
79 | 79 |
|
80 | 80 | __all__ = (
|
81 | 81 | "_BaseCommand",
|
@@ -779,6 +779,26 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]:
|
779 | 779 | if option == inspect.Parameter.empty:
|
780 | 780 | option = str
|
781 | 781 |
|
| 782 | + if self._is_typing_literal(option): |
| 783 | + literal_values = get_args(option) |
| 784 | + if not all(isinstance(v, (str, int, float)) for v in literal_values): |
| 785 | + raise TypeError( |
| 786 | + "Literal values for choices must be str, int, or float." |
| 787 | + ) |
| 788 | + |
| 789 | + value_type = type(literal_values[0]) |
| 790 | + if not all(isinstance(v, value_type) for v in literal_values): |
| 791 | + raise TypeError( |
| 792 | + "All Literal values for choices must be of the same type." |
| 793 | + ) |
| 794 | + |
| 795 | + option = Option( |
| 796 | + value_type, |
| 797 | + choices=[ |
| 798 | + OptionChoice(name=str(v), value=v) for v in literal_values |
| 799 | + ], |
| 800 | + ) |
| 801 | + |
782 | 802 | if self._is_typing_annotated(option):
|
783 | 803 | type_hint = get_args(option)[0]
|
784 | 804 | metadata = option.__metadata__
|
@@ -866,6 +886,9 @@ def _is_typing_union(self, annotation):
|
866 | 886 | def _is_typing_optional(self, annotation):
|
867 | 887 | return self._is_typing_union(annotation) and type(None) in annotation.__args__ # type: ignore
|
868 | 888 |
|
| 889 | + def _is_typing_literal(self, annotation): |
| 890 | + return get_origin(annotation) is Literal |
| 891 | + |
869 | 892 | def _is_typing_annotated(self, annotation):
|
870 | 893 | return get_origin(annotation) is Annotated
|
871 | 894 |
|
|
0 commit comments