Skip to content

Commit

Permalink
Merge branch 'master' into message_call
Browse files Browse the repository at this point in the history
Signed-off-by: Dorukyum <53639936+Dorukyum@users.noreply.github.com>
  • Loading branch information
Dorukyum authored Jul 1, 2024
2 parents 99e1e33 + 99b40e2 commit aa92cd1
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ These changes are available on the `master` branch, but have not yet been releas
- Added `MemberFlags`. ([#2489](https://github.com/Pycord-Development/pycord/pull/2489))
- Added `bypass_verification` parameter to `Member.edit`.
([#2489](https://github.com/Pycord-Development/pycord/pull/2489))
- Added `RoleFlags`. ([#2487](https://github.com/Pycord-Development/pycord/pull/2487))
- Added `MessageCall` information.
([#2488](https://github.com/Pycord-Development/pycord/pull/2488))

Expand Down Expand Up @@ -67,6 +68,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))
- Fixed many inaccurate type hints throughout the library.
([#2457](https://github.com/Pycord-Development/pycord/pull/2457))
- Fixed `AttributeError` due to `discord.Option` being initialised with `input_type` set
Expand Down
36 changes: 27 additions & 9 deletions discord/commands/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from __future__ import annotations

import inspect
import logging
from enum import Enum
from typing import TYPE_CHECKING, Literal, Optional, Type, Union

Expand All @@ -41,7 +42,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 @@ -86,6 +87,8 @@
DMChannel: ChannelType.private,
}

_log = logging.getLogger(__name__)


class ThreadOption:
"""Represents a class that can be passed as the ``input_type`` for an :class:`Option` class.
Expand Down Expand Up @@ -115,12 +118,13 @@ 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.
description: Optional[:class:`str`]
The description of this option.
Must be 100 characters or fewer.
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.
choices: Optional[List[Union[:class:`Any`, :class:`OptionChoice`]]]
The list of available choices for this option.
Can be a list of values or :class:`OptionChoice` objects (which represent a name:value pair).
Expand Down Expand Up @@ -195,7 +199,14 @@ def __init__(
input_type_is_class = isinstance(input_type, type)
if input_type_is_class and issubclass(input_type, (Enum, DiscordEnum)):
if description is None:
description = inspect.getdoc(input_type)
description = inspect.cleandoc(input_type.__doc__)
if description and len(description) > 100:
description = description[:97] + "..."
_log.warning(
"Option %s's description was truncated due to Enum %s's docstring exceeding 100 characters.",
self.name,
input_type,
)
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 +261,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 +343,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
55 changes: 55 additions & 0 deletions discord/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"ApplicationFlags",
"ChannelFlags",
"SKUFlags",
"RoleFlags",
"MemberFlags",
)

Expand Down Expand Up @@ -1758,3 +1759,57 @@ def bypasses_verification(self):
def started_onboarding(self):
""":class:`bool`: Returns ``True`` if the member has started onboarding."""
return 1 << 3


@fill_with_flags()
class RoleFlags(BaseFlags):
r"""Wraps up the Discord Role flags.
.. container:: operations
.. describe:: x == y
Checks if two RoleFlags are equal.
.. describe:: x != y
Checks if two RoleFlags are not equal.
.. describe:: x + y
Adds two flags together. Equivalent to ``x | y``.
.. describe:: x - y
Subtracts two flags from each other.
.. describe:: x | y
Returns the union of two flags. Equivalent to ``x + y``.
.. describe:: x & y
Returns the intersection of two flags.
.. describe:: ~x
Returns the inverse of a flag.
.. describe:: hash(x)
Return the flag's hash.
.. describe:: iter(x)
Returns an iterator of ``(name, value)`` pairs. This allows it
to be, for example, constructed as a dict or a list of pairs.
Note that aliases are not shown.
.. versionadded:: 2.6
Attributes
-----------
value: :class:`int`
The raw value. This value is a bit array field of a 53-bit integer
representing the currently available flags. You should query
flags via the properties rather than using this raw value.
"""

__slots__ = ()

@flag_value
def in_prompt(self):
""":class:`bool`: Returns ``True`` if the role is selectable in one of the guild's :class:`~discord.OnboardingPrompt`."""
return 1 << 0
8 changes: 8 additions & 0 deletions discord/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from .asset import Asset
from .colour import Colour
from .errors import InvalidArgument
from .flags import RoleFlags
from .mixins import Hashable
from .permissions import Permissions
from .utils import MISSING, _bytes_to_base64_data, _get_as_snowflake, snowflake_time
Expand Down Expand Up @@ -177,6 +178,11 @@ class Role(Hashable):
Only available to guilds that contain ``ROLE_ICONS`` in :attr:`Guild.features`.
.. versionadded:: 2.0
flags: :class:`RoleFlags`
Extra attributes of the role.
.. versionadded:: 2.6
"""

__slots__ = (
Expand All @@ -193,6 +199,7 @@ class Role(Hashable):
"unicode_emoji",
"_icon",
"_state",
"flags",
)

def __init__(self, *, guild: Guild, state: ConnectionState, data: RolePayload):
Expand Down Expand Up @@ -253,6 +260,7 @@ def _update(self, data: RolePayload):
self.mentionable: bool = data.get("mentionable", False)
self._icon: str | None = data.get("icon")
self.unicode_emoji: str | None = data.get("unicode_emoji")
self.flags: RoleFlags = RoleFlags._from_value(data.get("flags", 0))
self.tags: RoleTags | None

try:
Expand Down
1 change: 1 addition & 0 deletions discord/types/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Role(TypedDict):
permissions: str
managed: bool
mentionable: bool
flags: int


class RoleTags(TypedDict, total=False):
Expand Down
5 changes: 5 additions & 0 deletions docs/api/data_classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ Flags
.. autoclass:: MemberFlags()
:members:

.. attributetable:: RoleFlags

.. autoclass:: RoleFlags()
:members:

Colour
------

Expand Down

0 comments on commit aa92cd1

Please sign in to comment.