Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into feat/theme-embed-…
Browse files Browse the repository at this point in the history
…colors
  • Loading branch information
shiftinv committed Sep 20, 2023
2 parents 689ac56 + 1f871ff commit f641d2a
Show file tree
Hide file tree
Showing 25 changed files with 181 additions and 230 deletions.
232 changes: 67 additions & 165 deletions CONTRIBUTING.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions changelog/1036.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make :class:`Interaction` and subtypes accept the bot type as a generic parameter to denote the type returned by the :attr:`~Interaction.bot` and :attr:`~Interaction.client` properties.
1 change: 1 addition & 0 deletions changelog/1096.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support ``integration_type`` field in :attr:`AuditLogEntry.extra` (for :attr:`~AuditLogAction.kick` and :attr:`~AuditLogAction.member_role_update` actions).
1 change: 1 addition & 0 deletions changelog/1098.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Overhaul and simplify `contribution guide <https://github.com/DisnakeDev/disnake/tree/master/CONTRIBUTING.md>`__.
18 changes: 14 additions & 4 deletions disnake/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,10 @@ class _AuditLogProxyAutoModAction:
rule_trigger_type: enums.AutoModTriggerType


class _AuditLogProxyKickOrMemberRoleAction:
integration_type: Optional[str]


class AuditLogEntry(Hashable):
"""Represents an Audit Log entry.
Expand Down Expand Up @@ -589,7 +593,6 @@ def _from_data(self, data: AuditLogEntryPayload) -> None:

if isinstance(self.action, enums.AuditLogAction) and extra:
if self.action is enums.AuditLogAction.member_prune:
# member prune has two keys with useful information
elems = {
"delete_member_days": utils._get_as_snowflake(extra, "delete_member_days"),
"members_removed": utils._get_as_snowflake(extra, "members_removed"),
Expand All @@ -607,13 +610,11 @@ def _from_data(self, data: AuditLogEntryPayload) -> None:
}
self.extra = type("_AuditLogProxy", (), elems)()
elif self.action is enums.AuditLogAction.member_disconnect:
# The member disconnect action has a dict with some information
elems = {
"count": int(extra["count"]),
}
self.extra = type("_AuditLogProxy", (), elems)()
elif self.action.name.endswith("pin"):
# the pin actions have a dict with some information
elems = {
"channel": self._get_channel_or_thread(
utils._get_as_snowflake(extra, "channel_id")
Expand All @@ -622,7 +623,6 @@ def _from_data(self, data: AuditLogEntryPayload) -> None:
}
self.extra = type("_AuditLogProxy", (), elems)()
elif self.action.name.startswith("overwrite_"):
# the overwrite_ actions have a dict with some information
instance_id = int(extra["id"])
the_type = extra.get("type")
if the_type == "1":
Expand Down Expand Up @@ -662,6 +662,15 @@ def _from_data(self, data: AuditLogEntryPayload) -> None:
),
}
self.extra = type("_AuditLogProxy", (), elems)()
elif self.action in (
enums.AuditLogAction.kick,
enums.AuditLogAction.member_role_update,
):
elems = {
# unlike other extras, this key isn't always provided
"integration_type": extra.get("integration_type"),
}
self.extra = type("_AuditLogProxy", (), elems)()

self.extra: Any
# actually this but there's no reason to annoy users with this:
Expand All @@ -672,6 +681,7 @@ def _from_data(self, data: AuditLogEntryPayload) -> None:
# _AuditLogProxyPinAction,
# _AuditLogProxyStageInstanceAction,
# _AuditLogProxyAutoModAction,
# _AuditLogProxyKickOrMemberRoleAction,
# Member, User, None,
# Role,
# ]
Expand Down
21 changes: 14 additions & 7 deletions disnake/ext/commands/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
T = TypeVar("T", bound=Any)
TypeT = TypeVar("TypeT", bound=Type[Any])
CallableT = TypeVar("CallableT", bound=Callable[..., Any])
BotT = TypeVar("BotT", bound="disnake.Client", covariant=True)

__all__ = (
"Range",
Expand Down Expand Up @@ -520,11 +521,11 @@ class ParamInfo:

def __init__(
self,
default: Union[Any, Callable[[ApplicationCommandInteraction], Any]] = ...,
default: Union[Any, Callable[[ApplicationCommandInteraction[BotT]], Any]] = ...,
*,
name: LocalizedOptional = None,
description: LocalizedOptional = None,
converter: Optional[Callable[[ApplicationCommandInteraction, Any], Any]] = None,
converter: Optional[Callable[[ApplicationCommandInteraction[BotT], Any], Any]] = None,
convert_default: bool = False,
autocomplete: Optional[AnyAutocompleter] = None,
choices: Optional[Choices] = None,
Expand Down Expand Up @@ -911,6 +912,7 @@ def isolate_self(
parametersl.pop(0)
if parametersl:
annot = parametersl[0].annotation
annot = get_origin(annot) or annot
if issubclass_(annot, ApplicationCommandInteraction) or annot is inspect.Parameter.empty:
inter_param = parameters.pop(parametersl[0].name)

Expand Down Expand Up @@ -982,7 +984,9 @@ def collect_params(
injections[parameter.name] = default
elif parameter.annotation in Injection._registered:
injections[parameter.name] = Injection._registered[parameter.annotation]
elif issubclass_(parameter.annotation, ApplicationCommandInteraction):
elif issubclass_(
get_origin(parameter.annotation) or parameter.annotation, ApplicationCommandInteraction
):
if inter_param is None:
inter_param = parameter
else:
Expand Down Expand Up @@ -1116,21 +1120,24 @@ def expand_params(command: AnySlashCommand) -> List[Option]:
if param.autocomplete:
command.autocompleters[param.name] = param.autocomplete

if issubclass_(sig.parameters[inter_param].annotation, disnake.GuildCommandInteraction):
if issubclass_(
get_origin(annot := sig.parameters[inter_param].annotation) or annot,
disnake.GuildCommandInteraction,
):
command._guild_only = True

return [param.to_option() for param in params]


def Param(
default: Union[Any, Callable[[ApplicationCommandInteraction], Any]] = ...,
default: Union[Any, Callable[[ApplicationCommandInteraction[BotT]], Any]] = ...,
*,
name: LocalizedOptional = None,
description: LocalizedOptional = None,
choices: Optional[Choices] = None,
converter: Optional[Callable[[ApplicationCommandInteraction, Any], Any]] = None,
converter: Optional[Callable[[ApplicationCommandInteraction[BotT], Any], Any]] = None,
convert_defaults: bool = False,
autocomplete: Optional[Callable[[ApplicationCommandInteraction, str], Any]] = None,
autocomplete: Optional[Callable[[ApplicationCommandInteraction[BotT], str], Any]] = None,
channel_types: Optional[List[ChannelType]] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
Expand Down
10 changes: 5 additions & 5 deletions disnake/interactions/application_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ..member import Member
from ..message import Message
from ..user import User
from .base import Interaction, InteractionDataResolved
from .base import ClientT, Interaction, InteractionDataResolved

__all__ = (
"ApplicationCommandInteraction",
Expand Down Expand Up @@ -41,7 +41,7 @@
)


class ApplicationCommandInteraction(Interaction):
class ApplicationCommandInteraction(Interaction[ClientT]):
"""Represents an interaction with an application command.
Current examples are slash commands, user commands and message commands.
Expand Down Expand Up @@ -119,7 +119,7 @@ def filled_options(self) -> Dict[str, Any]:
return kwargs


class GuildCommandInteraction(ApplicationCommandInteraction):
class GuildCommandInteraction(ApplicationCommandInteraction[ClientT]):
"""An :class:`ApplicationCommandInteraction` subclass, primarily meant for annotations.
This prevents the command from being invoked in DMs by automatically setting
Expand All @@ -137,7 +137,7 @@ class GuildCommandInteraction(ApplicationCommandInteraction):
me: Member


class UserCommandInteraction(ApplicationCommandInteraction):
class UserCommandInteraction(ApplicationCommandInteraction[ClientT]):
"""An :class:`ApplicationCommandInteraction` subclass meant for annotations.
No runtime behavior is changed but annotations are modified
Expand All @@ -147,7 +147,7 @@ class UserCommandInteraction(ApplicationCommandInteraction):
target: Union[User, Member]


class MessageCommandInteraction(ApplicationCommandInteraction):
class MessageCommandInteraction(ApplicationCommandInteraction[ClientT]):
"""An :class:`ApplicationCommandInteraction` subclass meant for annotations.
No runtime behavior is changed but annotations are modified
Expand Down
16 changes: 7 additions & 9 deletions disnake/interactions/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
TYPE_CHECKING,
Any,
Dict,
Generic,
List,
Mapping,
Optional,
Expand Down Expand Up @@ -95,9 +96,10 @@
MISSING: Any = utils.MISSING

T = TypeVar("T")
ClientT = TypeVar("ClientT", bound="Client", covariant=True)


class Interaction:
class Interaction(Generic[ClientT]):
"""A base class representing a user-initiated Discord interaction.
An interaction happens when a user performs an action that the client needs to
Expand Down Expand Up @@ -175,7 +177,7 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState) -> None:
self._state: ConnectionState = state
# TODO: Maybe use a unique session
self._session: ClientSession = state.http._HTTPClient__session # type: ignore
self.client: Client = state._get_client()
self.client: ClientT = cast(ClientT, state._get_client())
self._original_response: Optional[InteractionMessage] = None

