Skip to content

Commit

Permalink
Merge branch 'master' into Eneg/cooldowns-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
shiftinv authored Nov 29, 2024
2 parents 496c123 + b92f382 commit bc674b4
Show file tree
Hide file tree
Showing 61 changed files with 1,030 additions and 156 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ repos:
name: "run black in all files"

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.3.4
rev: v0.8.0
hooks:
- id: ruff
args: [--fix, --fixable=I]
2 changes: 1 addition & 1 deletion changelog/1113.feature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Support application subscriptions and one-time purchases (see the :ddocs:`offici
- New types: :class:`SKU`, :class:`Entitlement`.
- New :attr:`Interaction.entitlements` attribute, and :meth:`InteractionResponse.require_premium` response type.
- New events: :func:`on_entitlement_create`, :func:`on_entitlement_update`, :func:`on_entitlement_delete`.
- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.create_entitlement`.
- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.fetch_entitlement`, :meth:`~Client.create_entitlement`.
1 change: 1 addition & 0 deletions changelog/1115.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :class:`SelectDefaultValue`, and add :attr:`~UserSelectMenu.default_values` to all auto-populated select menu types.
1 change: 0 additions & 1 deletion changelog/1180.doc.rst

This file was deleted.

1 change: 1 addition & 0 deletions changelog/1184.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the possibility to pass :class:`disnake.File` objects to :meth:`Embed.set_author` and :meth:`~Embed.set_footer`.
2 changes: 1 addition & 1 deletion changelog/1186.feature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ Support application subscriptions and one-time purchases (see the :ddocs:`offici
- New types: :class:`SKU`, :class:`Entitlement`.
- New :attr:`Interaction.entitlements` attribute, and :meth:`InteractionResponse.require_premium` response type.
- New events: :func:`on_entitlement_create`, :func:`on_entitlement_update`, :func:`on_entitlement_delete`.
- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.create_entitlement`.
- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.fetch_entitlement`, :meth:`~Client.create_entitlement`.
1 change: 1 addition & 0 deletions changelog/1203.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement new :attr:`.Member.guild_banner` property.
1 change: 1 addition & 0 deletions changelog/1212.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add new :attr:`~MessageType.poll_result` message type.
1 change: 1 addition & 0 deletions changelog/1216.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :meth:`Guild.fetch_voice_state` to fetch the :class:`VoiceState` of a member.
1 change: 0 additions & 1 deletion changelog/1228.feature.rst

This file was deleted.

1 change: 0 additions & 1 deletion changelog/1228.misc.rst

This file was deleted.

1 change: 1 addition & 0 deletions changelog/1238.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for ``BaseFlags`` to allow comparison with ``flag_values`` and vice versa.
1 change: 1 addition & 0 deletions changelog/1245.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement :attr:`~MemberFlags.is_guest`, :attr:`~MemberFlags.started_home_actions`, :attr:`~MemberFlags.completed_home_actions`, :attr:`~MemberFlags.automod_quarantined_username`, :attr:`~MemberFlags.dm_settings_upsell_acknowledged` new member flags.
1 change: 1 addition & 0 deletions changelog/1247.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement the new :meth:`.Guild.fetch_role` API method.
5 changes: 5 additions & 0 deletions changelog/1249.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Support application subscriptions and one-time purchases (see the :ddocs:`official docs <monetization/overview>` for more info).
- New types: :class:`SKU`, :class:`Entitlement`.
- New :attr:`Interaction.entitlements` attribute, and :meth:`InteractionResponse.require_premium` response type.
- New events: :func:`on_entitlement_create`, :func:`on_entitlement_update`, :func:`on_entitlement_delete`.
- New :class:`Client` methods: :meth:`~Client.skus`, :meth:`~Client.entitlements`, :meth:`~Client.fetch_entitlement`, :meth:`~Client.create_entitlement`.
1 change: 1 addition & 0 deletions changelog/1252.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
|commands| Fix incorrect exception when using the :func:`~ext.commands.default_member_permissions` decorator on a :func:`~ext.commands.user_command` while also using the cog-level ``user_command_attrs`` field.
8 changes: 3 additions & 5 deletions disnake/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
from .permissions import PermissionOverwrite, Permissions
from .role import Role
from .sticker import GuildSticker, StandardSticker, StickerItem
from .ui.action_row import components_to_dict
from .utils import _overload_with_permissions
from .voice_client import VoiceClient, VoiceProtocol

Expand Down Expand Up @@ -179,6 +178,7 @@ def avatar(self) -> Optional[Asset]:
raise NotImplementedError


# FIXME: this shouldn't be a protocol. isinstance(thread, PrivateChannel) returns true, and issubclass doesn't work.
@runtime_checkable
class PrivateChannel(Snowflake, Protocol):
"""An ABC that details the common operations on a private Discord channel.
Expand Down Expand Up @@ -1719,16 +1719,14 @@ async def send(

if view is not None and components is not None:
raise TypeError("cannot pass both view and components parameter to send()")

elif view:
if not hasattr(view, "__discord_ui_view__"):
raise TypeError(f"view parameter must be View not {view.__class__!r}")

components_payload = view.to_components()

elif components:
components_payload = components_to_dict(components)
from .ui.action_row import components_to_dict

components_payload = components_to_dict(components)
else:
components_payload = None

Expand Down
2 changes: 1 addition & 1 deletion disnake/app_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def localize(self, store: LocalizationProtocol) -> None:
o.localize(store)


class ApplicationCommand(ABC):
class ApplicationCommand(ABC): # noqa: B024 # this will get refactored eventually
"""The base class for application commands.
The following classes implement this ABC:
Expand Down
13 changes: 13 additions & 0 deletions disnake/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ def _from_guild_avatar(
animated=animated,
)

@classmethod
def _from_guild_banner(
cls, state: AnyState, guild_id: int, member_id: int, banner: str
) -> Self:
animated = banner.startswith("a_")
format = "gif" if animated else "png"
return cls(
state,
url=f"{cls.BASE}/guilds/{guild_id}/users/{member_id}/banners/{banner}.{format}?size=1024",
key=banner,
animated=animated,
)

@classmethod
def _from_icon(cls, state: AnyState, object_id: int, icon_hash: str, path: str) -> Self:
return cls(
Expand Down
1 change: 1 addition & 0 deletions disnake/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5092,6 +5092,7 @@ def _channel_type_factory(
cls: Union[Type[disnake.abc.GuildChannel], Type[Thread]]
) -> List[ChannelType]:
return {
# FIXME: this includes private channels; improve this once there's a common base type for all channels
disnake.abc.GuildChannel: list(ChannelType.__members__.values()),
VocalGuildChannel: [ChannelType.voice, ChannelType.stage_voice],
disnake.abc.PrivateChannel: [ChannelType.private, ChannelType.group],
Expand Down
41 changes: 40 additions & 1 deletion disnake/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,12 @@ def run(self, *args: Any, **kwargs: Any) -> None:
This function must be the last function to call due to the fact that it
is blocking. That means that registration of events or anything being
called after this function call will not execute until it returns.
called after this function call will not execute until it returns
Parameters
----------
token: :class:`str`
The discord token of the bot that is being ran.
"""
loop = self.loop

Expand Down Expand Up @@ -3142,6 +3147,7 @@ def entitlements(
guild: Optional[Snowflake] = None,
skus: Optional[Sequence[Snowflake]] = None,
exclude_ended: bool = False,
exclude_deleted: bool = True,
oldest_first: bool = False,
) -> EntitlementIterator:
"""Retrieves an :class:`.AsyncIterator` that enables receiving entitlements for the application.
Expand Down Expand Up @@ -3181,6 +3187,8 @@ def entitlements(
The SKUs for which entitlements are retrieved.
exclude_ended: :class:`bool`
Whether to exclude ended/expired entitlements. Defaults to ``False``.
exclude_deleted: :class:`bool`
Whether to exclude deleted entitlements. Defaults to ``True``.
oldest_first: :class:`bool`
If set to ``True``, return entries in oldest->newest order. Defaults to ``False``.
Expand All @@ -3204,9 +3212,40 @@ def entitlements(
guild_id=guild.id if guild is not None else None,
sku_ids=[sku.id for sku in skus] if skus else None,
exclude_ended=exclude_ended,
exclude_deleted=exclude_deleted,
oldest_first=oldest_first,
)

async def fetch_entitlement(self, entitlement_id: int, /) -> Entitlement:
"""|coro|
Retrieves a :class:`.Entitlement` for the given ID.
.. note::
This method is an API call. To get the entitlements of the invoking user/guild
in interactions, consider using :attr:`.Interaction.entitlements`.
.. versionadded:: 2.10
Parameters
----------
entitlement_id: :class:`int`
The ID of the entitlement to retrieve.
Raises
------
HTTPException
Retrieving the entitlement failed.
Returns
-------
:class:`.Entitlement`
The retrieved entitlement.
"""
data = await self.http.get_entitlement(self.application_id, entitlement_id=entitlement_id)
return Entitlement(data=data, state=self._connection)

async def create_entitlement(
self, sku: Snowflake, owner: Union[abc.User, Guild]
) -> Entitlement:
Expand Down
83 changes: 81 additions & 2 deletions disnake/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
cast,
)

from .enums import ButtonStyle, ChannelType, ComponentType, TextInputStyle, try_enum
from .enums import (
ButtonStyle,
ChannelType,
ComponentType,
SelectDefaultValueType,
TextInputStyle,
try_enum,
)
from .partial_emoji import PartialEmoji, _EmojiTag
from .utils import MISSING, assert_never, get_slots

Expand All @@ -35,6 +42,7 @@
Component as ComponentPayload,
MentionableSelectMenu as MentionableSelectMenuPayload,
RoleSelectMenu as RoleSelectMenuPayload,
SelectDefaultValue as SelectDefaultValuePayload,
SelectOption as SelectOptionPayload,
StringSelectMenu as StringSelectMenuPayload,
TextInput as TextInputPayload,
Expand All @@ -53,6 +61,7 @@
"MentionableSelectMenu",
"ChannelSelectMenu",
"SelectOption",
"SelectDefaultValue",
"TextInput",
)

Expand Down Expand Up @@ -264,6 +273,12 @@ class BaseSelectMenu(Component):
A list of options that can be selected in this select menu.
disabled: :class:`bool`
Whether the select menu is disabled or not.
default_values: List[:class:`SelectDefaultValue`]
The list of values (users/roles/channels) that are selected by default.
If set, the number of items must be within the bounds set by ``min_values`` and ``max_values``.
Only available for auto-populated select menus.
.. versionadded:: 2.10
"""

__slots__: Tuple[str, ...] = (
Expand All @@ -272,9 +287,11 @@ class BaseSelectMenu(Component):
"min_values",
"max_values",
"disabled",
"default_values",
)

__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
# FIXME: this isn't pretty; we should decouple __repr__ from slots
__repr_info__: ClassVar[Tuple[str, ...]] = tuple(s for s in __slots__ if s != "default_values")

# n.b: ideally this would be `BaseSelectMenuPayload`,
# but pyright made TypedDict keys invariant and doesn't
Expand All @@ -288,6 +305,9 @@ def __init__(self, data: AnySelectMenuPayload) -> None:
self.min_values: int = data.get("min_values", 1)
self.max_values: int = data.get("max_values", 1)
self.disabled: bool = data.get("disabled", False)
self.default_values: List[SelectDefaultValue] = [
SelectDefaultValue._from_dict(d) for d in (data.get("default_values") or [])
]

def to_dict(self) -> BaseSelectMenuPayload:
payload: BaseSelectMenuPayload = {
Expand All @@ -301,6 +321,9 @@ def to_dict(self) -> BaseSelectMenuPayload:
if self.placeholder:
payload["placeholder"] = self.placeholder

if self.default_values:
payload["default_values"] = [v.to_dict() for v in self.default_values]

return payload


Expand Down Expand Up @@ -377,6 +400,11 @@ class UserSelectMenu(BaseSelectMenu):
Defaults to 1 and must be between 1 and 25.
disabled: :class:`bool`
Whether the select menu is disabled or not.
default_values: List[:class:`SelectDefaultValue`]
The list of values (users/members) that are selected by default.
If set, the number of items must be within the bounds set by ``min_values`` and ``max_values``.
.. versionadded:: 2.10
"""

__slots__: Tuple[str, ...] = ()
Expand Down Expand Up @@ -412,6 +440,11 @@ class RoleSelectMenu(BaseSelectMenu):
Defaults to 1 and must be between 1 and 25.
disabled: :class:`bool`
Whether the select menu is disabled or not.
default_values: List[:class:`SelectDefaultValue`]
The list of values (roles) that are selected by default.
If set, the number of items must be within the bounds set by ``min_values`` and ``max_values``.
.. versionadded:: 2.10
"""

__slots__: Tuple[str, ...] = ()
Expand Down Expand Up @@ -447,6 +480,11 @@ class MentionableSelectMenu(BaseSelectMenu):
Defaults to 1 and must be between 1 and 25.
disabled: :class:`bool`
Whether the select menu is disabled or not.
default_values: List[:class:`SelectDefaultValue`]
The list of values (users/roles) that are selected by default.
If set, the number of items must be within the bounds set by ``min_values`` and ``max_values``.
.. versionadded:: 2.10
"""

__slots__: Tuple[str, ...] = ()
Expand Down Expand Up @@ -485,6 +523,11 @@ class ChannelSelectMenu(BaseSelectMenu):
channel_types: Optional[List[:class:`ChannelType`]]
A list of channel types that can be selected in this select menu.
If ``None``, channels of all types may be selected.
default_values: List[:class:`SelectDefaultValue`]
The list of values (channels) that are selected by default.
If set, the number of items must be within the bounds set by ``min_values`` and ``max_values``.
.. versionadded:: 2.10
"""

__slots__: Tuple[str, ...] = ("channel_types",)
Expand Down Expand Up @@ -613,6 +656,42 @@ def to_dict(self) -> SelectOptionPayload:
return payload


class SelectDefaultValue:
"""Represents a default value of an auto-populated select menu (currently all
select menu types except :class:`StringSelectMenu`).
Depending on the :attr:`type` attribute, this can represent different types of objects.
.. versionadded:: 2.10
Attributes
----------
id: :class:`int`
The ID of the target object.
type: :class:`SelectDefaultValueType`
The type of the target object.
"""

__slots__: Tuple[str, ...] = ("id", "type")

def __init__(self, id: int, type: SelectDefaultValueType) -> None:
self.id: int = id
self.type: SelectDefaultValueType = type

@classmethod
def _from_dict(cls, data: SelectDefaultValuePayload) -> Self:
return cls(int(data["id"]), try_enum(SelectDefaultValueType, data["type"]))

def to_dict(self) -> SelectDefaultValuePayload:
return {
"id": self.id,
"type": self.type.value,
}

def __repr__(self) -> str:
return f"<SelectDefaultValue id={self.id!r} type={self.type.value!r}>"


class TextInput(Component):
"""Represents a text input from the Discord Bot UI Kit.
Expand Down
Loading

0 comments on commit bc674b4

Please sign in to comment.