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 Oct 17, 2024
2 parents ded4a25 + 354ae42 commit dff511e
Show file tree
Hide file tree
Showing 42 changed files with 3,136 additions and 125 deletions.
2 changes: 2 additions & 0 deletions discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
from .threads import *
from .automod import *
from .poll import *
from .soundboard import *
from .subscription import *


class VersionInfo(NamedTuple):
Expand Down
17 changes: 16 additions & 1 deletion discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,11 +1005,15 @@ async def _clone_impl(
base_attrs: Dict[str, Any],
*,
name: Optional[str] = None,
category: Optional[CategoryChannel] = None,
reason: Optional[str] = None,
) -> Self:
base_attrs['permission_overwrites'] = [x._asdict() for x in self._overwrites]
base_attrs['parent_id'] = self.category_id
base_attrs['name'] = name or self.name
if category is not None:
base_attrs['parent_id'] = category.id

guild_id = self.guild.id
cls = self.__class__
data = await self._state.http.create_channel(guild_id, self.type.value, reason=reason, **base_attrs)
Expand All @@ -1019,7 +1023,13 @@ async def _clone_impl(
self.guild._channels[obj.id] = obj # type: ignore # obj is a GuildChannel
return obj

async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> Self:
async def clone(
self,
*,
name: Optional[str] = None,
category: Optional[CategoryChannel] = None,
reason: Optional[str] = None,
) -> Self:
"""|coro|
Clones this channel. This creates a channel with the same properties
Expand All @@ -1034,6 +1044,11 @@ async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = Non
name: Optional[:class:`str`]
The name of the new channel. If not provided, defaults to this
channel name.
category: Optional[:class:`~discord.CategoryChannel`]
The category the new channel belongs to.
This parameter is ignored if cloning a category channel.
.. versionadded:: 2.5
reason: Optional[:class:`str`]
The reason for cloning this channel. Shows up on the audit log.
Expand Down
22 changes: 19 additions & 3 deletions discord/app_commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2823,7 +2823,7 @@ def inner(f: T) -> T:
return inner


def default_permissions(**perms: bool) -> Callable[[T], T]:
def default_permissions(perms_obj: Optional[Permissions] = None, /, **perms: bool) -> Callable[[T], T]:
r"""A decorator that sets the default permissions needed to execute this command.
When this decorator is used, by default users must have these permissions to execute the command.
Expand All @@ -2847,8 +2847,12 @@ def default_permissions(**perms: bool) -> Callable[[T], T]:
-----------
\*\*perms: :class:`bool`
Keyword arguments denoting the permissions to set as the default.
perms_obj: :class:`~discord.Permissions`
A permissions object as positional argument. This can be used in combination with ``**perms``.
Example
.. versionadded:: 2.5
Examples
---------
.. code-block:: python3
Expand All @@ -2857,9 +2861,21 @@ def default_permissions(**perms: bool) -> Callable[[T], T]:
@app_commands.default_permissions(manage_messages=True)
async def test(interaction: discord.Interaction):
await interaction.response.send_message('You may or may not have manage messages.')
.. code-block:: python3
ADMIN_PERMS = discord.Permissions(administrator=True)
@app_commands.command()
@app_commands.default_permissions(ADMIN_PERMS, manage_messages=True)
async def test(interaction: discord.Interaction):
await interaction.response.send_message('You may or may not have manage messages.')
"""

permissions = Permissions(**perms)
if perms_obj is not None:
permissions = perms_obj | Permissions(**perms)
else:
permissions = Permissions(**perms)

def decorator(func: T) -> T:
if isinstance(func, (Command, Group, ContextMenu)):
Expand Down
32 changes: 17 additions & 15 deletions discord/app_commands/transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
ClassVar,
Coroutine,
Dict,
Generic,
List,
Literal,
Optional,
Expand All @@ -56,6 +57,7 @@
from ..role import Role
from ..member import Member
from ..message import Attachment
from .._types import ClientT

__all__ = (
'Transformer',
Expand Down Expand Up @@ -191,7 +193,7 @@ def display_name(self) -> str:
return self.name if self._rename is MISSING else str(self._rename)


class Transformer:
class Transformer(Generic[ClientT]):
"""The base class that allows a type annotation in an application command parameter
to map into a :class:`~discord.AppCommandOptionType` and transform the raw value into one
from this type.
Expand Down Expand Up @@ -304,7 +306,7 @@ def _error_display_name(self) -> str:
else:
return name

async def transform(self, interaction: Interaction, value: Any, /) -> Any:
async def transform(self, interaction: Interaction[ClientT], value: Any, /) -> Any:
"""|maybecoro|
Transforms the converted option value into another value.
Expand All @@ -324,7 +326,7 @@ async def transform(self, interaction: Interaction, value: Any, /) -> Any:
raise NotImplementedError('Derived classes need to implement this.')

async def autocomplete(
self, interaction: Interaction, value: Union[int, float, str], /
self, interaction: Interaction[ClientT], value: Union[int, float, str], /
) -> List[Choice[Union[int, float, str]]]:
"""|coro|
Expand Down Expand Up @@ -352,15 +354,15 @@ async def autocomplete(
raise NotImplementedError('Derived classes can implement this.')


class IdentityTransformer(Transformer):
class IdentityTransformer(Transformer[ClientT]):
def __init__(self, type: AppCommandOptionType) -> None:
self._type = type

@property
def type(self) -> AppCommandOptionType:
return self._type

async def transform(self, interaction: Interaction, value: Any, /) -> Any:
async def transform(self, interaction: Interaction[ClientT], value: Any, /) -> Any:
return value


Expand Down Expand Up @@ -489,7 +491,7 @@ async def transform(self, interaction: Interaction, value: Any, /) -> Any:
return self._enum[value]


class InlineTransformer(Transformer):
class InlineTransformer(Transformer[ClientT]):
def __init__(self, annotation: Any) -> None:
super().__init__()
self.annotation: Any = annotation
Expand All @@ -502,7 +504,7 @@ def _error_display_name(self) -> str:
def type(self) -> AppCommandOptionType:
return AppCommandOptionType.string

async def transform(self, interaction: Interaction, value: Any, /) -> Any:
async def transform(self, interaction: Interaction[ClientT], value: Any, /) -> Any:
return await self.annotation.transform(interaction, value)


Expand Down Expand Up @@ -611,18 +613,18 @@ def __class_getitem__(cls, obj) -> RangeTransformer:
return transformer


class MemberTransformer(Transformer):
class MemberTransformer(Transformer[ClientT]):
@property
def type(self) -> AppCommandOptionType:
return AppCommandOptionType.user

async def transform(self, interaction: Interaction, value: Any, /) -> Member:
async def transform(self, interaction: Interaction[ClientT], value: Any, /) -> Member:
if not isinstance(value, Member):
raise TransformerError(value, self.type, self)
return value


class BaseChannelTransformer(Transformer):
class BaseChannelTransformer(Transformer[ClientT]):
def __init__(self, *channel_types: Type[Any]) -> None:
super().__init__()
if len(channel_types) == 1:
Expand Down Expand Up @@ -654,22 +656,22 @@ def type(self) -> AppCommandOptionType:
def channel_types(self) -> List[ChannelType]:
return self._channel_types

async def transform(self, interaction: Interaction, value: Any, /):
async def transform(self, interaction: Interaction[ClientT], value: Any, /):
resolved = value.resolve()
if resolved is None or not isinstance(resolved, self._types):
raise TransformerError(value, AppCommandOptionType.channel, self)
return resolved


class RawChannelTransformer(BaseChannelTransformer):
async def transform(self, interaction: Interaction, value: Any, /):
class RawChannelTransformer(BaseChannelTransformer[ClientT]):
async def transform(self, interaction: Interaction[ClientT], value: Any, /):
if not isinstance(value, self._types):
raise TransformerError(value, AppCommandOptionType.channel, self)
return value


class UnionChannelTransformer(BaseChannelTransformer):
async def transform(self, interaction: Interaction, value: Any, /):
class UnionChannelTransformer(BaseChannelTransformer[ClientT]):
async def transform(self, interaction: Interaction[ClientT], value: Any, /):
if isinstance(value, self._types):
return value

Expand Down
4 changes: 2 additions & 2 deletions discord/app_commands/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
from .commands import ContextMenuCallback, CommandCallback, P, T

ErrorFunc = Callable[
[Interaction, AppCommandError],
[Interaction[ClientT], AppCommandError],
Coroutine[Any, Any, Any],
]

Expand Down Expand Up @@ -833,7 +833,7 @@ async def on_error(self, interaction: Interaction[ClientT], error: AppCommandErr
else:
_log.error('Ignoring exception in command tree', exc_info=error)

def error(self, coro: ErrorFunc) -> ErrorFunc:
def error(self, coro: ErrorFunc[ClientT]) -> ErrorFunc[ClientT]:
"""A decorator that registers a coroutine as a local error handler.
This must match the signature of the :meth:`on_error` callback.
Expand Down
6 changes: 6 additions & 0 deletions discord/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ def _transform_automod_actions(entry: AuditLogEntry, data: List[AutoModerationAc
return [AutoModRuleAction.from_data(action) for action in data]


def _transform_default_emoji(entry: AuditLogEntry, data: str) -> PartialEmoji:
return PartialEmoji(name=data)


E = TypeVar('E', bound=enums.Enum)


Expand Down Expand Up @@ -341,6 +345,8 @@ class AuditLogChanges:
'available_tags': (None, _transform_forum_tags),
'flags': (None, _transform_overloaded_flags),
'default_reaction_emoji': (None, _transform_default_reaction),
'emoji_name': ('emoji', _transform_default_emoji),
'user_id': ('user', _transform_member_id)
}
# fmt: on

Expand Down
Loading

0 comments on commit dff511e

Please sign in to comment.