Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Rapptz/discord.py into v2…
Browse files Browse the repository at this point in the history
…-martine
  • Loading branch information
PredaaA committed Jun 26, 2024
2 parents 31a9f2f + 3a80636 commit 7d3a5d7
Show file tree
Hide file tree
Showing 33 changed files with 1,258 additions and 815 deletions.
4 changes: 2 additions & 2 deletions discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
__author__ = 'Rapptz'
__license__ = 'MIT'
__copyright__ = 'Copyright 2015-present Rapptz'
__version__ = '2.4.0a'
__version__ = '2.5.0a'

__path__ = __import__('pkgutil').extend_path(__path__, __name__)

Expand Down Expand Up @@ -80,7 +80,7 @@ class VersionInfo(NamedTuple):
serial: int


version_info: VersionInfo = VersionInfo(major=2, minor=4, micro=0, releaselevel='alpha', serial=0)
version_info: VersionInfo = VersionInfo(major=2, minor=5, micro=0, releaselevel='alpha', serial=0)

logging.getLogger(__name__).addHandler(logging.NullHandler())

Expand Down
25 changes: 23 additions & 2 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from .object import OLDEST_OBJECT, Object
from .context_managers import Typing
from .enums import ChannelType, InviteTarget
from .errors import ClientException
from .errors import ClientException, NotFound
from .mentions import AllowedMentions
from .permissions import PermissionOverwrite, Permissions
from .role import Role
Expand Down Expand Up @@ -122,7 +122,14 @@ def __repr__(self) -> str:

async def _single_delete_strategy(messages: Iterable[Message], *, reason: Optional[str] = None):
for m in messages:
await m.delete()
try:
await m.delete()
except NotFound as exc:
if exc.code == 10008:
continue # bulk deletion ignores not found messages, single deletion does not.
# several other race conditions with deletion should fail without continuing,
# such as the channel being deleted and not found.
raise