self.id: int = int(data["id"])
Expand Down Expand Up @@ -208,13 +210,9 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState) -> None:
self.author = self._state.store_user(user)

@property
def bot(self) -> AnyBot:
""":class:`~disnake.ext.commands.Bot`: The bot handling the interaction.
Only applicable when used with :class:`~disnake.ext.commands.Bot`.
This is an alias for :attr:`.client`.
"""
return self.client # type: ignore
def bot(self) -> ClientT:
""":class:`~disnake.ext.commands.Bot`: An alias for :attr:`.client`."""
return self.client

@property
def created_at(self) -> datetime:
Expand Down
4 changes: 2 additions & 2 deletions disnake/interactions/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ..enums import ComponentType, try_enum
from ..message import Message
from ..utils import cached_slot_property
from .base import Interaction, InteractionDataResolved
from .base import ClientT, Interaction, InteractionDataResolved

__all__ = (
"MessageInteraction",
Expand All @@ -28,7 +28,7 @@
from .base import InteractionChannel


class MessageInteraction(Interaction):
class MessageInteraction(Interaction[ClientT]):
"""Represents an interaction with a message component.
Current examples are buttons and dropdowns.
Expand Down
4 changes: 2 additions & 2 deletions disnake/interactions/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from ..enums import ComponentType
from ..message import Message
from ..utils import cached_slot_property
from .base import Interaction
from .base import ClientT, Interaction

if TYPE_CHECKING:
from ..state import ConnectionState
Expand All @@ -21,7 +21,7 @@
__all__ = ("ModalInteraction", "ModalInteractionData")


class ModalInteraction(Interaction):
class ModalInteraction(Interaction[ClientT]):
"""Represents an interaction with a modal.
.. versionadded:: 2.4
Expand Down
3 changes: 3 additions & 0 deletions disnake/types/audit_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ class _AuditLogChange_AutoModTriggerMetadata(TypedDict):
]


# All of these are technically only required for matching event types,
# but they're typed as required keys for simplicity
class AuditEntryInfo(TypedDict):
delete_member_days: str
members_removed: str
Expand All @@ -312,6 +314,7 @@ class AuditEntryInfo(TypedDict):
application_id: Snowflake
auto_moderation_rule_name: str
auto_moderation_rule_trigger_type: str
integration_type: str


