From 44cb10b09067e6fcbc4b6fea6ac5aa5e8a8b1356 Mon Sep 17 00:00:00 2001 From: shiftinv Date: Fri, 13 Dec 2024 21:42:15 +0100 Subject: [PATCH] refactor: "integration type" -> "install type" --- changelog/1173.feature.rst | 12 +-- disnake/app_commands.py | 100 +++++++++---------- disnake/appinfo.py | 48 ++++----- disnake/ext/commands/base_core.py | 46 ++++----- disnake/ext/commands/ctx_menus_core.py | 34 +++---- disnake/ext/commands/interaction_bot_base.py | 32 +++--- disnake/ext/commands/slash_core.py | 22 ++-- disnake/flags.py | 35 ++++--- disnake/interactions/application_command.py | 2 +- disnake/message.py | 2 +- disnake/types/interactions.py | 2 +- disnake/utils.py | 2 +- docs/api/app_commands.rst | 8 +- docs/api/app_info.rst | 8 +- docs/ext/commands/api/app_commands.rst | 2 +- docs/ext/commands/slash_commands.rst | 22 ++-- tests/ext/commands/test_base_core.py | 4 +- 17 files changed, 188 insertions(+), 193 deletions(-) diff --git a/changelog/1173.feature.rst b/changelog/1173.feature.rst index bbee9b160e..02268dbb8b 100644 --- a/changelog/1173.feature.rst +++ b/changelog/1173.feature.rst @@ -1,13 +1,13 @@ Add support for user-installed commands. See :ref:`app_command_contexts` for further details. -- Add :attr:`ApplicationCommand.integration_types` and :attr:`ApplicationCommand.contexts` fields, - with respective :class:`ApplicationIntegrationTypes` and :class:`InteractionContextTypes` flag types. +- Add :attr:`ApplicationCommand.install_types` and :attr:`ApplicationCommand.contexts` fields, + with respective :class:`ApplicationInstallTypes` and :class:`InteractionContextTypes` flag types. - :class:`Interaction` changes: - Add :attr:`Interaction.context` field, reflecting the context in which the interaction occurred. - Add :attr:`Interaction.authorizing_integration_owners` field and :class:`AuthorizingIntegrationOwners` class, containing details about the application installation. - :attr:`Interaction.app_permissions` is now always provided by Discord. - Add :attr:`Message.interaction_metadata` and :class:`InteractionMetadata` type, containing metadata for the interaction associated with a message. - Add ``integration_type`` parameter to :func:`utils.oauth_url`. -- Add :attr:`AppInfo.guild_integration_type_config` and :attr:`AppInfo.user_integration_type_config` fields. -- |commands| Add ``integration_types`` and ``contexts`` parameters to application command decorators. -- |commands| Add :func:`~ext.commands.integration_types` and :func:`~ext.commands.contexts` decorators. -- |commands| Using the :class:`GuildCommandInteraction` annotation now sets :attr:`~ApplicationCommand.integration_types` and :attr:`~ApplicationCommand.contexts`, instead of :attr:`~ApplicationCommand.dm_permission`. +- Add :attr:`AppInfo.guild_install_type_config` and :attr:`AppInfo.user_install_type_config` fields. +- |commands| Add ``install_types`` and ``contexts`` parameters to application command decorators. +- |commands| Add :func:`~ext.commands.install_types` and :func:`~ext.commands.contexts` decorators. +- |commands| Using the :class:`GuildCommandInteraction` annotation now sets :attr:`~ApplicationCommand.install_types` and :attr:`~ApplicationCommand.contexts`, instead of :attr:`~ApplicationCommand.dm_permission`. diff --git a/disnake/app_commands.py b/disnake/app_commands.py index 414c16ebba..cd6eb76ece 100644 --- a/disnake/app_commands.py +++ b/disnake/app_commands.py @@ -17,7 +17,7 @@ try_enum, try_enum_to_int, ) -from .flags import ApplicationIntegrationTypes, InteractionContextTypes +from .flags import ApplicationInstallTypes, InteractionContextTypes from .i18n import Localized from .permissions import Permissions from .utils import MISSING, _get_as_snowflake, _maybe_cast, deprecated, warn_deprecated @@ -492,9 +492,9 @@ class ApplicationCommand(ABC): # noqa: B024 # this will get refactored eventua .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -511,7 +511,7 @@ class ApplicationCommand(ABC): # noqa: B024 # this will get refactored eventua "name", "default_member_permissions", "nsfw", - "integration_types", + "install_types", "contexts", ) @@ -522,7 +522,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, ) -> None: self.type: ApplicationCommandType = enum_if_int(ApplicationCommandType, type) @@ -544,7 +544,7 @@ def __init__( self._default_member_permissions = default_member_permissions.value # note: this defaults to `[0]` for syncing purposes only - self.integration_types: Optional[ApplicationIntegrationTypes] = integration_types + self.install_types: Optional[ApplicationInstallTypes] = install_types self.contexts: Optional[InteractionContextTypes] = contexts self._always_synced: bool = False @@ -628,7 +628,7 @@ def __eq__(self, other) -> bool: if not any( (isinstance(obj, _APIApplicationCommandMixin) and obj.guild_id) for obj in (self, other) ): - if self._integration_types_with_default != other._integration_types_with_default: + if self._install_types_with_default != other._install_types_with_default: return False # `contexts` takes priority over `dm_permission`; @@ -645,18 +645,18 @@ def __eq__(self, other) -> bool: return True @property - def _integration_types_with_default(self) -> Optional[ApplicationIntegrationTypes]: + def _install_types_with_default(self) -> Optional[ApplicationInstallTypes]: # if this is an api-provided command object, keep things as-is - if self.integration_types is None and not isinstance(self, _APIApplicationCommandMixin): + if self.install_types is None and not isinstance(self, _APIApplicationCommandMixin): # The purpose of this default is to avoid re-syncing after the updating to the new version, # at least as long as the user hasn't enabled user installs in the dev portal # (i.e. if they haven't, the api defaults to this value as well). # Additionally, this provides consistency independent of the dev portal configuration, # even if it might not be ideal. - # In an ideal world, we would make use of `application_info().integration_types_config`. - return ApplicationIntegrationTypes(guild=True) + # In an ideal world, we would make use of `application_info().install_types_config`. + return ApplicationInstallTypes(guild=True) - return self.integration_types + return self.install_types def to_dict(self) -> EditApplicationCommandPayload: data: EditApplicationCommandPayload = { @@ -671,12 +671,12 @@ def to_dict(self) -> EditApplicationCommandPayload: "nsfw": self.nsfw, } - integration_types = ( - self._integration_types_with_default.values - if self._integration_types_with_default is not None + install_types = ( + self._install_types_with_default.values + if self._install_types_with_default is not None else None ) - data["integration_types"] = integration_types + data["integration_types"] = install_types contexts = self.contexts.values if self.contexts is not None else None data["contexts"] = contexts @@ -731,9 +731,9 @@ class UserCommand(ApplicationCommand): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -753,7 +753,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, ) -> None: super().__init__( @@ -762,7 +762,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) @@ -786,9 +786,9 @@ class APIUserCommand(UserCommand, _APIApplicationCommandMixin): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -821,9 +821,9 @@ def from_dict(cls, data: ApplicationCommandPayload) -> Self: name=Localized(data["name"], data=data.get("name_localizations")), default_member_permissions=_get_as_snowflake(data, "default_member_permissions"), nsfw=data.get("nsfw"), - integration_types=( - ApplicationIntegrationTypes._from_values(integration_types) - if (integration_types := data.get("integration_types")) is not None + install_types=( + ApplicationInstallTypes._from_values(install_types) + if (install_types := data.get("integration_types")) is not None else None ), contexts=( @@ -854,9 +854,9 @@ class MessageCommand(ApplicationCommand): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -876,7 +876,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, ) -> None: super().__init__( @@ -885,7 +885,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) @@ -909,9 +909,9 @@ class APIMessageCommand(MessageCommand, _APIApplicationCommandMixin): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -944,9 +944,9 @@ def from_dict(cls, data: ApplicationCommandPayload) -> Self: name=Localized(data["name"], data=data.get("name_localizations")), default_member_permissions=_get_as_snowflake(data, "default_member_permissions"), nsfw=data.get("nsfw"), - integration_types=( - ApplicationIntegrationTypes._from_values(integration_types) - if (integration_types := data.get("integration_types")) is not None + install_types=( + ApplicationInstallTypes._from_values(install_types) + if (install_types := data.get("integration_types")) is not None else None ), contexts=( @@ -984,9 +984,9 @@ class SlashCommand(ApplicationCommand): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -1014,7 +1014,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, ) -> None: super().__init__( @@ -1023,7 +1023,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) _validate_name(self.name) @@ -1123,9 +1123,9 @@ class APISlashCommand(SlashCommand, _APIApplicationCommandMixin): .. versionadded:: 2.8 - integration_types: Optional[:class:`ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`ApplicationInstallTypes.guild` only. Only available for global commands. .. versionadded:: 2.10 @@ -1164,9 +1164,9 @@ def from_dict(cls, data: ApplicationCommandPayload) -> Self: ), default_member_permissions=_get_as_snowflake(data, "default_member_permissions"), nsfw=data.get("nsfw"), - integration_types=( - ApplicationIntegrationTypes._from_values(integration_types) - if (integration_types := data.get("integration_types")) is not None + install_types=( + ApplicationInstallTypes._from_values(install_types) + if (install_types := data.get("integration_types")) is not None else None ), contexts=( diff --git a/disnake/appinfo.py b/disnake/appinfo.py index 0d4c082abe..0264c3df51 100644 --- a/disnake/appinfo.py +++ b/disnake/appinfo.py @@ -26,7 +26,7 @@ "AppInfo", "PartialAppInfo", "InstallParams", - "IntegrationTypeConfiguration", + "InstallTypeConfiguration", ) @@ -45,7 +45,7 @@ class InstallParams: __slots__ = ( "_app_id", - "_integration_type", + "_install_type", "scopes", "permissions", ) @@ -55,10 +55,10 @@ def __init__( data: InstallParamsPayload, parent: AppInfo, *, - integration_type: Optional[ApplicationIntegrationTypeLiteral] = None, + install_type: Optional[ApplicationIntegrationTypeLiteral] = None, ) -> None: self._app_id = parent.id - self._integration_type: Optional[ApplicationIntegrationTypeLiteral] = integration_type + self._install_type: Optional[ApplicationIntegrationTypeLiteral] = install_type self.scopes = data["scopes"] self.permissions = Permissions(int(data["permissions"])) @@ -78,20 +78,20 @@ def to_url(self) -> str: scopes=self.scopes, permissions=self.permissions, integration_type=( - self._integration_type if self._integration_type is not None else utils.MISSING + self._install_type if self._install_type is not None else utils.MISSING ), ) -class IntegrationTypeConfiguration: - """Represents the configuration for a particular application integration type. +class InstallTypeConfiguration: + """Represents the configuration for a particular application installation type. .. versionadded:: 2.10 Attributes ---------- install_params: Optional[:class:`InstallParams`] - The installation parameters for this integration type. + The parameters for this installation type. """ __slots__ = ("install_params",) @@ -101,10 +101,10 @@ def __init__( data: ApplicationIntegrationTypeConfigurationPayload, *, parent: AppInfo, - integration_type: ApplicationIntegrationTypeLiteral, + install_type: ApplicationIntegrationTypeLiteral, ) -> None: self.install_params: Optional[InstallParams] = ( - InstallParams(install_params, parent=parent, integration_type=integration_type) + InstallParams(install_params, parent=parent, install_type=install_type) if (install_params := data.get("oauth2_install_params")) else None ) @@ -183,8 +183,8 @@ class AppInfo: install_params: Optional[:class:`InstallParams`] The installation parameters for this application. - See also :attr:`guild_integration_type_config`/:attr:`user_integration_type_config` - for integration type-specific configuration. + See also :attr:`guild_install_type_config`/:attr:`user_install_type_config` + for installation type-specific configuration. .. versionadded:: 2.5 @@ -235,7 +235,7 @@ class AppInfo: "role_connections_verification_url", "approximate_guild_count", "approximate_user_install_count", - "_integration_types_config", + "_install_types_config", ) def __init__(self, state: ConnectionState, data: AppInfoPayload) -> None: @@ -281,15 +281,15 @@ def __init__(self, state: ConnectionState, data: AppInfoPayload) -> None: self.approximate_user_install_count: int = data.get("approximate_user_install_count", 0) # this is a bit of a mess, but there's no better way to expose this data for now - self._integration_types_config: Dict[ - ApplicationIntegrationTypeLiteral, IntegrationTypeConfiguration + self._install_types_config: Dict[ + ApplicationIntegrationTypeLiteral, InstallTypeConfiguration ] = {} for type_str, config in (data.get("integration_types_config") or {}).items(): - integration_type = cast("ApplicationIntegrationTypeLiteral", int(type_str)) - self._integration_types_config[integration_type] = IntegrationTypeConfiguration( + install_type = cast("ApplicationIntegrationTypeLiteral", int(type_str)) + self._install_types_config[install_type] = InstallTypeConfiguration( config or {}, parent=self, - integration_type=integration_type, + install_type=install_type, ) def __repr__(self) -> str: @@ -342,22 +342,22 @@ def summary(self) -> str: return self._summary @property - def guild_integration_type_config(self) -> Optional[IntegrationTypeConfiguration]: - """Optional[:class:`IntegrationTypeConfiguration`]: The guild installation parameters for + def guild_install_type_config(self) -> Optional[InstallTypeConfiguration]: + """Optional[:class:`InstallTypeConfiguration`]: The guild installation parameters for this application. If this application cannot be installed to guilds, returns ``None``. .. versionadded:: 2.10 """ - return self._integration_types_config.get(0) + return self._install_types_config.get(0) @property - def user_integration_type_config(self) -> Optional[IntegrationTypeConfiguration]: - """Optional[:class:`IntegrationTypeConfiguration`]: The user installation parameters for + def user_install_type_config(self) -> Optional[InstallTypeConfiguration]: + """Optional[:class:`InstallTypeConfiguration`]: The user installation parameters for this application. If this application cannot be installed to users, returns ``None``. .. versionadded:: 2.10 """ - return self._integration_types_config.get(1) + return self._install_types_config.get(1) class PartialAppInfo: diff --git a/disnake/ext/commands/base_core.py b/disnake/ext/commands/base_core.py index fa643f07eb..a7f75a6c71 100644 --- a/disnake/ext/commands/base_core.py +++ b/disnake/ext/commands/base_core.py @@ -22,7 +22,7 @@ from disnake.app_commands import ApplicationCommand from disnake.enums import ApplicationCommandType -from disnake.flags import ApplicationIntegrationTypes, InteractionContextTypes +from disnake.flags import ApplicationInstallTypes, InteractionContextTypes from disnake.permissions import Permissions from disnake.utils import _generated, _overload_with_permissions, async_all, maybe_coroutine @@ -53,7 +53,7 @@ __all__ = ( "InvokableApplicationCommand", "default_member_permissions", - "integration_types", + "install_types", "contexts", ) @@ -212,11 +212,11 @@ def _ensure_assignment_on_copy(self, other: AppCommandT) -> AppCommandT: other.body._default_member_permissions = self.body._default_member_permissions if ( - self.body.integration_types != other.body.integration_types - and self.body.integration_types is not None # see above + self.body.install_types != other.body.install_types + and self.body.install_types is not None # see above ): - other.body.integration_types = ApplicationIntegrationTypes._from_value( - self.body.integration_types.value + other.body.install_types = ApplicationInstallTypes._from_value( + self.body.install_types.value ) if ( @@ -253,13 +253,13 @@ def _update_copy(self: AppCommandT, kwargs: Dict[str, Any]) -> AppCommandT: return self.copy() def _apply_guild_only(self) -> None: - # If we have a `GuildCommandInteraction` annotation, set `contexts` and `integration_types` accordingly. + # If we have a `GuildCommandInteraction` annotation, set `contexts` and `install_types` accordingly. # This matches the old pre-user-apps behavior. if self._guild_only: # n.b. this overwrites any user-specified parameter # FIXME(3.0): this should raise if these were set elsewhere (except `*_command_attrs`) already self.body.contexts = InteractionContextTypes(guild=True) - self.body.integration_types = ApplicationIntegrationTypes(guild=True) + self.body.install_types = ApplicationInstallTypes(guild=True) @property def dm_permission(self) -> bool: @@ -283,13 +283,13 @@ def default_member_permissions(self) -> Optional[Permissions]: return self.body.default_member_permissions @property - def integration_types(self) -> Optional[ApplicationIntegrationTypes]: - """Optional[:class:`.ApplicationIntegrationTypes`]: The integration types/installation contexts + def install_types(self) -> Optional[ApplicationInstallTypes]: + """Optional[:class:`.ApplicationInstallTypes`]: The installation types where the command is available. Only available for global commands. .. versionadded:: 2.10 """ - return self.body.integration_types + return self.body.install_types @property def contexts(self) -> Optional[InteractionContextTypes]: @@ -816,11 +816,11 @@ def decorator(func: T) -> T: return decorator -def integration_types(*, guild: bool = False, user: bool = False) -> Callable[[T], T]: - """A decorator that sets the integration types/installation contexts where the +def install_types(*, guild: bool = False, user: bool = False) -> Callable[[T], T]: + """A decorator that sets the installation types where the application command is available. - See also the ``integration_types`` parameter for application command decorators. + See also the ``install_types`` parameter for application command decorators. .. note:: This does not work with slash subcommands/groups. @@ -830,28 +830,24 @@ def integration_types(*, guild: bool = False, user: bool = False) -> Callable[[T Parameters ---------- **params: bool - The integration types; see :class:`.ApplicationIntegrationTypes`. + The installation types; see :class:`.ApplicationInstallTypes`. Setting a parameter to ``False`` does not affect the result. """ def decorator(func: T) -> T: from .slash_core import SubCommand, SubCommandGroup - integration_types = ApplicationIntegrationTypes(guild=guild, user=user) + install_types = ApplicationInstallTypes(guild=guild, user=user) if isinstance(func, InvokableApplicationCommand): if isinstance(func, (SubCommand, SubCommandGroup)): - raise TypeError( - "Cannot set `integration_types` on subcommands or subcommand groups" - ) + raise TypeError("Cannot set `install_types` on subcommands or subcommand groups") # special case - don't overwrite if `_guild_only` was set, since that takes priority if not func._guild_only: - if func.body.integration_types is not None: - raise ValueError( - "Cannot set `integration_types` in both parameter and decorator" - ) - func.body.integration_types = integration_types + if func.body.install_types is not None: + raise ValueError("Cannot set `install_types` in both parameter and decorator") + func.body.install_types = install_types else: - func.__integration_types__ = integration_types # type: ignore + func.__install_types__ = install_types # type: ignore return func return decorator diff --git a/disnake/ext/commands/ctx_menus_core.py b/disnake/ext/commands/ctx_menus_core.py index 984357289d..b7ad876424 100644 --- a/disnake/ext/commands/ctx_menus_core.py +++ b/disnake/ext/commands/ctx_menus_core.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Sequence, Tuple, Union from disnake.app_commands import MessageCommand, UserCommand -from disnake.flags import ApplicationIntegrationTypes, InteractionContextTypes +from disnake.flags import ApplicationInstallTypes, InteractionContextTypes from disnake.i18n import Localized from disnake.permissions import Permissions @@ -77,7 +77,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -93,7 +93,7 @@ def __init__( except AttributeError: pass try: - integration_types = func.__integration_types__ + install_types = func.__install_types__ except AttributeError: pass try: @@ -106,7 +106,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) @@ -189,7 +189,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -205,7 +205,7 @@ def __init__( except AttributeError: pass try: - integration_types = func.__integration_types__ + install_types = func.__install_types__ except AttributeError: pass try: @@ -218,7 +218,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) @@ -261,7 +261,7 @@ def user_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -298,9 +298,9 @@ def user_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -349,7 +349,7 @@ def decorator( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, auto_sync=auto_sync, @@ -366,7 +366,7 @@ def message_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -406,9 +406,9 @@ def message_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -457,7 +457,7 @@ def decorator( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, auto_sync=auto_sync, diff --git a/disnake/ext/commands/interaction_bot_base.py b/disnake/ext/commands/interaction_bot_base.py index a8caed58c5..4e9f8698ea 100644 --- a/disnake/ext/commands/interaction_bot_base.py +++ b/disnake/ext/commands/interaction_bot_base.py @@ -28,7 +28,7 @@ from disnake.app_commands import ApplicationCommand, Option from disnake.custom_warnings import SyncWarning from disnake.enums import ApplicationCommandType -from disnake.flags import ApplicationIntegrationTypes, InteractionContextTypes +from disnake.flags import ApplicationInstallTypes, InteractionContextTypes from disnake.utils import warn_deprecated from . import errors @@ -490,7 +490,7 @@ def slash_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, options: Optional[List[Option]] = None, guild_ids: Optional[Sequence[int]] = None, @@ -539,9 +539,9 @@ def slash_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -589,7 +589,7 @@ def decorator(func: CommandCallback) -> InvokableSlashCommand: dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, connectors=connectors, @@ -609,7 +609,7 @@ def user_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -649,9 +649,9 @@ def user_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -693,7 +693,7 @@ def decorator( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, auto_sync=auto_sync, @@ -712,7 +712,7 @@ def message_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, auto_sync: Optional[bool] = None, @@ -752,9 +752,9 @@ def message_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -796,7 +796,7 @@ def decorator( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, auto_sync=auto_sync, diff --git a/disnake/ext/commands/slash_core.py b/disnake/ext/commands/slash_core.py index db94c27edc..a42e881391 100644 --- a/disnake/ext/commands/slash_core.py +++ b/disnake/ext/commands/slash_core.py @@ -20,7 +20,7 @@ from disnake import utils from disnake.app_commands import Option, SlashCommand from disnake.enums import OptionType -from disnake.flags import ApplicationIntegrationTypes, InteractionContextTypes +from disnake.flags import ApplicationInstallTypes, InteractionContextTypes from disnake.i18n import Localized from disnake.interactions import ApplicationCommandInteraction from disnake.permissions import Permissions @@ -99,7 +99,7 @@ async def _call_autocompleter( _INVALID_SUB_KWARGS = frozenset( - {"dm_permission", "default_member_permissions", "integration_types", "contexts"} + {"dm_permission", "default_member_permissions", "install_types", "contexts"} ) @@ -110,7 +110,7 @@ def _check_invalid_sub_kwargs(func: CommandCallback, kwargs: Dict[str, Any]) -> for decorator_key in [ "__default_member_permissions__", - "__integration_types__", + "__install_types__", "__contexts__", ]: if hasattr(func, decorator_key): @@ -446,7 +446,7 @@ def __init__( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, guild_ids: Optional[Sequence[int]] = None, connectors: Optional[Dict[str, str]] = None, @@ -473,7 +473,7 @@ def __init__( except AttributeError: pass try: - integration_types = func.__integration_types__ + install_types = func.__install_types__ except AttributeError: pass try: @@ -490,7 +490,7 @@ def __init__( dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, ) @@ -775,7 +775,7 @@ def slash_command( dm_permission: Optional[bool] = None, # deprecated default_member_permissions: Optional[Union[Permissions, int]] = None, nsfw: Optional[bool] = None, - integration_types: Optional[ApplicationIntegrationTypes] = None, + install_types: Optional[ApplicationInstallTypes] = None, contexts: Optional[InteractionContextTypes] = None, options: Optional[List[Option]] = None, guild_ids: Optional[Sequence[int]] = None, @@ -808,9 +808,9 @@ def slash_command( .. versionadded:: 2.8 - integration_types: Optional[:class:`.ApplicationIntegrationTypes`] - The integration types/installation contexts where the command is available. - Defaults to :attr:`.ApplicationIntegrationTypes.guild` only. + install_types: Optional[:class:`.ApplicationInstallTypes`] + The installation types where the command is available. + Defaults to :attr:`.ApplicationInstallTypes.guild` only. Only available for global commands. See :ref:`app_command_contexts` for details. @@ -880,7 +880,7 @@ def decorator(func: CommandCallback) -> InvokableSlashCommand: dm_permission=dm_permission, default_member_permissions=default_member_permissions, nsfw=nsfw, - integration_types=integration_types, + install_types=install_types, contexts=contexts, guild_ids=guild_ids, connectors=connectors, diff --git a/disnake/flags.py b/disnake/flags.py index 270f3f205d..5117f7b80b 100644 --- a/disnake/flags.py +++ b/disnake/flags.py @@ -43,7 +43,7 @@ "RoleFlags", "AttachmentFlags", "SKUFlags", - "ApplicationIntegrationTypes", + "ApplicationInstallTypes", "InteractionContextTypes", ) @@ -2699,8 +2699,7 @@ def user_subscription(self): return 1 << 8 -# TODO: rename to just `IntegrationTypes`? -class ApplicationIntegrationTypes(ListBaseFlags): +class ApplicationInstallTypes(ListBaseFlags): """Represents the location(s) in which an application or application command can be installed. See the :ddocs:`official documentation ` for more info. @@ -2709,37 +2708,37 @@ class ApplicationIntegrationTypes(ListBaseFlags): .. describe:: x == y - Checks if two ApplicationIntegrationTypes instances are equal. + Checks if two ApplicationInstallTypes instances are equal. .. describe:: x != y - Checks if two ApplicationIntegrationTypes instances are not equal. + Checks if two ApplicationInstallTypes instances are not equal. .. describe:: x <= y - Checks if an ApplicationIntegrationTypes instance is a subset of another ApplicationIntegrationTypes instance. + Checks if an ApplicationInstallTypes instance is a subset of another ApplicationInstallTypes instance. .. describe:: x >= y - Checks if an ApplicationIntegrationTypes instance is a superset of another ApplicationIntegrationTypes instance. + Checks if an ApplicationInstallTypes instance is a superset of another ApplicationInstallTypes instance. .. describe:: x < y - Checks if an ApplicationIntegrationTypes instance is a strict subset of another ApplicationIntegrationTypes instance. + Checks if an ApplicationInstallTypes instance is a strict subset of another ApplicationInstallTypes instance. .. describe:: x > y - Checks if an ApplicationIntegrationTypes instance is a strict superset of another ApplicationIntegrationTypes instance. + Checks if an ApplicationInstallTypes instance is a strict superset of another ApplicationInstallTypes instance. .. describe:: x | y, x |= y - Returns a new ApplicationIntegrationTypes instance with all enabled flags from both x and y. + Returns a new ApplicationInstallTypes instance with all enabled flags from both x and y. (Using ``|=`` will update in place). .. describe:: x & y, x &= y - Returns a new ApplicationIntegrationTypes instance with only flags enabled on both x and y. + Returns a new ApplicationInstallTypes instance with only flags enabled on both x and y. (Using ``&=`` will update in place). .. describe:: x ^ y, x ^= y - Returns a new ApplicationIntegrationTypes instance with only flags enabled on one of x or y, but not both. + Returns a new ApplicationInstallTypes instance with only flags enabled on one of x or y, but not both. (Using ``^=`` will update in place). .. describe:: ~x - Returns a new ApplicationIntegrationTypes instance with all flags from x inverted. + Returns a new ApplicationInstallTypes instance with all flags from x inverted. .. describe:: hash(x) Returns the flag's hash. @@ -2751,13 +2750,13 @@ class ApplicationIntegrationTypes(ListBaseFlags): Additionally supported are a few operations on class attributes. - .. describe:: ApplicationIntegrationTypes.y | ApplicationIntegrationTypes.z, ApplicationIntegrationTypes(y=True) | ApplicationIntegrationTypes.z + .. describe:: ApplicationInstallTypes.y | ApplicationInstallTypes.z, ApplicationInstallTypes(y=True) | ApplicationInstallTypes.z - Returns an ApplicationIntegrationTypes instance with all provided flags enabled. + Returns an ApplicationInstallTypes instance with all provided flags enabled. - .. describe:: ~ApplicationIntegrationTypes.y + .. describe:: ~ApplicationInstallTypes.y - Returns an ApplicationIntegrationTypes instance with all flags except ``y`` inverted from their default value. + Returns an ApplicationInstallTypes instance with all flags except ``y`` inverted from their default value. .. versionadded:: 2.10 @@ -2778,7 +2777,7 @@ def __init__(self, *, guild: bool = ..., user: bool = ...) -> None: @classmethod def all(cls) -> Self: - """A factory method that creates an :class:`ApplicationIntegrationTypes` instance with everything enabled.""" + """A factory method that creates an :class:`ApplicationInstallTypes` instance with everything enabled.""" self = cls.__new__(cls) self.value = all_flags_value(cls.VALID_FLAGS) return self diff --git a/disnake/interactions/application_command.py b/disnake/interactions/application_command.py index 7e4c1bfa22..2148d7df9c 100644 --- a/disnake/interactions/application_command.py +++ b/disnake/interactions/application_command.py @@ -161,7 +161,7 @@ class GuildCommandInteraction(ApplicationCommandInteraction[ClientT]): This restricts the command to only be usable in guilds and only as a guild-installed command, by automatically setting :attr:`ApplicationCommand.contexts` to :attr:`~InteractionContextTypes.guild` only - and :attr:`ApplicationCommand.integration_types` to :attr:`~ApplicationIntegrationTypes.guild` only. + and :attr:`ApplicationCommand.install_types` to :attr:`~ApplicationInstallTypes.guild` only. Note that this does not apply to slash subcommands, subcommand groups, or autocomplete callbacks. Additionally, the type annotations of :attr:`~Interaction.author`, :attr:`~Interaction.guild`, diff --git a/disnake/message.py b/disnake/message.py index c8020ea398..efe965ae13 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -898,7 +898,7 @@ class AuthorizingIntegrationOwners: __slots__ = ("guild_id", "user_id") def __init__(self, data: AuthorizingIntegrationOwnersPayload) -> None: - # keys are stringified ApplicationIntegrationTypes + # keys are stringified ApplicationInstallTypes self.guild_id: Optional[int] = _get_as_snowflake(data, "0") self.user_id: Optional[int] = _get_as_snowflake(data, "1") diff --git a/disnake/types/interactions.py b/disnake/types/interactions.py index 719cc12f23..12833beffd 100644 --- a/disnake/types/interactions.py +++ b/disnake/types/interactions.py @@ -255,7 +255,7 @@ class ModalInteractionData(TypedDict): ## Interactions -# keys are stringified ApplicationIntegrationType's +# keys are stringified ApplicationInstallType's AuthorizingIntegrationOwners = Dict[str, Snowflake] diff --git a/disnake/utils.py b/disnake/utils.py index 96c83dfd77..1cbd012344 100644 --- a/disnake/utils.py +++ b/disnake/utils.py @@ -329,7 +329,7 @@ def oauth_url( .. versionadded:: 2.0 integration_type: :class:`int` - An optional integration type/installation context to install the application in. + An optional integration type/installation type to install the application with. .. versionadded:: 2.10 diff --git a/docs/api/app_commands.rst b/docs/api/app_commands.rst index 38f843ae9f..e49bc47ebf 100644 --- a/docs/api/app_commands.rst +++ b/docs/api/app_commands.rst @@ -108,12 +108,12 @@ OptionChoice .. autoclass:: OptionChoice() :members: -ApplicationIntegrationTypes -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ApplicationInstallTypes +~~~~~~~~~~~~~~~~~~~~~~~ -.. attributetable:: ApplicationIntegrationTypes +.. attributetable:: ApplicationInstallTypes -.. autoclass:: ApplicationIntegrationTypes() +.. autoclass:: ApplicationInstallTypes() :members: InteractionContextTypes diff --git a/docs/api/app_info.rst b/docs/api/app_info.rst index 48dc898c13..3b10b6c553 100644 --- a/docs/api/app_info.rst +++ b/docs/api/app_info.rst @@ -34,12 +34,12 @@ InstallParams .. autoclass:: InstallParams() :members: -IntegrationTypeConfiguration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +InstallTypeConfiguration +~~~~~~~~~~~~~~~~~~~~~~~~ -.. attributetable:: IntegrationTypeConfiguration +.. attributetable:: InstallTypeConfiguration -.. autoclass:: IntegrationTypeConfiguration() +.. autoclass:: InstallTypeConfiguration() :members: Team diff --git a/docs/ext/commands/api/app_commands.rst b/docs/ext/commands/api/app_commands.rst index 095461c343..5db8fbe3a7 100644 --- a/docs/ext/commands/api/app_commands.rst +++ b/docs/ext/commands/api/app_commands.rst @@ -202,7 +202,7 @@ Functions .. autofunction:: default_member_permissions :decorator: -.. autofunction:: integration_types +.. autofunction:: install_types :decorator: .. autofunction:: contexts diff --git a/docs/ext/commands/slash_commands.rst b/docs/ext/commands/slash_commands.rst index e7db584022..ad3e681e46 100644 --- a/docs/ext/commands/slash_commands.rst +++ b/docs/ext/commands/slash_commands.rst @@ -677,17 +677,17 @@ Yet again, with a file like ``locale/de.json`` containing localizations like thi Installation/Interaction Contexts --------------------------------- -The :attr:`~ApplicationCommand.integration_types` and :attr:`~ApplicationCommand.contexts` command +The :attr:`~ApplicationCommand.install_types` and :attr:`~ApplicationCommand.contexts` command attributes allow you to control how and where your command can be run. .. note:: These fields cannot be configured for a slash subcommand or subcommand group, only in top-level slash commands and user/message commands. -Integration Types -+++++++++++++++++ +Install Types ++++++++++++++ -The :attr:`~ApplicationCommand.integration_types` field determines whether your command can be used +The :attr:`~ApplicationCommand.install_types` field determines whether your command can be used when the bot is installed to a guild, a user, or both. Bots installed to a **guild** are visible to *all members*, which used to be the only entry point for users @@ -695,18 +695,18 @@ to run commands. Alternatively, bots can now also support being installed to a * the commands available everywhere to the *authorizing user* only. For instance, to make a command only available in a user-installed context, you can -use the :func:`~.ext.commands.integration_types` decorator: +use the :func:`~.ext.commands.install_types` decorator: .. code-block:: python3 @bot.slash_command() - @commands.integration_types(user=True) + @commands.install_types(user=True) async def command(inter: disnake.ApplicationCommandInteraction): ... -Alternatively, you may pass e.g. ``integration_types=disnake.ApplicationIntegrationTypes(user=True)`` -as an argument directly to the command decorator. To allow all (guild + user) installation contexts, -a :meth:`ApplicationIntegrationTypes.all` shorthand is also available. +Alternatively, you may pass e.g. ``install_types=disnake.ApplicationInstallTypes(user=True)`` +as an argument directly to the command decorator. To allow all (guild + user) installation types, +a :meth:`ApplicationInstallTypes.all` shorthand is also available. By default, commands are set to only be usable in guild-installed contexts. @@ -717,7 +717,7 @@ By default, commands are set to only be usable in guild-installed contexts. Contexts ++++++++ -While ``integration_types`` determines where the bot must be *installed* to run a command, +While ``install_types`` determines where the bot must be *installed* to run a command, :attr:`~ApplicationCommand.contexts` dictates where *in Discord* a command can be used. Possible surfaces are **guilds**, **DMs with the bot**, and **DMs (and group DMs) between other users**, @@ -726,7 +726,7 @@ or :attr:`~InteractionContextTypes.private_channel` respectively to ``True``. The :attr:`~InteractionContextTypes.private_channel` context is only meaningful for user-installed commands. -Similarly to ``integration_types``, this can be accomplished using the :func:`~.ext.commands.contexts` +Similarly to ``install_types``, this can be accomplished using the :func:`~.ext.commands.contexts` decorator, to e.g. disallow a command in guilds: .. code-block:: python3 diff --git a/tests/ext/commands/test_base_core.py b/tests/ext/commands/test_base_core.py index e350de3800..c8335dd70a 100644 --- a/tests/ext/commands/test_base_core.py +++ b/tests/ext/commands/test_base_core.py @@ -107,7 +107,7 @@ def test_contexts_guildcommandinteraction(meta: DecoratorMeta) -> None: class Cog(commands.Cog): # this shouldn't raise, it should be silently ignored @commands.contexts(bot_dm=True) - @commands.integration_types(user=True) + @commands.install_types(user=True) # this is a legacy parameter, essentially the same as using `GuildCommandInteraction` @meta.decorator(guild_only=True) async def cmd(self, _) -> None: @@ -115,7 +115,7 @@ async def cmd(self, _) -> None: for c in (Cog, Cog()): assert c.cmd.contexts == disnake.InteractionContextTypes(guild=True) - assert c.cmd.integration_types == disnake.ApplicationIntegrationTypes(guild=True) + assert c.cmd.install_types == disnake.ApplicationInstallTypes(guild=True) def test_localization_copy() -> None: