From 05ef5fa3a6817fdea9fde7c42b8450ae59afa9c1 Mon Sep 17 00:00:00 2001 From: jack1142 <6032823+jack1142@users.noreply.github.com> Date: Mon, 10 Aug 2020 21:19:00 +0200 Subject: [PATCH] Preparations for d.py 1.4 (includes breaking changes related to mass mentions) (#3845) Co-authored-by: PredaaA <46051820+PredaaA@users.noreply.github.com> --- redbot/__init__.py | 10 ---------- redbot/core/bot.py | 7 +++++-- redbot/core/commands/__init__.py | 3 +++ redbot/core/commands/_dpy_reimplements.py | 11 +++++++++++ redbot/core/commands/commands.py | 1 + redbot/core/commands/context.py | 12 ++++++------ setup.cfg | 5 ++--- tools/primary_deps.ini | 4 ---- 8 files changed, 28 insertions(+), 25 deletions(-) diff --git a/redbot/__init__.py b/redbot/__init__.py index 113228727..34a4ca525 100644 --- a/redbot/__init__.py +++ b/redbot/__init__.py @@ -213,13 +213,3 @@ if "--debug" not in _sys.argv: # DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10. # self._event = asyncio.Event(loop=loop) _warnings.filterwarnings("ignore", category=DeprecationWarning, module="aiohttp", lineno=21) - # DeprecationWarning: rename klass to create_protocol - # warnings.warn("rename klass to create_protocol", DeprecationWarning) - _warnings.filterwarnings( - "ignore", category=DeprecationWarning, module="websockets", lineno=407 - ) - # DeprecationWarning: The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10. - # transport, protocol = await self._create_connection() - _warnings.filterwarnings( - "ignore", category=DeprecationWarning, module="websockets", lineno=535 - ) diff --git a/redbot/core/bot.py b/redbot/core/bot.py index fe71aa20f..ca41320d7 100644 --- a/redbot/core/bot.py +++ b/redbot/core/bot.py @@ -181,6 +181,9 @@ class RedBase( if "command_not_found" not in kwargs: kwargs["command_not_found"] = "Command {} not found.\n{}" + if "allowed_mentions" not in kwargs: + kwargs["allowed_mentions"] = discord.AllowedMentions(everyone=False, roles=False) + message_cache_size = cli_flags.message_cache_size if cli_flags.no_message_cache: message_cache_size = None @@ -1261,7 +1264,7 @@ class RedBase( if permissions_not_loaded: command.requires.ready_event.set() if isinstance(command, commands.Group): - for subcommand in set(command.walk_commands()): + for subcommand in command.walk_commands(): self.dispatch("command_add", subcommand) if permissions_not_loaded: subcommand.requires.ready_event.set() @@ -1275,7 +1278,7 @@ class RedBase( return command.requires.reset() if isinstance(command, commands.Group): - for subcommand in set(command.walk_commands()): + for subcommand in command.walk_commands(): subcommand.requires.reset() def clear_permission_rules(self, guild_id: Optional[int], **kwargs) -> None: diff --git a/redbot/core/commands/__init__.py b/redbot/core/commands/__init__.py index cfaa2669b..984ad76fd 100644 --- a/redbot/core/commands/__init__.py +++ b/redbot/core/commands/__init__.py @@ -76,6 +76,8 @@ from ._dpy_reimplements import ( when_mentioned_or as when_mentioned_or, when_mentioned as when_mentioned, bot_has_any_role as bot_has_any_role, + before_invoke as before_invoke, + after_invoke as after_invoke, ) ### DEP-WARN: Check this *every* discord.py update @@ -143,6 +145,7 @@ from discord.ext.commands import ( MaxConcurrency as MaxConcurrency, MaxConcurrencyReached as MaxConcurrencyReached, bot_has_guild_permissions as bot_has_guild_permissions, + CommandRegistrationError as CommandRegistrationError, ) diff --git a/redbot/core/commands/_dpy_reimplements.py b/redbot/core/commands/_dpy_reimplements.py index 6421a9643..559256aad 100644 --- a/redbot/core/commands/_dpy_reimplements.py +++ b/redbot/core/commands/_dpy_reimplements.py @@ -31,6 +31,8 @@ if not TYPE_CHECKING: bot_has_role as bot_has_role, bot_has_any_role as bot_has_any_role, cooldown as cooldown, + before_invoke as before_invoke, + after_invoke as after_invoke, ) from ..i18n import Translator @@ -59,6 +61,8 @@ __all__ = [ "when_mentioned_or", "cooldown", "when_mentioned", + "before_invoke", + "after_invoke", ] _CT = TypeVar("_CT", bound=Context) @@ -66,6 +70,7 @@ _T = TypeVar("_T") _F = TypeVar("_F") CheckType = Union[Callable[[_CT], bool], Callable[[_CT], Coroutine[Any, Any, bool]]] CoroLike = Callable[..., Union[Awaitable[_T], Generator[Any, None, _T]]] +InvokeHook = Callable[[_CT], Coroutine[Any, Any, bool]] class CheckDecorator(Protocol): @@ -109,6 +114,12 @@ if TYPE_CHECKING: def cooldown(rate: int, per: float, type: dpy_commands.BucketType = ...) -> Callable[[_F], _F]: ... + def before_invoke(coro: InvokeHook) -> Callable[[_F], _F]: + ... + + def after_invoke(coro: InvokeHook) -> Callable[[_F], _F]: + ... + PrefixCallable = Callable[[dpy_commands.bot.BotBase, discord.Message], List[str]] diff --git a/redbot/core/commands/commands.py b/redbot/core/commands/commands.py index 5fed9e88c..7fb79d2f1 100644 --- a/redbot/core/commands/commands.py +++ b/redbot/core/commands/commands.py @@ -794,6 +794,7 @@ class Group(GroupMixin, Command, CogGroupMixin, DPYGroup): # we skip prepare in some cases to avoid some things # We still always want this part of the behavior though ctx.command = self + ctx.subcommand_passed = None # Our re-ordered behavior below. view = ctx.view previous = view.index diff --git a/redbot/core/commands/context.py b/redbot/core/commands/context.py index 2daa6e15f..c899aa4a6 100644 --- a/redbot/core/commands/context.py +++ b/redbot/core/commands/context.py @@ -69,12 +69,12 @@ class Context(DPYContext): Other Parameters ---------------- - filter : Callable[`str`] -> `str` - A function which is used to sanitize the ``content`` before - it is sent. Defaults to - :func:`~redbot.core.utils.common_filters.filter_mass_mentions`. + filter : callable (`str`) -> `str`, optional + A function which is used to filter the ``content`` before + it is sent. This must take a single `str` as an argument, and return - the sanitized `str`. + the processed `str`. When `None` is passed, ``content`` won't be touched. + Defaults to `None`. **kwargs See `discord.ext.commands.Context.send`. @@ -85,7 +85,7 @@ class Context(DPYContext): """ - _filter = kwargs.pop("filter", common_filters.filter_mass_mentions) + _filter = kwargs.pop("filter", None) if _filter and content: content = _filter(str(content)) diff --git a/setup.cfg b/setup.cfg index aed3fad14..1ce1c9acf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -44,7 +44,7 @@ install_requires = click==7.1.2 colorama==0.4.3 contextlib2==0.6.0.post1 - discord.py==1.3.4 + discord.py==1.4.1 distro==1.5.0; sys_platform == "linux" fuzzywuzzy==0.18.0 idna==2.10 @@ -53,12 +53,11 @@ install_requires = python-Levenshtein-wheels==0.13.1 pytz==2020.1 PyYAML==5.3.1 - Red-Lavalink==0.5.1 + Red-Lavalink==0.6.0 schema==0.7.2 tqdm==4.48.0 typing-extensions==3.7.4.2 uvloop==0.14.0; sys_platform != "win32" and platform_python_implementation == "CPython" - websockets==8.1 yarl==1.5.1 [options.extras_require] diff --git a/tools/primary_deps.ini b/tools/primary_deps.ini index f5ab6da25..faf415e6a 100644 --- a/tools/primary_deps.ini +++ b/tools/primary_deps.ini @@ -24,10 +24,6 @@ install_requires = schema tqdm uvloop; sys_platform != "win32" and platform_python_implementation == "CPython" - # Websockets is a secondary dependency, but until pip has a complete dependency resolver, we - # need to list it here to avoid an incompatible version being installed. - # See under point 2 here: https://pip.pypa.io/en/stable/user_guide/#requirements-files - websockets<9.0 [options.extras_require] docs =