Previously, Context.command was not guaranteed to be the actual command
being checked if it can run. This could be troublesome when
implementing help commands or when using the default help command.
This new change allows at least for the guarantee that Context.command
to be technically correct in Command.can_run.
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.
Along with this change comes with the removal of Converter.prepare and
adding two arguments to Converter.convert, the context and the argument.
I suppose an added benefit is that you don't have to do attribute
access since it's a local variable.
Internally, instead of using module objects just use the `__module__`
attribute which is the same thing. From preliminary testing this seems
to work fine with both regular one-file-per-cog approaches and the
folder cog approach.
Fixes#126.
This is a breaking change. The original purpose of no_pm has been
mainly a legacy aspect. They came from a time before checks were a
generalised concept and were never removed. A check is the proper way
to do its behaviour.
This should prevent asyncio.CancelledError from being propagated more
and suppressed "Task was destroyed but was pending!" warnings when
doing graceful closes outside of using a KeyboardInterrupt.
To make clean up a bit more robust, also add signal handlers
for POSIX systems.
This allows for you to create converters that can have varying
behaviour using the converter's __init__ instead of having to do a
meta-class based approach to get around the fact that __init__ is part
of the interface.
To make up for the lack of __init__, a new method Converter.prepare was
added to do the work that __init__ used to do.
If a command or a group raised a CommandError derived exception it
would be wrapped into CommandInvokeError. This fixes this case so it
raises the original exception instead.
The way the command cooldown works is using a windowed way of doing it.
That is, if we have a cooldown of 2 commands every 30 seconds then if we
do a single command, we have 30 seconds to do the second command or else
we will get rate limited. This more or less matches the common
expectations on how cooldowns should be.
These cooldowns can be bucketed up to a single dimension of depth for
a per-user, per-guild, or per-channel basis. Of course, a global bucket
is also provided. These cannot be mixed, e.g. no per-channel per-user
cooldowns.
When a command cooldown is triggered, the error handlers will receive a
an exception of type CommandOnCooldown with proper information regarding
the cooldown such as retry_after and the bucket information itself.