Ensure all choices are the same type as the parameter type

Fixes #7625
This commit is contained in:
Rapptz 2022-03-11 07:26:25 -05:00
parent 377561844d
commit bbf7a7981b
2 changed files with 16 additions and 3 deletions

View File

@ -223,9 +223,9 @@ def _populate_choices(params: Dict[str, CommandParameter], all_choices: Dict[str
if param.type not in (AppCommandOptionType.string, AppCommandOptionType.number, AppCommandOptionType.integer):
raise TypeError('choices are only supported for integer, string, or number option types')
# There's a type safety hole if someone does Choice[float] as an annotation
# but the values are actually Choice[int]. Since the input-output is the same this feels
# safe enough to ignore.
if not all(param.type == choice._option_type for choice in choices):
raise TypeError('choices must all have the same inner option type as the parameter choice type')
param.choices = choices
if all_choices:

View File

@ -188,6 +188,19 @@ class Choice(Generic[ChoiceT]):
def __repr__(self) -> str:
return f'{self.__class__.__name__}(name={self.name!r}, value={self.value!r})'
@property
def _option_type(self) -> AppCommandOptionType:
if isinstance(self.value, int):
return AppCommandOptionType.integer
elif isinstance(self.value, float):
return AppCommandOptionType.number
elif isinstance(self.value, str):
return AppCommandOptionType.string
else:
raise TypeError(
f'invalid Choice value type given, expected int, str, or float but received {self.value.__class__!r}'
)
def to_dict(self) -> ApplicationCommandOptionChoice:
return {
'name': self.name,