aboutsummaryrefslogtreecommitdiff
path: root/discord/ext/commands/context.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2017-05-19 21:33:39 -0400
committerRapptz <[email protected]>2017-05-19 21:33:39 -0400
commitb81fbb5a7f6df4125cddc57feefceef75a1974c1 (patch)
tree57c63c84050dbfbf6c8f848bf0bf57c71d651752 /discord/ext/commands/context.py
parent[commands] Fix Context.command_failed from being incorrect. (diff)
downloaddiscord.py-b81fbb5a7f6df4125cddc57feefceef75a1974c1.tar.xz
discord.py-b81fbb5a7f6df4125cddc57feefceef75a1974c1.zip
[commands] Add Context.reinvoke and Command.root_parent
Context.reinvoke would be the new way to bypass checks and cooldowns. However, with its addition comes a change in the invocation order of checks, callbacks, and cooldowns. While previously cooldowns would trigger after command argument parsing, the new behaviour parses cooldowns before command argument parsing. The implication of this change is that Context.args and Context.kwargs will no longer be filled properly.
Diffstat (limited to 'discord/ext/commands/context.py')
-rw-r--r--discord/ext/commands/context.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/discord/ext/commands/context.py b/discord/ext/commands/context.py
index ef7d9ca6..53aecdb1 100644
--- a/discord/ext/commands/context.py
+++ b/discord/ext/commands/context.py
@@ -121,6 +121,59 @@ class Context(discord.abc.Messageable):
ret = yield from command.callback(*arguments, **kwargs)
return ret
+ @asyncio.coroutine
+ def reinvoke(self, *, call_hooks=False, restart=True):
+ """|coro|
+
+ Calls the command again.
+
+ This is similar to :meth:`~.Context.invoke` except that it bypasses
+ checks, cooldowns, and error handlers.
+
+ .. note::
+
+ If you want to bypass :exc:`.UserInputError` derived exceptions,
+ it is recommended to use the regular :meth:`~.Context.invoke`
+ as it will work more naturally. After all, this will end up
+ using the old arguments the user has used and will thus just
+ fail again.
+
+ Parameters
+ ------------
+ call_hooks: bool
+ Whether to call the before and after invoke hooks.
+ restart: bool
+ Whether to start the call chain from the very beginning
+ or where we left off (i.e. the command that caused the error).
+ """
+ cmd = self.command
+ view = self.view
+ if cmd is None:
+ raise ValueError('This context is not valid.')
+
+ # some state to revert to when we're done
+ index, previous = view.index, view.previous
+ invoked_with = self.invoked_with
+ invoked_subcommand = self.invoked_subcommand
+ subcommand_passed = self.subcommand_passed
+
+ if restart:
+ to_call = cmd.root_parent or cmd
+ view.index = len(self.prefix) + 1
+ view.previous = 0
+ else:
+ to_call = cmd
+
+ try:
+ yield from to_call.reinvoke(self, call_hooks=call_hooks)
+ finally:
+ self.command = cmd
+ view.index = index
+ view.previous = previous
+ self.invoked_with = invoked_with
+ self.invoked_subcommand = invoked_subcommand
+ self.subcommand_passed = subcommand_passed
+
@property
def valid(self):
"""Checks if the invocation context is valid to be invoked with."""