class AuditLogEntry(TypedDict):
Expand Down
5 changes: 4 additions & 1 deletion disnake/ui/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
if TYPE_CHECKING:
from typing_extensions import ParamSpec, Self

from ..client import Client
from ..components import NestedComponent
from ..enums import ComponentType
from ..interactions import MessageInteraction
Expand All @@ -35,6 +36,8 @@
else:
ParamSpec = TypeVar

ClientT = TypeVar("ClientT", bound="Client")


class WrappedComponent(ABC):
"""Represents the base UI component that all UI components inherit from.
Expand Down Expand Up @@ -142,7 +145,7 @@ def view(self) -> V_co:
"""Optional[:class:`View`]: The underlying view for this item."""
return self._view

async def callback(self, interaction: MessageInteraction, /) -> None:
async def callback(self, interaction: MessageInteraction[ClientT], /) -> None:
"""|coro|
The callback associated with this UI item.
Expand Down
9 changes: 6 additions & 3 deletions disnake/ui/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
import os
import sys
import traceback
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, TypeVar, Union

from ..enums import TextInputStyle
from ..utils import MISSING
from .action_row import ActionRow, components_to_rows
from .text_input import TextInput

if TYPE_CHECKING:
from ..client import Client
from ..interactions.modal import ModalInteraction
from ..state import ConnectionState
from ..types.components import Modal as ModalPayload
Expand All @@ -22,6 +23,8 @@

__all__ = ("Modal",)

ClientT = TypeVar("ClientT", bound="Client")


class Modal:
"""Represents a UI Modal.
Expand Down Expand Up @@ -156,7 +159,7 @@ def add_text_input(
)
)

async def callback(self, interaction: ModalInteraction, /) -> None:
async def callback(self, interaction: ModalInteraction[ClientT], /) -> None:
"""|coro|
The callback associated with this modal.
Expand All @@ -170,7 +173,7 @@ async def callback(self, interaction: ModalInteraction, /) -> None:
"""
pass

async def on_error(self, error: Exception, interaction: ModalInteraction) -> None:
async def on_error(self, error: Exception, interaction: ModalInteraction[ClientT]) -> None:
"""|coro|
A callback that is called when an error occurs.
Expand Down
6 changes: 3 additions & 3 deletions disnake/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,14 @@ def __init__(self, name: str, function: Callable[[T], T_co]) -> None:
self.__doc__ = function.__doc__

@overload
def __get__(self, instance: None, owner: Type[T]) -> Self:
def __get__(self, instance: None, owner: Type[Any]) -> Self:
...

@overload
def __get__(self, instance: T, owner: Type[T]) -> T_co:
def __get__(self, instance: T, owner: Type[Any]) -> T_co:
...

def __get__(self, instance: Optional[T], owner: Type[T]) -> Any:
def __get__(self, instance: Optional[T], owner: Type[Any]) -> Any:
if instance is None:
return self

Expand Down
10 changes: 10 additions & 0 deletions docs/api/audit_logs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,11 @@ AuditLogAction
the :class:`User` who got kicked. If the user is not found then it is
a :class:`Object` with the user's ID.

When this is the action, the type of :attr:`~AuditLogEntry.extra` may be
set to an unspecified proxy object with one attribute:

- ``integration_type``: A string representing the type of the integration which performed the action, if any.

When this is the action, :attr:`~AuditLogEntry.changes` is empty.

.. attribute:: member_prune
Expand Down Expand Up @@ -984,6 +989,11 @@ AuditLogAction
the :class:`Member` or :class:`User` who got the role. If the user is not found then it is
a :class:`Object` with the user's ID.

When this is the action, the type of :attr:`~AuditLogEntry.extra` may be
set to an unspecified proxy object with one attribute:

- ``integration_type``: A string representing the type of the integration which performed the action, if any.

Possible attributes for :class:`AuditLogDiff`:

- :attr:`~AuditLogDiff.roles`
Expand Down
Loading

0 comments on commit f641d2a

Please sign in to comment.