From d9a8ae9c78f5ca0eef5e1f033b4151ece4ed1028 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Wed, 18 Dec 2019 01:20:50 -0500 Subject: [PATCH] [commands] Add predicate attribute to checks to get inner function --- discord/ext/commands/core.py | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 5754acc4a..8c086603c 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -1307,10 +1307,27 @@ def check(predicate): will be propagated while those subclassed will be sent to :func:`.on_command_error`. + A special attribute named ``predicate`` is bound to the value + returned by this decorator to retrieve the predicate passed to the + decorator. This allows the following introspection and chaining to be done: + + .. code-block:: python3 + + def owner_or_permissions(**perms): + original = commands.has_permissions(**perms).predicate + def extended_check(ctx): + if ctx.guild is None: + return False + return ctx.guild.owner_id == ctx.author.id or original(ctx) + return commands.check(extended_check) + .. note:: These functions can either be regular functions or coroutines. + .. versionchanged:: 1.3.0 + The ``predicate`` attribute was added. + Examples --------- @@ -1356,6 +1373,8 @@ def check(predicate): func.__commands_checks__.append(predicate) return func + + decorator.predicate = predicate return decorator def has_role(item): @@ -1374,6 +1393,10 @@ def has_role(item): is missing a role, or :exc:`.NoPrivateMessage` if it is used in a private message. Both inherit from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionchanged:: 1.1.0 Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage` @@ -1410,6 +1433,10 @@ def has_any_role(*items): is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message. Both inherit from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionchanged:: 1.1.0 Raise :exc:`.MissingAnyRole` or :exc:`.NoPrivateMessage` @@ -1449,6 +1476,10 @@ def bot_has_role(item): is missing the role, or :exc:`.NoPrivateMessage` if it is used in a private message. Both inherit from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionchanged:: 1.1.0 Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage` @@ -1478,6 +1509,10 @@ def bot_has_any_role(*items): is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message. Both inherit from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionchanged:: 1.1.0 Raise :exc:`.BotMissingAnyRole` or :exc:`.NoPrivateMessage` @@ -1508,6 +1543,10 @@ def has_permissions(**perms): This check raises a special exception, :exc:`.MissingPermissions` that is inherited from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + Parameters ------------ perms @@ -1543,6 +1582,10 @@ def bot_has_permissions(**perms): This check raises a special exception, :exc:`.BotMissingPermissions` that is inherited from :exc:`.CheckFailure`. + + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. """ def predicate(ctx): guild = ctx.guild @@ -1565,6 +1608,10 @@ def has_guild_permissions(**perms): If this check is called in a DM context, it will raise an exception, :exc:`.NoPrivateMessage`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionadded:: 1.3.0 """ def predicate(ctx): @@ -1585,6 +1632,10 @@ def bot_has_guild_permissions(**perms): """Similar to :func:`.has_guild_permissions`, but checks the bot members guild permissions. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionadded:: 1.3.0 """ def predicate(ctx): @@ -1609,6 +1660,10 @@ def dm_only(): This check raises a special exception, :exc:`.PrivateMessageOnly` that is inherited from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionadded:: 1.1.0 """ @@ -1626,6 +1681,10 @@ def guild_only(): This check raises a special exception, :exc:`.NoPrivateMessage` that is inherited from :exc:`.CheckFailure`. + + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. """ def predicate(ctx): @@ -1643,6 +1702,10 @@ def is_owner(): This check raises a special exception, :exc:`.NotOwner` that is derived from :exc:`.CheckFailure`. + + .. note:: + + The ``predicate`` attribute for this function **is** a coroutine. """ async def predicate(ctx): @@ -1658,6 +1721,10 @@ def is_nsfw(): This check raises a special exception, :exc:`.NSFWChannelRequired` that is derived from :exc:`.CheckFailure`. + .. note:: + + The ``predicate`` attribute for this function is **not** a coroutine. + .. versionchanged:: 1.1.0 Raise :exc:`.NSFWChannelRequired` instead of generic :exc:`.CheckFailure`.