Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: enum option issues #2463

Merged
merged 12 commits into from
Jul 1, 2024
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2448](https://github.com/Pycord-Development/pycord/pull/2448))
- Fixed missing `application_id` in `Entitlement.delete`.
([#2458](https://github.com/Pycord-Development/pycord/pull/2458))
- Fixed issues with enums as `Option` types with long descriptions or too many values
([#2463](https://github.com/Pycord-Development/pycord/pull/2463))

### Changed

Expand Down
24 changes: 17 additions & 7 deletions discord/commands/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from ..enums import ChannelType
from ..enums import Enum as DiscordEnum
from ..enums import SlashCommandOptionType
from ..utils import MISSING
from ..utils import MISSING, basic_autocomplete

if TYPE_CHECKING:
from ..ext.commands import Converter
Expand Down Expand Up @@ -115,6 +115,7 @@ class Option:
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`]]
The type of input that is expected for this option. This can be a :class:`SlashCommandOptionType`,
an associated class, a channel type, a :class:`Converter`, a converter class or an :class:`enum.Enum`.
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.
name: :class:`str`
The name of this option visible in the UI.
Inherits from the variable name if not provided as a parameter.
Expand Down Expand Up @@ -196,6 +197,8 @@ def __init__(
if input_type_is_class and issubclass(input_type, (Enum, DiscordEnum)):
if description is None:
description = inspect.getdoc(input_type)
NeloBlivion marked this conversation as resolved.
Show resolved Hide resolved
if description and len(description) > 100:
NeloBlivion marked this conversation as resolved.
Show resolved Hide resolved
description = description[:97] + "..."
enum_choices = [OptionChoice(e.name, e.value) for e in input_type]
value_class = enum_choices[0].value.__class__
if all(isinstance(elem.value, value_class) for elem in enum_choices):
Expand Down Expand Up @@ -250,10 +253,19 @@ def __init__(
kwargs.pop("required", True) if "default" not in kwargs else False
)
self.default = kwargs.pop("default", None)
self.choices: list[OptionChoice] = enum_choices or [
o if isinstance(o, OptionChoice) else OptionChoice(o)
for o in kwargs.pop("choices", [])
]

self.autocomplete = kwargs.pop("autocomplete", None)
if len(enum_choices) > 25:
self.choices: list[OptionChoice] = []
for e in enum_choices:
e.value = str(e.value)
self.autocomplete = basic_autocomplete(enum_choices)
self.input_type = SlashCommandOptionType.string
else:
self.choices: list[OptionChoice] = enum_choices or [
o if isinstance(o, OptionChoice) else OptionChoice(o)
for o in kwargs.pop("choices", [])
]

if self.input_type == SlashCommandOptionType.integer:
minmax_types = (int, type(None))
Expand Down Expand Up @@ -323,8 +335,6 @@ def __init__(
if self.max_length < 1 or self.max_length > 6000:
raise AttributeError("max_length must between 1 and 6000 (inclusive)")

self.autocomplete = kwargs.pop("autocomplete", None)

self.name_localizations = kwargs.pop("name_localizations", MISSING)
self.description_localizations = kwargs.pop(
"description_localizations", MISSING
Expand Down