Browse Source

Merge branch 'master' into feat/share-client-theme

pull/10428/head
Soheab 4 weeks ago
committed by GitHub
parent
commit
bc396c54ec
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/lint.yml
  2. 27
      discord/app_commands/commands.py
  3. 4
      discord/app_commands/transformers.py
  4. 8
      discord/app_commands/tree.py
  5. 4
      discord/client.py
  6. 9
      discord/ext/commands/bot.py
  7. 6
      discord/ext/commands/cog.py
  8. 14
      discord/ext/commands/core.py
  9. 10
      discord/ext/tasks/__init__.py
  10. 5
      discord/guild.py
  11. 7
      discord/member.py
  12. 4
      discord/ui/action_row.py
  13. 4
      discord/ui/button.py
  14. 15
      discord/ui/select.py
  15. 9
      discord/utils.py
  16. 4
      docs/_static/style.css
  17. 4
      docs/api.rst
  18. 6
      docs/ext/commands/commands.rst
  19. 2
      docs/ext/commands/extensions.rst
  20. 2
      docs/intents.rst
  21. 8
      docs/interactions/api.rst
  22. 5
      docs/version_guarantees.rst
  23. 1
      pyproject.toml
  24. 14
      tests/test_permissions_all.py

2
.github/workflows/lint.yml

@ -45,4 +45,4 @@ jobs:
- name: Run ruff
if: ${{ always() && steps.install-deps.outcome == 'success' }}
run: |
ruff format --check discord examples
ruff format --check

27
discord/app_commands/commands.py

