From e5aafe455455a554b3904f8fd1ce8d8a49c11900 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Sun, 11 Jun 2023 01:34:48 +0530 Subject: [PATCH 01/15] fix: `KeyError` in `EmbedMedia` (#2109) * fix `KeyError` * Typehints and `proxy_url` --- discord/embeds.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/discord/embeds.py b/discord/embeds.py index b7037dd349..fb34acc33f 100644 --- a/discord/embeds.py +++ b/discord/embeds.py @@ -173,16 +173,18 @@ class EmbedMedia: # Thumbnail, Image, Video url: str proxy_url: str | None - height: int - width: int + height: int | None + width: int | None @classmethod def from_dict(cls, data: dict[str, str | int]) -> EmbedMedia: self = cls.__new__(cls) self.url = str(data.get("url")) - self.proxy_url = str(data.get("proxy_url")) - self.height = int(data["height"]) - self.width = int(data["width"]) + self.proxy_url = ( + str(proxy_url) if (proxy_url := data.get("proxy_url")) else None + ) + self.height = int(height) if (height := data.get("height")) else None + self.width = int(width) if (width := data.get("width")) else None return self def __repr__(self) -> str: From 50281e645c057423b4de750f6e49c83fad09b9de Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Mon, 12 Jun 2023 04:45:32 +0530 Subject: [PATCH 02/15] feat(ext.bridge): add `bridge.Context` as a Union class (#2106) * add `bridge.Context` * style(pre-commit): auto fixes from pre-commit.com hooks * docs and changelog * Improve docs * style(pre-commit): auto fixes from pre-commit.com hooks * change docs declaration from `class` to `data` --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: plun1331 <49261529+plun1331@users.noreply.github.com> --- CHANGELOG.md | 2 ++ discord/ext/bridge/context.py | 11 +++++++++-- docs/ext/bridge/api.rst | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c94cf00022..88bf77570b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2086](https://github.com/Pycord-Development/pycord/pull/2086)) - Added new embedded activities, Gartic Phone and Jamspace. ([#2102](https://github.com/Pycord-Development/pycord/pull/2102)) +- Added `bridge.Context` as a shortcut to `Union` of subclasses. + ([#2106](https://github.com/Pycord-Development/pycord/pull/2106)) ### Changed diff --git a/discord/ext/bridge/context.py b/discord/ext/bridge/context.py index 3ba5989886..033fdd6caf 100644 --- a/discord/ext/bridge/context.py +++ b/discord/ext/bridge/context.py @@ -25,7 +25,7 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, overload +from typing import TYPE_CHECKING, Any, Union, overload from discord.commands import ApplicationContext from discord.interactions import Interaction, InteractionMessage @@ -38,7 +38,7 @@ from .core import BridgeExtCommand, BridgeSlashCommand -__all__ = ("BridgeContext", "BridgeExtContext", "BridgeApplicationContext") +__all__ = ("BridgeContext", "BridgeExtContext", "BridgeApplicationContext", "Context") class BridgeContext(ABC): @@ -195,3 +195,10 @@ async def delete( """ if self._original_response_message: await self._original_response_message.delete(delay=delay, reason=reason) + + +Context = Union[BridgeExtContext, BridgeApplicationContext] +""" +A Union class for either :class:`BridgeExtContext` or :class:`BridgeApplicationContext`. +Can be used as a type hint for Context for bridge commands. +""" diff --git a/docs/ext/bridge/api.rst b/docs/ext/bridge/api.rst index 327e6600fb..d8f4d78821 100644 --- a/docs/ext/bridge/api.rst +++ b/docs/ext/bridge/api.rst @@ -151,3 +151,9 @@ BridgeContext Subclasses .. autoclass:: discord.ext.bridge.BridgeExtContext :members: + +.. attributetable:: discord.ext.bridge.Context + +.. data:: discord.ext.bridge.Context + + Alias of :data:`typing.Union` [ :class:`.BridgeExtContext`, :class:`.BridgeApplicationContext` ] for typing convenience. From 17987c7f9f09cd83a7db35b616596f6eb9b27e10 Mon Sep 17 00:00:00 2001 From: UK <41271523+NeloBlivion@users.noreply.github.com> Date: Mon, 12 Jun 2023 14:36:45 +0100 Subject: [PATCH 03/15] fix: Flags again... (#2111) Theoretical final fix for flags with MISSING --- discord/ext/commands/flags.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/discord/ext/commands/flags.py b/discord/ext/commands/flags.py index 0848a831a1..54e7e0c37c 100644 --- a/discord/ext/commands/flags.py +++ b/discord/ext/commands/flags.py @@ -33,6 +33,11 @@ from discord.utils import MISSING, MissingField, maybe_coroutine, resolve_annotation +if sys.version_info >= (3, 11): + _MISSING = MissingField +else: + _MISSING = MISSING + from .converter import run_converters from .errors import ( BadFlagArgument, @@ -81,13 +86,13 @@ class Flag: Whether multiple given values overrides the previous value. """ - name: str = MISSING + name: str = _MISSING aliases: list[str] = field(default_factory=list) - attribute: str = MISSING - annotation: Any = MISSING - default: Any = MISSING - max_args: int = MISSING - override: bool = MISSING + attribute: str = _MISSING + annotation: Any = _MISSING + default: Any = _MISSING + max_args: int = _MISSING + override: bool = _MISSING cast_to_dict: bool = False @property From 3021603723a4af6ca3398602902d70e0b60fc754 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 03:48:20 +0000 Subject: [PATCH 04/15] chore(deps-dev): Update pytest requirement from ~=7.3.1 to ~=7.3.2 (#2118) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.3.1...7.3.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 5be4239173..bb9bc2ecd0 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,6 @@ -r _.txt pylint~=2.17.4 -pytest~=7.3.1 +pytest~=7.3.2 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.3.0 From 763b14af1194001a4624056d5fba5c3ca2ad6a7b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:51:36 +0000 Subject: [PATCH 05/15] chore(pre-commit): pre-commit autoupdate (#2117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(pre-commit): pre-commit autoupdate updates: - [github.com/asottile/pyupgrade: v3.4.0 → v3.6.0](https://github.com/asottile/pyupgrade/compare/v3.4.0...v3.6.0) * style(pre-commit): auto fixes from pre-commit.com hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- discord/channel.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae3d79b71d..1c51f465bd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: # - --remove-duplicate-keys # - --remove-unused-variables - repo: https://github.com/asottile/pyupgrade - rev: v3.4.0 + rev: v3.6.0 hooks: - id: pyupgrade args: [--py38-plus] diff --git a/discord/channel.py b/discord/channel.py index 9a2e931eba..076b2c704f 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -751,7 +751,7 @@ def _repr_attrs(self) -> tuple[str, ...]: def _update(self, guild: Guild, data: TextChannelPayload) -> None: super()._update(guild, data) - async def _get_channel(self) -> "TextChannel": + async def _get_channel(self) -> TextChannel: return self def is_news(self) -> bool: @@ -1064,11 +1064,11 @@ async def edit( available_tags: list[ForumTag] = ..., require_tag: bool = ..., overwrites: Mapping[Role | Member | Snowflake, PermissionOverwrite] = ..., - ) -> "ForumChannel" | None: + ) -> ForumChannel | None: ... @overload - async def edit(self) -> "ForumChannel" | None: + async def edit(self) -> ForumChannel | None: ... async def edit(self, *, reason=None, **options): From af22f84e12dd61229d4c34a3c65f3b3b9b2d8d24 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Wed, 14 Jun 2023 07:53:16 +0530 Subject: [PATCH 06/15] feat: Add `cooldown` and `max_concurrency` to `SlashCommandGroup` (#2091) Signed-off-by: Om <92863779+Om1609@users.noreply.github.com> Co-authored-by: Lala Sabathil Co-authored-by: Middledot <78228142+Middledot@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 4 ++++ discord/commands/core.py | 51 +++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88bf77570b..946ca1905a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2042](https://github.com/Pycord-Development/pycord/pull/2042)) - Added `icon` and `unicode_emoji` to `Guild.create_role`. ([#2086](https://github.com/Pycord-Development/pycord/pull/2086)) +- Added `cooldown` and `max_concurrency` to `SlashCommandGroup`. + ([#2091](https://github.com/Pycord-Development/pycord/pull/2091)) - Added new embedded activities, Gartic Phone and Jamspace. ([#2102](https://github.com/Pycord-Development/pycord/pull/2102)) - Added `bridge.Context` as a shortcut to `Union` of subclasses. @@ -131,6 +133,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2079](https://github.com/Pycord-Development/pycord/pull/2079)) - Fixed `HTTPException` when trying to create a forum thread with files. ([#2075](https://github.com/Pycord-Development/pycord/pull/2075)) +- Fixed `before_invoke` not being run for `SlashCommandGroup`. + ([#2091](https://github.com/Pycord-Development/pycord/pull/2091)) - Fixed `AttributeError` when accessing a `Select`'s values when it hasn't been interacted with. ([#2104](https://github.com/Pycord-Development/pycord/pull/2104)) diff --git a/discord/commands/core.py b/discord/commands/core.py index 90a614a786..3f0018f88f 100644 --- a/discord/commands/core.py +++ b/discord/commands/core.py @@ -84,6 +84,7 @@ from .. import Permissions from ..cog import Cog + from ..ext.commands.cooldowns import CooldownMapping, MaxConcurrency T = TypeVar("T") CogT = TypeVar("CogT", bound="Cog") @@ -294,18 +295,17 @@ async def prepare(self, ctx: ApplicationContext) -> None: f"The check functions for the command {self.name} failed" ) - if hasattr(self, "_max_concurrency"): - if self._max_concurrency is not None: - # For this application, context can be duck-typed as a Message - await self._max_concurrency.acquire(ctx) # type: ignore # ctx instead of non-existent message + if self._max_concurrency is not None: + # For this application, context can be duck-typed as a Message + await self._max_concurrency.acquire(ctx) # type: ignore # ctx instead of non-existent message - try: - self._prepare_cooldowns(ctx) - await self.call_before_hooks(ctx) - except: - if self._max_concurrency is not None: - await self._max_concurrency.release(ctx) # type: ignore # ctx instead of non-existent message - raise + try: + self._prepare_cooldowns(ctx) + await self.call_before_hooks(ctx) + except: + if self._max_concurrency is not None: + await self._max_concurrency.release(ctx) # type: ignore # ctx instead of non-existent message + raise def is_on_cooldown(self, ctx: ApplicationContext) -> bool: """Checks whether the command is currently on cooldown. @@ -1119,6 +1119,8 @@ def __init__( description: str | None = None, guild_ids: list[int] | None = None, parent: SlashCommandGroup | None = None, + cooldown: CooldownMapping | None = None, + max_concurrency: MaxConcurrency | None = None, **kwargs, ) -> None: self.name = str(name) @@ -1153,6 +1155,33 @@ def __init__( "description_localizations", MISSING ) + # similar to ApplicationCommand + from ..ext.commands.cooldowns import BucketType, CooldownMapping, MaxConcurrency + + # no need to getattr, since slash cmds groups cant be created using a decorator + + if cooldown is None: + buckets = CooldownMapping(cooldown, BucketType.default) + elif isinstance(cooldown, CooldownMapping): + buckets = cooldown + else: + raise TypeError( + "Cooldown must be a an instance of CooldownMapping or None." + ) + + self._buckets: CooldownMapping = buckets + + # no need to getattr, since slash cmds groups cant be created using a decorator + + if max_concurrency is not None and not isinstance( + max_concurrency, MaxConcurrency + ): + raise TypeError( + "max_concurrency must be an instance of MaxConcurrency or None" + ) + + self._max_concurrency: MaxConcurrency | None = max_concurrency + @property def module(self) -> str | None: return self.__module__ From d862b7528a5811135ec4bffd6f4d53bf93197568 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 23:26:38 +0000 Subject: [PATCH 07/15] chore(deps-dev): Bump pre-commit from 3.3.2 to 3.3.3 (#2121) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index bb9bc2ecd0..39791e736c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -5,7 +5,7 @@ pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.3.0 coverage~=7.2 -pre-commit==3.3.2 +pre-commit==3.3.3 codespell==2.2.4 bandit==1.7.5 flake8==6.0.0 From 715a3f50a3dd83e143bd08cbb7993c4e4b93ed25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 23:38:32 +0000 Subject: [PATCH 08/15] chore(deps-dev): Bump codespell from 2.2.4 to 2.2.5 (#2122) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 39791e736c..b51e52c143 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -6,6 +6,6 @@ pytest-asyncio~=0.21.0 mypy~=1.3.0 coverage~=7.2 pre-commit==3.3.3 -codespell==2.2.4 +codespell==2.2.5 bandit==1.7.5 flake8==6.0.0 From d894a586e1660ed50692880f77c8097a16de552f Mon Sep 17 00:00:00 2001 From: Amelia Froemming <7919407+afroemming@users.noreply.github.com> Date: Wed, 14 Jun 2023 20:30:40 -0500 Subject: [PATCH 09/15] feat: handle typing.Annotated form annotations in slash commands option parser. (#2124) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- CHANGELOG.md | 2 + discord/commands/core.py | 18 +++++++ tests/test_typing_annotated.py | 86 ++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 tests/test_typing_annotated.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 946ca1905a..cb7bb88942 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2102](https://github.com/Pycord-Development/pycord/pull/2102)) - Added `bridge.Context` as a shortcut to `Union` of subclasses. ([#2106](https://github.com/Pycord-Development/pycord/pull/2106)) +- Added Annotated forms support for typehinting slash command options. + ([#2124](https://github.com/Pycord-Development/pycord/pull/2124)) ### Changed diff --git a/discord/commands/core.py b/discord/commands/core.py index 3f0018f88f..08649c2827 100644 --- a/discord/commands/core.py +++ b/discord/commands/core.py @@ -44,6 +44,8 @@ Union, ) +from typing_extensions import Annotated, get_args, get_origin + from ..channel import _threaded_guild_channel_factory from ..enums import Enum as DiscordEnum from ..enums import MessageType, SlashCommandOptionType, try_enum @@ -732,6 +734,19 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]: if option == inspect.Parameter.empty: option = str + if self._is_typing_annotated(option): + type_hint = get_args(option)[0] + metadata = option.__metadata__ + # If multiple Options in metadata, the first will be used. + option_gen = (elem for elem in metadata if isinstance(elem, Option)) + option = next(option_gen, Option()) + # Handle Optional + if self._is_typing_optional(type_hint): + option.input_type = get_args(type_hint)[0] + option.default = None + else: + option.input_type = type_hint + if self._is_typing_union(option): if self._is_typing_optional(option): option = Option(option.__args__[0], default=None) @@ -820,6 +835,9 @@ def _is_typing_union(self, annotation): def _is_typing_optional(self, annotation): return self._is_typing_union(annotation) and type(None) in annotation.__args__ # type: ignore + def _is_typing_annotated(self, annotation): + return get_origin(annotation) is Annotated + @property def cog(self): return getattr(self, "_cog", MISSING) diff --git a/tests/test_typing_annotated.py b/tests/test_typing_annotated.py new file mode 100644 index 0000000000..582bd4f8a0 --- /dev/null +++ b/tests/test_typing_annotated.py @@ -0,0 +1,86 @@ +from typing import Optional + +import pytest +from typing_extensions import Annotated + +import discord +from discord import ApplicationContext +from discord.commands.core import SlashCommand, slash_command + + +def test_typing_annotated(): + async def echo(ctx, txt: Annotated[str, discord.Option()]): + await ctx.respond(txt) + + cmd = SlashCommand(echo) + bot = discord.Bot() + bot.add_application_command(cmd) + + +def test_typing_annotated_decorator(): + bot = discord.Bot() + + @bot.slash_command() + async def echo(ctx, txt: Annotated[str, discord.Option(description="Some text")]): + await ctx.respond(txt) + + +def test_typing_annotated_cog(): + class echoCog(discord.Cog): + def __init__(self, bot_) -> None: + self.bot = bot_ + super().__init__() + + @slash_command() + async def echo( + self, ctx, txt: Annotated[str, discord.Option(description="Some text")] + ): + await ctx.respond(txt) + + bot = discord.Bot() + bot.add_cog(echoCog(bot)) + + +def test_typing_annotated_cog_slashgroup(): + class echoCog(discord.Cog): + grp = discord.commands.SlashCommandGroup("echo") + + def __init__(self, bot_) -> None: + self.bot = bot_ + super().__init__() + + @grp.command() + async def echo( + self, ctx, txt: Annotated[str, discord.Option(description="Some text")] + ): + await ctx.respond(txt) + + bot = discord.Bot() + bot.add_cog(echoCog(bot)) + + +def test_typing_annotated_optional(): + async def echo(ctx, txt: Annotated[Optional[str], discord.Option()]): + await ctx.respond(txt) + + cmd = SlashCommand(echo) + bot = discord.Bot() + bot.add_application_command(cmd) + + +def test_no_annotation(): + async def echo(ctx, txt: str): + await ctx.respond(txt) + + cmd = SlashCommand(echo) + bot = discord.Bot() + bot.add_application_command(cmd) + + +def test_annotated_no_option(): + async def echo(ctx, txt: Annotated[str, "..."]): + await ctx.respond(txt) + + cmd = SlashCommand(echo) + bot = discord.Bot() + bot.add_application_command(cmd) From ca2f5da1f6918583767a8978c6393a1253fa59c7 Mon Sep 17 00:00:00 2001 From: Amelia Froemming <7919407+afroemming@users.noreply.github.com> Date: Fri, 16 Jun 2023 09:43:08 -0500 Subject: [PATCH 10/15] fix: Correct regression from pull #2124 (#2126) Pycord requires typing_extensions as a dependency for python < 3.11, however not on version >= 3.11. Because the changes in the referenced pull always tries to load from typing_extensions, they make it so an exception will be raised if the end user is using python >= 3.11 and does not otherwise have that library installed when _parse_options is run (ie, whenever a command is registered). This change checks the version of python running Pycord, then imports stdlib typing if >= 3.11. --- discord/commands/core.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/discord/commands/core.py b/discord/commands/core.py index 08649c2827..09222ab72b 100644 --- a/discord/commands/core.py +++ b/discord/commands/core.py @@ -30,6 +30,7 @@ import functools import inspect import re +import sys import types from collections import OrderedDict from enum import Enum @@ -44,8 +45,6 @@ Union, ) -from typing_extensions import Annotated, get_args, get_origin - from ..channel import _threaded_guild_channel_factory from ..enums import Enum as DiscordEnum from ..enums import MessageType, SlashCommandOptionType, try_enum @@ -66,6 +65,11 @@ from .context import ApplicationContext, AutocompleteContext from .options import Option, OptionChoice +if sys.version_info >= (3, 11): + from typing import Annotated, get_args, get_origin +else: + from typing_extensions import Annotated, get_args, get_origin + __all__ = ( "_BaseCommand", "ApplicationCommand", From 229a406e4eeb4d23740b296832504f9956579729 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:59:05 +0000 Subject: [PATCH 11/15] chore(pre-commit): pre-commit autoupdate (#2133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.6.0 → v3.7.0](https://github.com/asottile/pyupgrade/compare/v3.6.0...v3.7.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c51f465bd..b04a133df0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: # - --remove-duplicate-keys # - --remove-unused-variables - repo: https://github.com/asottile/pyupgrade - rev: v3.6.0 + rev: v3.7.0 hooks: - id: pyupgrade args: [--py38-plus] From e2925d928d1c852b8b0ccad66b10d8aba7c6de94 Mon Sep 17 00:00:00 2001 From: Sengolda <79252176+Sengolda@users.noreply.github.com> Date: Sat, 24 Jun 2023 12:46:59 +0530 Subject: [PATCH 12/15] docs: Change color to colour (#2132) Signed-off-by: Sengolda <79252176+Sengolda@users.noreply.github.com> Co-authored-by: Lala Sabathil --- discord/colour.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/discord/colour.py b/discord/colour.py index c202351859..a8dbf7236a 100644 --- a/discord/colour.py +++ b/discord/colour.py @@ -335,8 +335,8 @@ def nitro_pink(cls: type[CT]) -> CT: @classmethod def embed_background(cls: type[CT], theme: str = "dark") -> CT: - """A factory method that returns a :class:`Color` corresponding to the - embed colors on discord clients, with a value of: + """A factory method that returns a :class:`Colour` corresponding to the + embed colours on discord clients, with a value of: - ``0x2B2D31`` (dark) - ``0xEEEFF1`` (light) @@ -347,7 +347,7 @@ def embed_background(cls: type[CT], theme: str = "dark") -> CT: Parameters ---------- theme: :class:`str` - The theme color to apply, must be one of "dark", "light", or "amoled". + The theme colour to apply, must be one of "dark", "light", or "amoled". """ themes_cls = { "dark": 0x2B2D31, From b8d19a5e922d40ae854b1a85803bdd12fb6d2ca2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:13:41 +0000 Subject: [PATCH 13/15] chore(deps-dev): Update pytest requirement from ~=7.3.2 to ~=7.4.0 (#2140) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.3.2...7.4.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index b51e52c143..af4ec2cd25 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,6 +1,6 @@ -r _.txt pylint~=2.17.4 -pytest~=7.3.2 +pytest~=7.4.0 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 mypy~=1.3.0 From b10130272fda3e42b75bfcfceb6818e30dd00923 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:21:10 +0000 Subject: [PATCH 14/15] chore(deps-dev): Update mypy requirement from ~=1.3.0 to ~=1.4.0 (#2135) Updates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version. - [Commits](https://github.com/python/mypy/compare/v1.3.0...v1.4.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil --- requirements/dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index af4ec2cd25..a62ccb7f74 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,7 +3,7 @@ pylint~=2.17.4 pytest~=7.4.0 pytest-asyncio~=0.21.0 # pytest-order~=1.0.1 -mypy~=1.3.0 +mypy~=1.4.0 coverage~=7.2 pre-commit==3.3.3 codespell==2.2.5 From b076bd3125baf60a0f626256ba897f0800e02631 Mon Sep 17 00:00:00 2001 From: Om <92863779+Om1609@users.noreply.github.com> Date: Sun, 25 Jun 2023 00:37:15 +0530 Subject: [PATCH 15/15] feat: add `suppress` and `allowed_mentions` parameters (#2138) * add undocmented parameters * docs and improved logic * style(pre-commit): auto fixes from pre-commit.com hooks * Changelog * style(pre-commit): auto fixes from pre-commit.com hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 3 +++ discord/interactions.py | 39 +++++++++++++++++++++++++++++++++++++++ discord/webhook/async_.py | 18 ++++++++++++++++-- discord/webhook/sync.py | 14 ++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb7bb88942..7e42278642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,9 @@ These changes are available on the `master` branch, but have not yet been releas ([#2106](https://github.com/Pycord-Development/pycord/pull/2106)) - Added Annotated forms support for typehinting slash command options. ([#2124](https://github.com/Pycord-Development/pycord/pull/2124)) +- Added `suppress` and `allowed_mentions` parameters to `Webhook` and + `InteractionResponse` edit methods. + ([#2138](https://github.com/Pycord-Development/pycord/pull/2138)) ### Changed diff --git a/discord/interactions.py b/discord/interactions.py index 4a74edf201..83ca14f128 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -33,6 +33,7 @@ from .enums import InteractionResponseType, InteractionType, try_enum from .errors import ClientException, InteractionResponded, InvalidArgument from .file import File +from .flags import MessageFlags from .member import Member from .message import Attachment, Message from .object import Object @@ -386,6 +387,7 @@ async def edit_original_response( view: View | None = MISSING, allowed_mentions: AllowedMentions | None = None, delete_after: float | None = None, + suppress: bool = False, ) -> InteractionMessage: """|coro| @@ -424,6 +426,8 @@ async def edit_original_response( If provided, the number of seconds to wait in the background before deleting the message we just edited. If the deletion fails, then it is silently ignored. + suppress: :class:`bool` + Whether to suppress embeds for the message. Returns ------- @@ -453,6 +457,7 @@ async def edit_original_response( view=view, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, + suppress=suppress, ) adapter = async_context.get() http = self._state.http @@ -936,6 +941,8 @@ async def edit_message( attachments: list[Attachment] = MISSING, view: View | None = MISSING, delete_after: float | None = None, + suppress: bool | None = MISSING, + allowed_mentions: AllowedMentions | None = None, ) -> None: """|coro| @@ -966,6 +973,15 @@ async def edit_message( If provided, the number of seconds to wait in the background before deleting the message we just edited. If the deletion fails, then it is silently ignored. + suppress: Optional[:class:`bool`] + Whether to suppress embeds for the message. + allowed_mentions: Optional[:class:`~discord.AllowedMentions`] + Controls the mentions being processed in this message. If this is + passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`. + The merging behaviour only overrides attributes that have been explicitly passed + to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`. + If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions` + are used instead. Raises ------ @@ -1029,6 +1045,23 @@ async def edit_message( # we keep previous attachments when adding new files payload["attachments"] = [a.to_dict() for a in msg.attachments] + if suppress is not MISSING: + flags = MessageFlags._from_value(self._parent.message.flags.value) + flags.suppress_embeds = suppress + payload["flags"] = flags.value + + if allowed_mentions is None: + payload["allowed_mentions"] = ( + state.allowed_mentions and state.allowed_mentions.to_dict() + ) + + elif state.allowed_mentions is not None: + payload["allowed_mentions"] = state.allowed_mentions.merge( + allowed_mentions + ).to_dict() + else: + payload["allowed_mentions"] = allowed_mentions.to_dict() + adapter = async_context.get() http = parent._state.http try: @@ -1215,6 +1248,7 @@ async def edit( view: View | None = MISSING, allowed_mentions: AllowedMentions | None = None, delete_after: float | None = None, + suppress: bool | None = MISSING, ) -> InteractionMessage: """|coro| @@ -1247,6 +1281,8 @@ async def edit( If provided, the number of seconds to wait in the background before deleting the message we just edited. If the deletion fails, then it is silently ignored. + suppress: Optional[:class:`bool`] + Whether to suppress embeds for the message. Returns ------- @@ -1266,6 +1302,8 @@ async def edit( """ if attachments is MISSING: attachments = self.attachments or MISSING + if suppress is MISSING: + suppress = self.flags.suppress_embeds return await self._state._interaction.edit_original_response( content=content, embeds=embeds, @@ -1276,6 +1314,7 @@ async def edit( view=view, allowed_mentions=allowed_mentions, delete_after=delete_after, + suppress=suppress, ) async def delete(self, *, delay: float | None = None) -> None: diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index f7d98f80a9..3a98c4baca 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -47,6 +47,7 @@ InvalidArgument, NotFound, ) +from ..flags import MessageFlags from ..http import Route from ..message import Attachment, Message from ..mixins import Hashable @@ -622,6 +623,7 @@ def handle_message_parameters( view: View | None = MISSING, allowed_mentions: AllowedMentions | None = MISSING, previous_allowed_mentions: AllowedMentions | None = None, + suppress: bool = False, ) -> ExecuteWebhookParameters: if files is not MISSING and file is not MISSING: raise TypeError("Cannot mix file and files keyword arguments.") @@ -648,8 +650,9 @@ def handle_message_parameters( payload["avatar_url"] = str(avatar_url) if username: payload["username"] = username - if ephemeral: - payload["flags"] = 64 + + flags = MessageFlags(suppress_embeds=suppress, ephemeral=ephemeral) + payload["flags"] = flags.value if allowed_mentions: if previous_allowed_mentions is not None: @@ -827,6 +830,7 @@ async def edit( attachments: list[Attachment] = MISSING, view: View | None = MISSING, allowed_mentions: AllowedMentions | None = None, + suppress: bool | None = MISSING, ) -> WebhookMessage: """|coro| @@ -868,6 +872,8 @@ async def edit( the view is removed. .. versionadded:: 2.0 + suppress: Optional[:class:`bool`] + Whether to suppress embeds for the message. Returns ------- @@ -898,6 +904,9 @@ async def edit( if attachments is MISSING: attachments = self.attachments or MISSING + if suppress is MISSING: + suppress = self.flags.suppress_embeds + return await self._state._webhook.edit_message( self.id, content=content, @@ -909,6 +918,7 @@ async def edit( view=view, allowed_mentions=allowed_mentions, thread=thread, + suppress=suppress, ) async def delete(self, *, delay: float | None = None) -> None: @@ -1845,6 +1855,7 @@ async def edit_message( view: View | None = MISSING, allowed_mentions: AllowedMentions | None = None, thread: Snowflake | None = MISSING, + suppress: bool = False, ) -> WebhookMessage: """|coro| @@ -1892,6 +1903,8 @@ async def edit_message( .. versionadded:: 2.0 thread: Optional[:class:`~discord.abc.Snowflake`] The thread that contains the message. + suppress: :class:`bool` + Whether to suppress embeds for the message. Returns ------- @@ -1939,6 +1952,7 @@ async def edit_message( view=view, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, + suppress=suppress, ) thread_id: int | None = None diff --git a/discord/webhook/sync.py b/discord/webhook/sync.py index 042130ac25..9e812b5709 100644 --- a/discord/webhook/sync.py +++ b/discord/webhook/sync.py @@ -472,6 +472,7 @@ def edit( file: File = MISSING, files: list[File] = MISSING, allowed_mentions: AllowedMentions | None = None, + suppress: bool | None = MISSING, ) -> SyncWebhookMessage: """Edits the message. @@ -492,6 +493,8 @@ def edit( allowed_mentions: :class:`AllowedMentions` Controls the mentions being processed in this message. See :meth:`.abc.Messageable.send` for more information. + suppress: Optional[:class:`bool`] + Whether to suppress embeds for the message. Returns ------- @@ -517,6 +520,9 @@ def edit( elif isinstance(self.channel, Thread): thread = Object(self.channel.id) + if suppress is MISSING: + suppress = self.flags.suppress_embeds + return self._state._webhook.edit_message( self.id, content=content, @@ -526,6 +532,7 @@ def edit( files=files, allowed_mentions=allowed_mentions, thread=thread, + suppress=suppress, ) def delete(self, *, delay: float | None = None) -> None: @@ -952,6 +959,7 @@ def send( thread: Snowflake = MISSING, thread_name: str | None = None, wait: Literal[False] = ..., + suppress: bool = MISSING, ) -> None: ... @@ -970,6 +978,7 @@ def send( thread: Snowflake = MISSING, thread_name: str | None = None, wait: bool = False, + suppress: bool = False, ) -> SyncWebhookMessage | None: """Sends a message using the webhook. @@ -1022,6 +1031,8 @@ def send( The name of the thread to create. Only works for forum channels. .. versionadded:: 2.0 + suppress: :class:`bool` + Whether to suppress embeds for the message. Returns ------- @@ -1070,6 +1081,7 @@ def send( embeds=embeds, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, + suppress=suppress, ) adapter: WebhookAdapter = _get_webhook_adapter() thread_id: int | None = None @@ -1151,6 +1163,7 @@ def edit_message( files: list[File] = MISSING, allowed_mentions: AllowedMentions | None = None, thread: Snowflake | None = MISSING, + suppress: bool = False, ) -> SyncWebhookMessage: """Edits a message owned by this webhook. @@ -1211,6 +1224,7 @@ def edit_message( embeds=embeds, allowed_mentions=allowed_mentions, previous_allowed_mentions=previous_mentions, + suppress=suppress, ) adapter: WebhookAdapter = _get_webhook_adapter()