async def _purge_helper(
Expand Down Expand Up @@ -699,6 +706,7 @@ def permissions_for(self, obj: Union[Member, Role], /) -> Permissions:
- Member overrides
- Implicit permissions
- Member timeout
- User installed app
If a :class:`~discord.Role` is passed, then it checks the permissions
someone with that role would have, which is essentially:
Expand All @@ -714,6 +722,12 @@ def permissions_for(self, obj: Union[Member, Role], /) -> Permissions:
.. versionchanged:: 2.0
``obj`` parameter is now positional-only.
.. versionchanged:: 2.4
User installed apps are now taken into account.
The permissions returned for a user installed app mirrors the
permissions Discord returns in :attr:`~discord.Interaction.app_permissions`,
though it is recommended to use that attribute instead.
Parameters
----------
obj: Union[:class:`~discord.Member`, :class:`~discord.Role`]
Expand Down Expand Up @@ -745,6 +759,13 @@ def permissions_for(self, obj: Union[Member, Role], /) -> Permissions:
return Permissions.all()

default = self.guild.default_role
if default is None:

if self._state.self_id == obj.id:
return Permissions._user_installed_permissions(in_guild=True)
else:
return Permissions.none()

base = Permissions(default.permissions.value)

# Handle the role case first
Expand Down
16 changes: 16 additions & 0 deletions discord/app_commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2372,6 +2372,12 @@ def guilds(*guild_ids: Union[Snowflake, int]) -> Callable[[T], T]:
with the :meth:`CommandTree.command` or :meth:`CommandTree.context_menu` decorator
then this must go below that decorator.
.. note ::
Due to a Discord limitation, this decorator cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
Example:
.. code-block:: python3
Expand Down Expand Up @@ -2545,6 +2551,8 @@ def private_channel_only(func: Optional[T] = None) -> Union[T, Callable[[T], T]]
Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.
.. versionadded:: 2.4
Examples
---------
Expand Down Expand Up @@ -2636,6 +2644,8 @@ def allowed_contexts(guilds: bool = MISSING, dms: bool = MISSING, private_channe
Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.
.. versionadded:: 2.4
Examples
---------
Expand Down Expand Up @@ -2687,6 +2697,8 @@ def guild_install(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.
.. versionadded:: 2.4
Examples
---------
Expand Down Expand Up @@ -2735,6 +2747,8 @@ def user_install(func: Optional[T] = None) -> Union[T, Callable[[T], T]]:
Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.
.. versionadded:: 2.4
Examples
---------
Expand Down Expand Up @@ -2777,6 +2791,8 @@ def allowed_installs(
Due to a Discord limitation, this decorator does nothing in subcommands and is ignored.
.. versionadded:: 2.4
Examples
---------
Expand Down
10 changes: 5 additions & 5 deletions discord/app_commands/installs.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ def user(self, value: bool) -> None:
def merge(self, other: AppInstallationType) -> AppInstallationType:
# Merging is similar to AllowedMentions where `self` is the base
# and the `other` is the override preference
guild = self.guild if other.guild is None else other.guild
user = self.user if other.user is None else other.user
guild = self._guild if other._guild is None else other._guild
user = self._user if other._user is None else other._user
return AppInstallationType(guild=guild, user=user)

def _is_unset(self) -> bool:
Expand Down Expand Up @@ -170,9 +170,9 @@ def private_channel(self, value: bool) -> None:
self._private_channel = bool(value)

def merge(self, other: AppCommandContext) -> AppCommandContext:
guild = self.guild if other.guild is None else other.guild
dm_channel = self.dm_channel if other.dm_channel is None else other.dm_channel
private_channel = self.private_channel if other.private_channel is None else other.private_channel
guild = self._guild if other._guild is None else other._guild
dm_channel = self._dm_channel if other._dm_channel is None else other._dm_channel
private_channel = self._private_channel if other._private_channel is None else other._private_channel
return AppCommandContext(guild=guild, dm_channel=dm_channel, private_channel=private_channel)

def _is_unset(self) -> bool:
Expand Down
42 changes: 42 additions & 0 deletions discord/app_commands/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,24 @@ def add_command(
guild: Optional[:class:`~discord.abc.Snowflake`]
The guild to add the command to. If not given or ``None`` then it
becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
guilds: List[:class:`~discord.abc.Snowflake`]
The list of guilds to add the command to. This cannot be mixed
with the ``guild`` parameter. If no guilds are given at all
then it becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
override: :class:`bool`
Whether to override a command with the same name. If ``False``
an exception is raised. Default is ``False``.
Expand Down Expand Up @@ -877,10 +891,24 @@ def command(
guild: Optional[:class:`~discord.abc.Snowflake`]
The guild to add the command to. If not given or ``None`` then it
becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
guilds: List[:class:`~discord.abc.Snowflake`]
The list of guilds to add the command to. This cannot be mixed
with the ``guild`` parameter. If no guilds are given at all
then it becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
auto_locale_strings: :class:`bool`
If this is set to ``True``, then all translatable strings will implicitly
be wrapped into :class:`locale_str` rather than :class:`str`. This could
Expand Down Expand Up @@ -960,10 +988,24 @@ async def ban(interaction: discord.Interaction, user: discord.Member):
guild: Optional[:class:`~discord.abc.Snowflake`]
The guild to add the command to. If not given or ``None`` then it
becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
guilds: List[:class:`~discord.abc.Snowflake`]
The list of guilds to add the command to. This cannot be mixed
with the ``guild`` parameter. If no guilds are given at all
then it becomes a global command instead.
.. note ::
Due to a Discord limitation, this keyword argument cannot be used in conjunction with
contexts (e.g. :func:`.app_commands.allowed_contexts`) or installation types
(e.g. :func:`.app_commands.allowed_installs`).
auto_locale_strings: :class:`bool`
If this is set to ``True``, then all translatable strings will implicitly
be wrapped into :class:`locale_str` rather than :class:`str`. This could
Expand Down
3 changes: 3 additions & 0 deletions discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,7 @@ async def edit(
*,
name: str = ...,
nsfw: bool = ...,
bitrate: int = ...,
user_limit: int = ...,
position: int = ...,
sync_permissions: int = ...,
Expand Down Expand Up @@ -1738,6 +1739,8 @@ async def edit(self, *, reason: Optional[str] = None, **options: Any) -> Optiona
----------
name: :class:`str`
The new channel's name.
bitrate: :class:`int`
The new channel's bitrate.
position: :class:`int`
The new channel's position.
nsfw: :class:`bool`
Expand Down
13 changes: 13 additions & 0 deletions discord/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ class Button(Component):
The label of the button, if any.
emoji: Optional[:class:`PartialEmoji`]
The emoji of the button, if available.
sku_id: Optional[:class:`int`]
The SKU ID this button sends you to, if available.
.. versionadded:: 2.4
"""

__slots__: Tuple[str, ...] = (
Expand All @@ -179,6 +183,7 @@ class Button(Component):
'disabled',
'label',
'emoji',
'sku_id',
)

__repr_info__: ClassVar[Tuple[str, ...]] = __slots__
Expand All @@ -195,6 +200,11 @@ def __init__(self, data: ButtonComponentPayload, /) -> None:
except KeyError:
self.emoji = None

try:
self.sku_id: Optional[int] = int(data['sku_id'])
except KeyError:
self.sku_id = None

@property
def type(self) -> Literal[ComponentType.button]:
""":class:`ComponentType`: The type of component."""
Expand All @@ -207,6 +217,9 @@ def to_dict(self) -> ButtonComponentPayload:
'disabled': self.disabled,
}

if self.sku_id:
payload['sku_id'] = str(self.sku_id)

if self.label:
payload['label'] = self.label

Expand Down
14 changes: 13 additions & 1 deletion discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ class InteractionResponseType(Enum):
message_update = 7 # for components
autocomplete_result = 8
modal = 9 # for modals
premium_required = 10
# premium_required = 10 (deprecated)


class VideoQualityMode(Enum):
Expand Down Expand Up @@ -635,6 +635,7 @@ class ButtonStyle(Enum):
success = 3
danger = 4
link = 5
premium = 6

# Aliases
blurple = 1
Expand Down Expand Up @@ -823,6 +824,17 @@ class PollLayoutType(Enum):
default = 1


class InviteType(Enum):
guild = 0
group_dm = 1
friend = 2


class ReactionType(Enum):
normal = 0
burst = 1


def create_unknown_value(cls: Type[E], val: Any) -> E:
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
name = f'unknown_{val}'
Expand Down
Loading

0 comments on commit 7d3a5d7

Please sign in to comment.