Skip to content

Commit 99b40e2

Browse files
NeloBlivionIcebluewolfpre-commit-ci[bot]Lulalaby
authored
fix: enum option issues (#2463)
* patch enums * cl * document enum choice/autocomplete behaviour * Update discord/commands/options.py Co-authored-by: Icebluewolf <[email protected]> Signed-off-by: UK <[email protected]> * clarify docstring and warn * style(pre-commit): auto fixes from pre-commit.com hooks * import * style(pre-commit): auto fixes from pre-commit.com hooks --------- Signed-off-by: UK <[email protected]> Co-authored-by: Icebluewolf <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil <[email protected]>
1 parent af87860 commit 99b40e2

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ These changes are available on the `master` branch, but have not yet been releas
6666
([#2448](https://github.com/Pycord-Development/pycord/pull/2448))
6767
- Fixed missing `application_id` in `Entitlement.delete`.
6868
([#2458](https://github.com/Pycord-Development/pycord/pull/2458))
69+
- Fixed issues with enums as `Option` types with long descriptions or too many values
70+
([#2463](https://github.com/Pycord-Development/pycord/pull/2463))
6971
- Fixed many inaccurate type hints throughout the library.
7072
([#2457](https://github.com/Pycord-Development/pycord/pull/2457))
7173
- Fixed `AttributeError` due to `discord.Option` being initialised with `input_type` set

discord/commands/options.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from __future__ import annotations
2626

2727
import inspect
28+
import logging
2829
from enum import Enum
2930
from typing import TYPE_CHECKING, Literal, Optional, Type, Union
3031

@@ -41,7 +42,7 @@
4142
from ..enums import ChannelType
4243
from ..enums import Enum as DiscordEnum
4344
from ..enums import SlashCommandOptionType
44-
from ..utils import MISSING
45+
from ..utils import MISSING, basic_autocomplete
4546

4647
if TYPE_CHECKING:
4748
from ..ext.commands import Converter
@@ -86,6 +87,8 @@
8687
DMChannel: ChannelType.private,
8788
}
8889

90+
_log = logging.getLogger(__name__)
91+
8992

9093
class ThreadOption:
9194
"""Represents a class that can be passed as the ``input_type`` for an :class:`Option` class.
@@ -115,12 +118,13 @@ class Option:
115118
input_type: Union[Type[:class:`str`], Type[:class:`bool`], Type[:class:`int`], Type[:class:`float`], Type[:class:`.abc.GuildChannel`], Type[:class:`Thread`], Type[:class:`Member`], Type[:class:`User`], Type[:class:`Attachment`], Type[:class:`Role`], Type[:class:`.abc.Mentionable`], :class:`SlashCommandOptionType`, Type[:class:`.ext.commands.Converter`], Type[:class:`enums.Enum`], Type[:class:`Enum`]]
116119
The type of input that is expected for this option. This can be a :class:`SlashCommandOptionType`,
117120
an associated class, a channel type, a :class:`Converter`, a converter class or an :class:`enum.Enum`.
121+
If a :class:`enum.Enum` is used and it has up to 25 values, :attr:`choices` will be automatically filled. If the :class:`enum.Enum` has more than 25 values, :attr:`autocomplete` will be implemented with :func:`discord.utils.basic_autocomplete` instead.
118122
name: :class:`str`
119123
The name of this option visible in the UI.
120124
Inherits from the variable name if not provided as a parameter.
121125
description: Optional[:class:`str`]
122126
The description of this option.
123-
Must be 100 characters or fewer.
127+
Must be 100 characters or fewer. If :attr:`input_type` is a :class:`enum.Enum` and :attr:`description` is not specified, :attr:`input_type`'s docstring will be used.
124128
choices: Optional[List[Union[:class:`Any`, :class:`OptionChoice`]]]
125129
The list of available choices for this option.
126130
Can be a list of values or :class:`OptionChoice` objects (which represent a name:value pair).
@@ -195,7 +199,14 @@ def __init__(
195199
input_type_is_class = isinstance(input_type, type)
196200
if input_type_is_class and issubclass(input_type, (Enum, DiscordEnum)):
197201
if description is None:
198-
description = inspect.getdoc(input_type)
202+
description = inspect.cleandoc(input_type.__doc__)
203+
if description and len(description) > 100:
204+
description = description[:97] + "..."
205+
_log.warning(
206+
"Option %s's description was truncated due to Enum %s's docstring exceeding 100 characters.",
207+
self.name,
208+
input_type,
209+
)
199210
enum_choices = [OptionChoice(e.name, e.value) for e in input_type]
200211
value_class = enum_choices[0].value.__class__
201212
if all(isinstance(elem.value, value_class) for elem in enum_choices):
@@ -250,10 +261,19 @@ def __init__(
250261
kwargs.pop("required", True) if "default" not in kwargs else False
251262
)
252263
self.default = kwargs.pop("default", None)
253-
self.choices: list[OptionChoice] = enum_choices or [
254-
o if isinstance(o, OptionChoice) else OptionChoice(o)
255-
for o in kwargs.pop("choices", [])
256-
]
264+
265+
self.autocomplete = kwargs.pop("autocomplete", None)
266+
if len(enum_choices) > 25:
267+
self.choices: list[OptionChoice] = []
268+
for e in enum_choices:
269+
e.value = str(e.value)
270+
self.autocomplete = basic_autocomplete(enum_choices)
271+
self.input_type = SlashCommandOptionType.string
272+
else:
273+
self.choices: list[OptionChoice] = enum_choices or [
274+
o if isinstance(o, OptionChoice) else OptionChoice(o)
275+
for o in kwargs.pop("choices", [])
276+
]
257277

258278
if self.input_type == SlashCommandOptionType.integer:
259279
minmax_types = (int, type(None))
@@ -323,8 +343,6 @@ def __init__(
323343
if self.max_length < 1 or self.max_length > 6000:
324344
raise AttributeError("max_length must between 1 and 6000 (inclusive)")
325345

326-
self.autocomplete = kwargs.pop("autocomplete", None)
327-
328346
self.name_localizations = kwargs.pop("name_localizations", MISSING)
329347
self.description_localizations = kwargs.pop(
330348
"description_localizations", MISSING

0 commit comments

Comments
 (0)