[commands] Add check_any check to OR together various checks
This commit is contained in:
		| @@ -48,6 +48,7 @@ __all__ = ( | ||||
|     'has_permissions', | ||||
|     'has_any_role', | ||||
|     'check', | ||||
|     'check_any', | ||||
|     'bot_has_role', | ||||
|     'bot_has_permissions', | ||||
|     'bot_has_any_role', | ||||
| @@ -1379,6 +1380,75 @@ def check(predicate): | ||||
|     decorator.predicate = predicate | ||||
|     return decorator | ||||
|  | ||||
| def check_any(*checks): | ||||
|     """A :func:`check` that is added that checks if any of the checks passed | ||||
|     will pass, i.e. using logical OR. | ||||
|  | ||||
|     If all checks fail then :exc:`.CheckAnyFailure` is raised to signal the failure. | ||||
|     It inherits from :exc:`.CheckFailure`. | ||||
|  | ||||
|     .. note:: | ||||
|  | ||||
|         The ``predicate`` attribute for this function **is** a coroutine. | ||||
|  | ||||
|     .. versionadded:: 1.3.0 | ||||
|  | ||||
|     Parameters | ||||
|     ------------ | ||||
|     \*checks: Callable[[:class:`Context`], :class:`bool`] | ||||
|         An argument list of checks that have been decorated with | ||||
|         the :func:`check` decorator. | ||||
|  | ||||
|     Raises | ||||
|     ------- | ||||
|     TypeError | ||||
|         A check passed has not been decorated with the :func:`check` | ||||
|         decorator. | ||||
|  | ||||
|     Examples | ||||
|     --------- | ||||
|  | ||||
|     Creating a basic check to see if it's the bot owner or | ||||
|     the server owner: | ||||
|  | ||||
|     .. code-block:: python3 | ||||
|  | ||||
|         def is_guild_owner(): | ||||
|             def predicate(ctx): | ||||
|                 return ctx.guild is not None and ctx.guild.owner_id == ctx.author.id | ||||
|             return commands.check(predicate) | ||||
|  | ||||
|         @bot.command() | ||||
|         @commands.check_any(commands.is_owner(), is_guild_owner()) | ||||
|         async def only_for_owners(ctx): | ||||
|             await ctx.send('Hello mister owner!') | ||||
|     """ | ||||
|  | ||||
|     unwrapped = [] | ||||
|     for wrapped in checks: | ||||
|         try: | ||||
|             pred = wrapped.predicate | ||||
|         except AttributeError: | ||||
|             raise TypeError('%r must be wrapped by commands.check decorator' % wrapped) from None | ||||
|         else: | ||||
|             unwrapped.append(pred) | ||||
|  | ||||
|     async def predicate(ctx): | ||||
|         errors = [] | ||||
|         maybe = discord.utils.maybe_coroutine | ||||
|         for func in unwrapped: | ||||
|             try: | ||||
|                 value = await maybe(func, ctx) | ||||
|             except CheckFailure as e: | ||||
|                 errors.append(e) | ||||
|             else: | ||||
|                 if value: | ||||
|                     return True | ||||
|         # if we're here, all checks failed | ||||
|         raise CheckAnyFailure(unwrapped, errors) | ||||
|  | ||||
|     return check(predicate) | ||||
|  | ||||
| def has_role(item): | ||||
|     """A :func:`.check` that is added that checks if the member invoking the | ||||
|     command has the role specified via the name or ID specified. | ||||
|   | ||||
| @@ -34,6 +34,7 @@ __all__ = ( | ||||
|     'PrivateMessageOnly', | ||||
|     'NoPrivateMessage', | ||||
|     'CheckFailure', | ||||
|     'CheckAnyFailure', | ||||
|     'CommandNotFound', | ||||
|     'DisabledCommand', | ||||
|     'CommandInvokeError', | ||||
| @@ -153,6 +154,26 @@ class CheckFailure(CommandError): | ||||
|     """ | ||||
|     pass | ||||
|  | ||||
| class CheckAnyFailure(CheckFailure): | ||||
|     """Exception raised when all predicates in :func:`check_any` fail. | ||||
|  | ||||
|     This inherits from :exc:`CheckFailure`. | ||||
|  | ||||
|     .. versionadded:: 1.3 | ||||
|  | ||||
|     Attributes | ||||
|     ------------ | ||||
|     errors: List[:class:`CheckFailure`] | ||||
|         A list of errors that were caught during execution. | ||||
|     checks: List[Callable[[:class:`Context`], :class:`bool`]] | ||||
|         A list of check predicates that failed. | ||||
|     """ | ||||
|  | ||||
|     def __init__(self, checks, errors): | ||||
|         self.checks = checks | ||||
|         self.errors = errors | ||||
|         super().__init__('You do not have permission to run this command.') | ||||
|  | ||||
| class PrivateMessageOnly(CheckFailure): | ||||
|     """Exception raised when an operation does not work outside of private | ||||
|     message contexts. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user