Use a Literal as the type for choice based options

This commit is contained in:
Kovid Goyal 2020-04-24 19:45:51 +05:30
parent 5762baeed7
commit c92aca5d19
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 14 additions and 8 deletions

View File

@ -9,7 +9,7 @@ from typing import (
Set, Tuple, Union, get_type_hints
)
from .utils import to_bool
from .utils import Choice, to_bool
def to_string(x: str) -> str:
@ -56,6 +56,8 @@ class Option:
if type(self.option_type) is type:
return type_name(self.option_type)
if isinstance(self.option_type, Choice):
return 'typing.Literal[{}]'.format(','.join(f'{x!r}' for x in self.option_type.all_choices))
th = get_type_hints(self.option_type)
try:
rettype = th['return']

View File

@ -68,17 +68,21 @@ def python_string(text: str) -> str:
return ans
def choices(*choices: str) -> Callable[[str], str]:
defval = choices[0]
uc = frozenset(choices)
class Choice:
def choice(x: str) -> str:
def __init__(self, choices: Sequence[str]):
self.defval = choices[0]
self.all_choices = frozenset(choices)
def __call__(self, x: str) -> str:
x = x.lower()
if x not in uc:
x = defval
if x not in self.all_choices:
x = self.defval
return x
return choice
def choices(*choices: str) -> Choice:
return Choice(choices)
def parse_line(