From 6ef2043b1076f2a5694b44fef785b06e83603aa3 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Thu, 31 Mar 2022 23:21:42 -0400 Subject: [PATCH] Validate Option names similar to slash command names --- discord/app_commands/models.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/discord/app_commands/models.py b/discord/app_commands/models.py index f63624d86..6e635e9ae 100644 --- a/discord/app_commands/models.py +++ b/discord/app_commands/models.py @@ -181,9 +181,20 @@ class Choice(Generic[ChoiceT]): __slots__ = ('name', 'value') def __init__(self, *, name: str, value: ChoiceT): - self.name: str = name + # Circular import avoidance + from .commands import validate_name + + self.name: str = validate_name(name) self.value: ChoiceT = value + @classmethod + def from_dict(cls, data: ApplicationCommandOptionChoice) -> Choice[Union[int, float, str]]: + # This is to avoid the validation check on Discord provided payloads. + self = cls.__new__(cls) + self.name = data['name'] + self.value = data['value'] + return self # type: ignore # Trick type checker to widen ChoiceT to Union + def __eq__(self, o: object) -> bool: return isinstance(o, Choice) and self.name == o.name and self.value == o.value @@ -542,9 +553,7 @@ class Argument: self.name: str = data['name'] self.description: str = data['description'] self.required: bool = data.get('required', False) - self.choices: List[Choice[Union[int, float, str]]] = [ - Choice(name=d['name'], value=d['value']) for d in data.get('choices', []) - ] + self.choices: List[Choice[Union[int, float, str]]] = [Choice.from_dict(d) for d in data.get('choices', [])] def to_dict(self) -> ApplicationCommandOption: return { @@ -606,9 +615,7 @@ class AppCommandGroup: self.name: str = data['name'] self.description: str = data['description'] self.required: bool = data.get('required', False) - self.choices: List[Choice[Union[int, float, str]]] = [ - Choice(name=d['name'], value=d['value']) for d in data.get('choices', []) - ] + self.choices: List[Choice[Union[int, float, str]]] = [Choice.from_dict(d) for d in data.get('choices', [])] self.arguments: List[Argument] = [ Argument(parent=self, state=self._state, data=d) for d in data.get('options', [])