@ -58,7 +58,16 @@ from ..message import Message
from ..user import User
from ..member import Member
from ..permissions import Permissions
from ..utils import resolve_annotation, MISSING, is_inside_class, maybe_coroutine, async_all, _shorten, _to_kebab_case
from ..utils import (
resolve_annotation,
MISSING,
is_inside_class,
maybe_coroutine,
async_all,
_iscoroutinefunction,
_shorten,
_to_kebab_case,
)
if TYPE_CHECKING:
from typing_extensions import ParamSpec, Concatenate, Unpack
@ -346,7 +355,7 @@ def _populate_autocomplete(params: Dict[str, CommandParameter], autocomplete: Di
if callback is MISSING:
continue
if not inspect.iscoroutinefunction(callback):
if not _iscoroutinefunction(callback):
raise TypeError('autocomplete callback must be a coroutine function')
if param.type not in (AppCommandOptionType.string, AppCommandOptionType.number, AppCommandOptionType.integer):
@ -1037,7 +1046,7 @@ class Command(Generic[GroupT, P, T]):
The coroutine passed is not actually a coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The error handler must be a coroutine.')
self.on_error = coro
@ -1098,7 +1107,7 @@ class Command(Generic[GroupT, P, T]):
"""
def decorator(coro: AutocompleteCallback[GroupT, ChoiceT]) -> AutocompleteCallback[GroupT, ChoiceT]:
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The autocomplete callback must be a coroutine function.')
try:
@ -1347,7 +1356,7 @@ class ContextMenu:
The coroutine passed is not actually a coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The error handler must be a coroutine.')
self.on_error = coro
@ -1840,7 +1849,7 @@ class Group:
The coroutine passed is not actually a coroutine, or is an invalid coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The error handler must be a coroutine.')
params = inspect.signature(coro).parameters
@ -1990,7 +1999,7 @@ class Group:
"""
def decorator(func: CommandCallback[GroupT, P, T]) -> Command[GroupT, P, T]:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('command function must be a coroutine function')
if description is MISSING:
@ -2051,7 +2060,7 @@ def command(
"""
def decorator(func: CommandCallback[GroupT, P, T]) -> Command[GroupT, P, T]:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('command function must be a coroutine function')
if description is MISSING:
@ -2123,7 +2132,7 @@ def context_menu(
"""
def decorator(func: ContextMenuCallback) -> ContextMenu:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('context menu function must be a coroutine function')
actual_name = func.__name__.title() if name is MISSING else name

4
discord/app_commands/transformers.py

@ -53,7 +53,7 @@ from ..channel import StageChannel, VoiceChannel, TextChannel, CategoryChannel,
from ..abc import GuildChannel
from ..threads import Thread
from ..enums import Enum as InternalEnum, AppCommandOptionType, ChannelType, Locale
from ..utils import MISSING, maybe_coroutine, _human_join, TIMESTAMP_PATTERN
from ..utils import MISSING, maybe_coroutine, _human_join, _iscoroutinefunction, TIMESTAMP_PATTERN
from ..user import User
from ..role import Role
from ..member import Member
@ -814,7 +814,7 @@ def get_supported_annotation(
params = inspect.signature(transform_classmethod.__func__).parameters
if len(params) != 3:
raise TypeError('Inline transformer with transform classmethod requires 3 parameters')
if not inspect.iscoroutinefunction(transform_classmethod.__func__):
if not _iscoroutinefunction(transform_classmethod.__func__):
raise TypeError('Inline transformer with transform classmethod must be a coroutine')
return (InlineTransformer(annotation), MISSING, False)

8
discord/app_commands/tree.py

@ -62,7 +62,7 @@ from .installs import AppCommandContext, AppInstallationType
from .translator import Translator, locale_str
from ..errors import ClientException, HTTPException
from ..enums import AppCommandType, InteractionType
from ..utils import MISSING, _get_as_snowflake, _is_submodule, _shorten
from ..utils import MISSING, _get_as_snowflake, _iscoroutinefunction, _is_submodule, _shorten
from .._types import ClientT
@ -839,7 +839,7 @@ class CommandTree(Generic[ClientT]):
not match the signature.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The error handler must be a coroutine.')
params = inspect.signature(coro).parameters
@ -908,7 +908,7 @@ class CommandTree(Generic[ClientT]):
"""
def decorator(func: CommandCallback[Group, P, T]) -> Command[Group, P, T]:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('command function must be a coroutine function')
if description is MISSING:
@ -1005,7 +1005,7 @@ class CommandTree(Generic[ClientT]):
"""
def decorator(func: ContextMenuCallback) -> ContextMenu:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('context menu function must be a coroutine function')
actual_name = func.__name__.title() if name is MISSING else name

4
discord/client.py

@ -68,7 +68,7 @@ from .voice_client import VoiceClient
from .http import HTTPClient
from .state import ConnectionState
from . import utils
from .utils import MISSING, time_snowflake, deprecated
from .utils import MISSING, time_snowflake, deprecated, _iscoroutinefunction
from .object import Object
from .backoff import ExponentialBackoff
from .webhook import Webhook
@ -2098,7 +2098,7 @@ class Client:
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('event registered must be a coroutine function')
setattr(self, coro.__name__, coro)

9
discord/ext/commands/bot.py

@ -25,7 +25,6 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
import asyncio
import collections
import collections.abc
import inspect
@ -53,7 +52,7 @@ from typing import (
import discord
from discord import app_commands
from discord.app_commands.tree import _retrieve_guild_ids
from discord.utils import MISSING, _is_submodule
from discord.utils import MISSING, _iscoroutinefunction, _is_submodule
from .core import GroupMixin
from .view import StringView
@ -581,7 +580,7 @@ class BotBase(GroupMixin[None]):
TypeError
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The pre-invoke hook must be a coroutine.')
self._before_invoke = coro
@ -618,7 +617,7 @@ class BotBase(GroupMixin[None]):
TypeError
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError('The post-invoke hook must be a coroutine.')
self._after_invoke = coro
@ -654,7 +653,7 @@ class BotBase(GroupMixin[None]):
"""
name = func.__name__ if name is MISSING else name
if not asyncio.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('Listeners must be coroutines')
if name in self.extra_events:

6
discord/ext/commands/cog.py

@ -28,7 +28,7 @@ import inspect
import discord
import logging
from discord import app_commands
from discord.utils import maybe_coroutine, _to_kebab_case
from discord.utils import maybe_coroutine, _iscoroutinefunction, _to_kebab_case
from typing import (
Any,
@ -233,7 +233,7 @@ class CogMeta(type):
if elem.startswith(('cog_', 'bot_')):
raise TypeError(no_bot_cog.format(base, elem))
cog_app_commands[elem] = value
elif inspect.iscoroutinefunction(value):
elif _iscoroutinefunction(value):
try:
getattr(value, '__cog_listener__')
except AttributeError:
@ -522,7 +522,7 @@ class Cog(metaclass=CogMeta):
actual = func
if isinstance(actual, staticmethod):
actual = actual.__func__
if not inspect.iscoroutinefunction(actual):
if not _iscoroutinefunction(actual):
raise TypeError('Listener function must be a coroutine function.')
actual.__cog_listener__ = True
to_assign = name or actual.__name__

14
discord/ext/commands/core.py

@ -427,7 +427,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
/,
**kwargs: Unpack[_CommandKwargs],
) -> None:
if not asyncio.iscoroutinefunction(func):
if not discord.utils._iscoroutinefunction(func):
raise TypeError('Callback must be a coroutine.')
name = kwargs.get('name') or func.__name__
@ -1102,7 +1102,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not discord.utils._iscoroutinefunction(coro):
raise TypeError('The error handler must be a coroutine.')
self.on_error: Error[CogT, Any] = coro
@ -1140,7 +1140,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
TypeError
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not discord.utils._iscoroutinefunction(coro):
raise TypeError('The pre-invoke hook must be a coroutine.')
self._before_invoke = coro
@ -1171,7 +1171,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
TypeError
The coroutine passed is not actually a coroutine.
"""
if not asyncio.iscoroutinefunction(coro):
if not discord.utils._iscoroutinefunction(coro):
raise TypeError('The post-invoke hook must be a coroutine.')
self._after_invoke = coro
@ -1945,7 +1945,7 @@ def check(predicate: UserCheck[ContextT], /) -> Check[ContextT]:
return func
if inspect.iscoroutinefunction(predicate):
if discord.utils._iscoroutinefunction(predicate):
decorator.predicate = predicate
else:
@ -2369,7 +2369,7 @@ def guild_only() -> Check[Any]:
return func
if inspect.iscoroutinefunction(predicate):
if discord.utils._iscoroutinefunction(predicate):
decorator.predicate = predicate
else:
@ -2444,7 +2444,7 @@ def is_nsfw() -> Check[Any]:
return func
if inspect.iscoroutinefunction(predicate):
if discord.utils._iscoroutinefunction(predicate):
decorator.predicate = predicate
else:

10
discord/ext/tasks/__init__.py

@ -46,7 +46,7 @@ import inspect
from collections.abc import Sequence
from discord.backoff import ExponentialBackoff
from discord.utils import MISSING
from discord.utils import MISSING, _iscoroutinefunction
_log = logging.getLogger(__name__)
@ -182,7 +182,7 @@ class Loop(Generic[LF]):
self._last_iteration: datetime.datetime = MISSING
self._next_iteration = None
if not inspect.iscoroutinefunction(self.coro):
if not _iscoroutinefunction(self.coro):
raise TypeError(f'Expected coroutine function, not {type(self.coro).__name__!r}.')
async def _call_loop_function(self, name: str, *args: Any, **kwargs: Any) -> None:
@ -574,7 +574,7 @@ class Loop(Generic[LF]):
The function was not a coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError(f'Expected coroutine function, received {coro.__class__.__name__}.')
self._before_loop = coro
@ -602,7 +602,7 @@ class Loop(Generic[LF]):
The function was not a coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError(f'Expected coroutine function, received {coro.__class__.__name__}.')
self._after_loop = coro
@ -632,7 +632,7 @@ class Loop(Generic[LF]):
TypeError
The function was not a coroutine.
"""
if not inspect.iscoroutinefunction(coro):
if not _iscoroutinefunction(coro):
raise TypeError(f'Expected coroutine function, received {coro.__class__.__name__}.')
self._error = coro # type: ignore

5
discord/guild.py

@ -2027,7 +2027,7 @@ class Guild(Hashable):
widget_channel: Optional[Snowflake] = MISSING,
mfa_level: MFALevel = MISSING,
raid_alerts_disabled: bool = MISSING,
safety_alerts_channel: TextChannel = MISSING,
safety_alerts_channel: Optional[TextChannel] = MISSING,
invites_disabled_until: datetime.datetime = MISSING,
dms_disabled_until: datetime.datetime = MISSING,
) -> Guild:
@ -2285,8 +2285,7 @@ class Guild(Hashable):
raise TypeError(
f'safety_alerts_channel must be of type TextChannel not {safety_alerts_channel.__class__.__name__}'
)
fields['safety_alerts_channel_id'] = safety_alerts_channel.id
fields['safety_alerts_channel_id'] = safety_alerts_channel.id
if owner is not MISSING:
if self.owner_id != self._state.self_id:

7
discord/member.py

@ -25,7 +25,6 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
import datetime
import inspect
import itertools
from operator import attrgetter
from typing import Any, Awaitable, Callable, Collection, Dict, List, Optional, TYPE_CHECKING, Tuple, TypeVar, Union
@ -190,7 +189,7 @@ def flatten_user(cls: T) -> T:
# probably a member function by now
def generate_function(x):
# We want sphinx to properly show coroutine functions as coroutines
if inspect.iscoroutinefunction(value):
if utils._iscoroutinefunction(value):
async def general(self, *args, **kwargs): # type: ignore
return await getattr(self._user, x)(*args, **kwargs)
@ -977,7 +976,7 @@ class Member(discord.abc.Messageable, _UserTag):
await http.edit_my_voice_state(guild_id, voice_state_payload)
else:
if not suppress:
voice_state_payload['request_to_speak_timestamp'] = datetime.datetime.utcnow().isoformat()
voice_state_payload['request_to_speak_timestamp'] = utils.utcnow().isoformat()
await http.edit_voice_state(guild_id, self.id, voice_state_payload)
if voice_channel is not MISSING:
@ -1038,7 +1037,7 @@ class Member(discord.abc.Messageable, _UserTag):
payload = {
'channel_id': self.voice.channel.id,
'request_to_speak_timestamp': datetime.datetime.utcnow().isoformat(),
'request_to_speak_timestamp': utils.utcnow().isoformat(),
}
if self._state.self_id != self.id:

4
discord/ui/action_row.py

@ -274,7 +274,7 @@ class ActionRow(Item[V]):
item._update_view(self.view)
item._parent = self
self._weight += 1
self._weight += item.width
self._children.append(item)
return self
@ -298,7 +298,7 @@ class ActionRow(Item[V]):
else:
if self._view:
self._view._add_count(-1)
self._weight -= 1
self._weight -= item.width
return self

4
discord/ui/button.py

@ -26,7 +26,6 @@ from __future__ import annotations
import copy
from typing import Callable, Literal, Optional, TYPE_CHECKING, Tuple, TypeVar, Union
import inspect
import os
@ -34,6 +33,7 @@ from .item import Item, ContainedItemCallbackType as ItemCallbackType, _ItemCall
from ..enums import ButtonStyle, ComponentType
from ..partial_emoji import PartialEmoji, _EmojiTag
from ..components import Button as ButtonComponent
from ..utils import _iscoroutinefunction
__all__ = (
'Button',
@ -370,7 +370,7 @@ def button(
"""
def decorator(func: ItemCallbackType[S, Button[V]]) -> ItemCallbackType[S, Button[V]]:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('button function must be a coroutine function')
func.__discord_ui_model_type__ = Button

15
discord/ui/select.py

@ -40,14 +40,13 @@ from typing import (
)
from contextvars import ContextVar
import copy
import inspect
import os
from .item import Item, ContainedItemCallbackType as ItemCallbackType, _ItemCallback
from ..enums import ChannelType, ComponentType, SelectDefaultValueType
from ..partial_emoji import PartialEmoji
from ..emoji import Emoji
from ..utils import MISSING, _human_join
from ..utils import MISSING, _human_join, _iscoroutinefunction
from ..components import (
SelectOption,
SelectMenu,
@ -241,7 +240,7 @@ class BaseSelect(Item[V]):
min_values: Optional[int] = None,
max_values: Optional[int] = None,
disabled: bool = False,
required: bool = False,
required: bool = True,
options: List[SelectOption] = MISSING,
channel_types: List[ChannelType] = MISSING,
default_values: Sequence[SelectDefaultValue] = MISSING,
@ -640,7 +639,7 @@ class UserSelect(BaseSelect[V]):
min_values: int = 1,
max_values: int = 1,
disabled: bool = False,
required: bool = False,
required: bool = True,
row: Optional[int] = None,
default_values: Sequence[ValidDefaultValues] = MISSING,
id: Optional[int] = None,
@ -748,7 +747,7 @@ class RoleSelect(BaseSelect[V]):
min_values: int = 1,
max_values: int = 1,
disabled: bool = False,
required: bool = False,
required: bool = True,
row: Optional[int] = None,
default_values: Sequence[ValidDefaultValues] = MISSING,
id: Optional[int] = None,
@ -852,7 +851,7 @@ class MentionableSelect(BaseSelect[V]):
min_values: int = 1,
max_values: int = 1,
disabled: bool = False,
required: bool = False,
required: bool = True,
row: Optional[int] = None,
default_values: Sequence[ValidDefaultValues] = MISSING,
id: Optional[int] = None,
@ -966,7 +965,7 @@ class ChannelSelect(BaseSelect[V]):
min_values: int = 1,
max_values: int = 1,
disabled: bool = False,
required: bool = False,
required: bool = True,
row: Optional[int] = None,
default_values: Sequence[ValidDefaultValues] = MISSING,
id: Optional[int] = None,
@ -1209,7 +1208,7 @@ def select(
"""
def decorator(func: ItemCallbackType[S, BaseSelectT]) -> ItemCallbackType[S, BaseSelectT]:
if not inspect.iscoroutinefunction(func):
if not _iscoroutinefunction(func):
raise TypeError('select function must be a coroutine function')
callback_cls = getattr(cls, '__origin__', cls)
if not issubclass(callback_cls, BaseSelect):

9
discord/utils.py

@ -26,6 +26,7 @@ from __future__ import annotations
import array
import asyncio
import inspect
from textwrap import TextWrapper
from typing import (
Any,
@ -1542,3 +1543,11 @@ class _RawReprMixin:
def __repr__(self) -> str:
value = ' '.join(f'{attr}={getattr(self, attr)!r}' for attr in self.__slots__)
return f'<{self.__class__.__name__} {value}>'
# `inspect.iscoroutinefunction()` only became equivalent to (now deprecated) `asyncio.iscoroutinefunction()` in Python 3.12
# https://github.com/python/cpython/issues/122858#issuecomment-2466239748
if sys.version_info >= (3, 12):
_iscoroutinefunction = inspect.iscoroutinefunction
else:
_iscoroutinefunction = asyncio.iscoroutinefunction

4
docs/_static/style.css

@ -387,7 +387,7 @@ aside {
background-color: var(--mobile-nav-background);
color: var(--mobile-nav-text);
z-index: 2;
max-height: 100vh;
max-height: 100dvh;
overflow-y: auto;
overscroll-behavior-y: contain;
}
@ -1285,7 +1285,7 @@ div.code-block-caption {
display: inline-block;
position: sticky;
top: 1em;
max-height: calc(100vh - 2em);
max-height: calc(100dvh - 2em);
max-width: 100%;
overflow-y: auto;
margin: 1em;

4
docs/api.rst

@ -2846,7 +2846,7 @@ of :class:`enum.Enum`.
.. attribute:: scheduled_event_update
A scheduled event was created.
A scheduled event was updated.
When this is the action, the type of :attr:`~AuditLogEntry.target` is
the :class:`ScheduledEvent` or :class:`Object` with the ID of the event
@ -2866,7 +2866,7 @@ of :class:`enum.Enum`.
.. attribute:: scheduled_event_delete
A scheduled event was created.
A scheduled event was deleted.
When this is the action, the type of :attr:`~AuditLogEntry.target` is
the :class:`ScheduledEvent` or :class:`Object` with the ID of the event

6
docs/ext/commands/commands.rst

@ -1212,7 +1212,7 @@ This allows you to define a command as both slash and text command without writi
both counterparts.
In order to define a hybrid command, The command callback should be decorated with
In order to define a hybrid command, the command callback should be decorated with
:meth:`.Bot.hybrid_command` decorator.
.. code-block:: python3
@ -1264,11 +1264,11 @@ Apart from that, all other features such as converters, checks, autocomplete, fl
are supported on hybrid commands. Note that due to a design constraint, decorators related to application commands
such as :func:`discord.app_commands.autocomplete` should be placed below the :func:`~ext.commands.hybrid_command` decorator.
For convenience and ease in writing code, The :class:`~ext.commands.Context` class implements
For convenience and ease in writing code, the :class:`~ext.commands.Context` class implements
some behavioural changes for various methods and attributes:
- :attr:`.Context.interaction` can be used to retrieve the slash command interaction.
- Since interaction can only be responded to once, The :meth:`.Context.send` automatically
- Since interaction can only be responded to once, the :meth:`.Context.send` automatically
determines whether to send an interaction response or a followup response.
- :meth:`.Context.defer` defers the interaction response for slash commands but shows typing
indicator for text commands.

2
docs/ext/commands/extensions.rst

@ -10,7 +10,7 @@ There comes a time in the bot development when you want to extend the bot functi
Primer
--------
An extension at its core is a python file with an entry point called ``setup``. This setup function must be a Python coroutine. It takes a single parameter -- the :class:`~.commands.Bot` that loads the extension.
An extension at its core is a Python file with an entry point called ``setup``. This setup function must be a Python coroutine. It takes a single parameter -- the :class:`~.commands.Bot` that loads the extension.
An example extension looks like this:

2
docs/intents.rst

@ -153,7 +153,7 @@ If the cache is disabled or you disable chunking guilds at startup, we might sti
- :meth:`Guild.fetch_member`
- Used to fetch a member by ID through the HTTP API.
- :meth:`Guild.fetch_members`
- used to fetch a large number of members through the HTTP API.
- Used to fetch a large number of members through the HTTP API.
It should be noted that the gateway has a strict rate limit of 120 requests per 60 seconds.

8
docs/interactions/api.rst

@ -533,10 +533,10 @@ Enumerations
.. attribute:: file_upload
Represents a file upload component, usually in a modal.
Represents a file upload component, usually in a modal.
.. versionadded:: 2.7
.. versionadded:: 2.7
.. attribute:: radio_group
Represents a radio group component.
@ -634,7 +634,7 @@ Enumerations
A string parameter.
.. attribute:: integer
A integer parameter.
An integer parameter.
.. attribute:: boolean
A boolean parameter.

5
docs/version_guarantees.rst

@ -24,9 +24,8 @@ Examples of Non-Breaking Changes
- Adding or removing private underscored attributes.
- Adding an element into the ``__slots__`` of a data class.
- Changing the behaviour of a function to fix a bug.
- Changes in the typing behaviour of the library
- Changes in the calling convention of functions that are primarily meant as callbacks
- Changes in the typing behaviour of the library.
- Changes in the calling convention of functions that are primarily meant as callbacks.
- Changes in the documentation.
- Modifying the internal HTTP handling.
- Upgrading the dependencies to a new version, major or otherwise.

1
pyproject.toml

@ -91,6 +91,7 @@ include-package-data = true
[tool.ruff]
line-length = 125
extend-exclude = ["docs", "tests"]
[tool.ruff.lint.isort]
combine-as-imports = true

14
tests/test_permissions_all.py

@ -1,7 +1,7 @@
import discord
from functools import reduce
from operator import or_
def test_permissions_all():
assert discord.Permissions.all().value == reduce(or_, discord.Permissions.VALID_FLAGS.values())
import discord
from functools import reduce
from operator import or_
def test_permissions_all():
assert discord.Permissions.all().value == reduce(or_, discord.Permissions.VALID_FLAGS.values())

Loading…
Cancel
Save