Drop support for Python 3.4 and make minimum version 3.5.2.
This commit is contained in:
@ -91,8 +91,7 @@ _mention_pattern = re.compile('|'.join(_mentions_transforms.keys()))
|
||||
def _is_submodule(parent, child):
|
||||
return parent == child or child.startswith(parent + ".")
|
||||
|
||||
@asyncio.coroutine
|
||||
def _default_help_command(ctx, *commands : str):
|
||||
async def _default_help_command(ctx, *commands : str):
|
||||
"""Shows this message."""
|
||||
bot = ctx.bot
|
||||
destination = ctx.message.author if bot.pm_help else ctx.message.channel
|
||||
@ -102,7 +101,7 @@ def _default_help_command(ctx, *commands : str):
|
||||
|
||||
# help by itself just lists our own commands.
|
||||
if len(commands) == 0:
|
||||
pages = yield from bot.formatter.format_help_for(ctx, bot)
|
||||
pages = await bot.formatter.format_help_for(ctx, bot)
|
||||
elif len(commands) == 1:
|
||||
# try to see if it is a cog name
|
||||
name = _mention_pattern.sub(repl, commands[0])
|
||||
@ -112,15 +111,15 @@ def _default_help_command(ctx, *commands : str):
|
||||
else:
|
||||
command = bot.all_commands.get(name)
|
||||
if command is None:
|
||||
yield from destination.send(bot.command_not_found.format(name))
|
||||
await destination.send(bot.command_not_found.format(name))
|
||||
return
|
||||
|
||||
pages = yield from bot.formatter.format_help_for(ctx, command)
|
||||
pages = await bot.formatter.format_help_for(ctx, command)
|
||||
else:
|
||||
name = _mention_pattern.sub(repl, commands[0])
|
||||
command = bot.all_commands.get(name)
|
||||
if command is None:
|
||||
yield from destination.send(bot.command_not_found.format(name))
|
||||
await destination.send(bot.command_not_found.format(name))
|
||||
return
|
||||
|
||||
for key in commands[1:]:
|
||||
@ -128,13 +127,13 @@ def _default_help_command(ctx, *commands : str):
|
||||
key = _mention_pattern.sub(repl, key)
|
||||
command = command.all_commands.get(key)
|
||||
if command is None:
|
||||
yield from destination.send(bot.command_not_found.format(key))
|
||||
await destination.send(bot.command_not_found.format(key))
|
||||
return
|
||||
except AttributeError:
|
||||
yield from destination.send(bot.command_has_no_subcommands.format(command, key))
|
||||
await destination.send(bot.command_has_no_subcommands.format(command, key))
|
||||
return
|
||||
|
||||
pages = yield from bot.formatter.format_help_for(ctx, command)
|
||||
pages = await bot.formatter.format_help_for(ctx, command)
|
||||
|
||||
if bot.pm_help is None:
|
||||
characters = sum(map(lambda l: len(l), pages))
|
||||
@ -143,7 +142,7 @@ def _default_help_command(ctx, *commands : str):
|
||||
destination = ctx.message.author
|
||||
|
||||
for page in pages:
|
||||
yield from destination.send(page)
|
||||
await destination.send(page)
|
||||
|
||||
class BotBase(GroupMixin):
|
||||
def __init__(self, command_prefix, formatter=None, description=None, pm_help=False, **options):
|
||||
@ -189,10 +188,9 @@ class BotBase(GroupMixin):
|
||||
ev = 'on_' + event_name
|
||||
for event in self.extra_events.get(ev, []):
|
||||
coro = self._run_event(event, event_name, *args, **kwargs)
|
||||
discord.compat.create_task(coro, loop=self.loop)
|
||||
asyncio.ensure_future(coro, loop=self.loop)
|
||||
|
||||
@asyncio.coroutine
|
||||
def close(self):
|
||||
async def close(self):
|
||||
for extension in tuple(self.extensions):
|
||||
try:
|
||||
self.unload_extension(extension)
|
||||
@ -205,10 +203,9 @@ class BotBase(GroupMixin):
|
||||
except:
|
||||
pass
|
||||
|
||||
yield from super().close()
|
||||
await super().close()
|
||||
|
||||
@asyncio.coroutine
|
||||
def on_command_error(self, context, exception):
|
||||
async def on_command_error(self, context, exception):
|
||||
"""|coro|
|
||||
|
||||
The default command error handler provided by the bot.
|
||||
@ -335,17 +332,15 @@ class BotBase(GroupMixin):
|
||||
self.add_check(func, call_once=True)
|
||||
return func
|
||||
|
||||
@asyncio.coroutine
|
||||
def can_run(self, ctx, *, call_once=False):
|
||||
async def can_run(self, ctx, *, call_once=False):
|
||||
data = self._check_once if call_once else self._checks
|
||||
|
||||
if len(data) == 0:
|
||||
return True
|
||||
|
||||
return (yield from discord.utils.async_all(f(ctx) for f in data))
|
||||
return (await discord.utils.async_all(f(ctx) for f in data))
|
||||
|
||||
@asyncio.coroutine
|
||||
def is_owner(self, user):
|
||||
async def is_owner(self, user):
|
||||
"""Checks if a :class:`.User` or :class:`.Member` is the owner of
|
||||
this bot.
|
||||
|
||||
@ -359,7 +354,7 @@ class BotBase(GroupMixin):
|
||||
"""
|
||||
|
||||
if self.owner_id is None:
|
||||
app = yield from self.application_info()
|
||||
app = await self.application_info()
|
||||
self.owner_id = owner_id = app.owner.id
|
||||
return user.id == owner_id
|
||||
return user.id == self.owner_id
|
||||
@ -773,8 +768,7 @@ class BotBase(GroupMixin):
|
||||
|
||||
# command processing
|
||||
|
||||
@asyncio.coroutine
|
||||
def get_prefix(self, message):
|
||||
async def get_prefix(self, message):
|
||||
"""|coro|
|
||||
|
||||
Retrieves the prefix the bot is listening to
|
||||
@ -801,9 +795,7 @@ class BotBase(GroupMixin):
|
||||
"""
|
||||
prefix = ret = self.command_prefix
|
||||
if callable(prefix):
|
||||
ret = prefix(self, message)
|
||||
if asyncio.iscoroutine(ret):
|
||||
ret = yield from ret
|
||||
ret = await discord.utils.maybe_coroutine(prefix, self, ret)
|
||||
|
||||
if isinstance(ret, (list, tuple)):
|
||||
ret = [p for p in ret if p]
|
||||
@ -813,8 +805,7 @@ class BotBase(GroupMixin):
|
||||
|
||||
return ret
|
||||
|
||||
@asyncio.coroutine
|
||||
def get_context(self, message, *, cls=Context):
|
||||
async def get_context(self, message, *, cls=Context):
|
||||
"""|coro|
|
||||
|
||||
Returns the invocation context from the message.
|
||||
@ -850,7 +841,7 @@ class BotBase(GroupMixin):
|
||||
if self._skip_check(message.author.id, self.user.id):
|
||||
return ctx
|
||||
|
||||
prefix = yield from self.get_prefix(message)
|
||||
prefix = await self.get_prefix(message)
|
||||
invoked_prefix = prefix
|
||||
|
||||
if isinstance(prefix, str):
|
||||
@ -867,8 +858,7 @@ class BotBase(GroupMixin):
|
||||
ctx.command = self.all_commands.get(invoker)
|
||||
return ctx
|
||||
|
||||
@asyncio.coroutine
|
||||
def invoke(self, ctx):
|
||||
async def invoke(self, ctx):
|
||||
"""|coro|
|
||||
|
||||
Invokes the command given under the invocation context and
|
||||
@ -882,18 +872,17 @@ class BotBase(GroupMixin):
|
||||
if ctx.command is not None:
|
||||
self.dispatch('command', ctx)
|
||||
try:
|
||||
if (yield from self.can_run(ctx, call_once=True)):
|
||||
yield from ctx.command.invoke(ctx)
|
||||
if (await self.can_run(ctx, call_once=True)):
|
||||
await ctx.command.invoke(ctx)
|
||||
except CommandError as e:
|
||||
yield from ctx.command.dispatch_error(ctx, e)
|
||||
await ctx.command.dispatch_error(ctx, e)
|
||||
else:
|
||||
self.dispatch('command_completion', ctx)
|
||||
elif ctx.invoked_with:
|
||||
exc = CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with))
|
||||
self.dispatch('command_error', ctx, exc)
|
||||
|
||||
@asyncio.coroutine
|
||||
def process_commands(self, message):
|
||||
async def process_commands(self, message):
|
||||
"""|coro|
|
||||
|
||||
This function processes the commands that have been registered
|
||||
@ -912,12 +901,11 @@ class BotBase(GroupMixin):
|
||||
message : discord.Message
|
||||
The message to process commands for.
|
||||
"""
|
||||
ctx = yield from self.get_context(message)
|
||||
yield from self.invoke(ctx)
|
||||
ctx = await self.get_context(message)
|
||||
await self.invoke(ctx)
|
||||
|
||||
@asyncio.coroutine
|
||||
def on_message(self, message):
|
||||
yield from self.process_commands(message)
|
||||
async def on_message(self, message):
|
||||
await self.process_commands(message)
|
||||
|
||||
class Bot(BotBase, discord.Client):
|
||||
"""Represents a discord bot.
|
||||
|
@ -86,8 +86,7 @@ class Context(discord.abc.Messageable):
|
||||
self.command_failed = attrs.pop('command_failed', False)
|
||||
self._state = self.message._state
|
||||
|
||||
@asyncio.coroutine
|
||||
def invoke(self, *args, **kwargs):
|
||||
async def invoke(self, *args, **kwargs):
|
||||
"""|coro|
|
||||
|
||||
Calls a command with the arguments given.
|
||||
@ -125,11 +124,10 @@ class Context(discord.abc.Messageable):
|
||||
arguments.append(self)
|
||||
arguments.extend(args[1:])
|
||||
|
||||
ret = yield from command.callback(*arguments, **kwargs)
|
||||
ret = await command.callback(*arguments, **kwargs)
|
||||
return ret
|
||||
|
||||
@asyncio.coroutine
|
||||
def reinvoke(self, *, call_hooks=False, restart=True):
|
||||
async def reinvoke(self, *, call_hooks=False, restart=True):
|
||||
"""|coro|
|
||||
|
||||
Calls the command again.
|
||||
@ -174,7 +172,7 @@ class Context(discord.abc.Messageable):
|
||||
to_call = cmd
|
||||
|
||||
try:
|
||||
yield from to_call.reinvoke(self, call_hooks=call_hooks)
|
||||
await to_call.reinvoke(self, call_hooks=call_hooks)
|
||||
finally:
|
||||
self.command = cmd
|
||||
view.index = index
|
||||
@ -188,8 +186,7 @@ class Context(discord.abc.Messageable):
|
||||
"""Checks if the invocation context is valid to be invoked with."""
|
||||
return self.prefix is not None and self.command is not None
|
||||
|
||||
@asyncio.coroutine
|
||||
def _get_channel(self):
|
||||
async def _get_channel(self):
|
||||
return self.channel
|
||||
|
||||
@property
|
||||
|
@ -57,8 +57,7 @@ class Converter:
|
||||
method to do its conversion logic. This method must be a coroutine.
|
||||
"""
|
||||
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
"""|coro|
|
||||
|
||||
The method to override to do conversion logic.
|
||||
@ -99,8 +98,7 @@ class MemberConverter(IDConverter):
|
||||
5. Lookup by nickname
|
||||
"""
|
||||
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
message = ctx.message
|
||||
bot = ctx.bot
|
||||
match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument)
|
||||
@ -136,8 +134,7 @@ class UserConverter(IDConverter):
|
||||
3. Lookup by name#discrim
|
||||
4. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument)
|
||||
result = None
|
||||
state = ctx._state
|
||||
@ -176,8 +173,7 @@ class TextChannelConverter(IDConverter):
|
||||
2. Lookup by mention.
|
||||
3. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
bot = ctx.bot
|
||||
|
||||
match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument)
|
||||
@ -216,8 +212,7 @@ class VoiceChannelConverter(IDConverter):
|
||||
2. Lookup by mention.
|
||||
3. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
bot = ctx.bot
|
||||
match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument)
|
||||
result = None
|
||||
@ -255,8 +250,7 @@ class CategoryChannelConverter(IDConverter):
|
||||
2. Lookup by mention.
|
||||
3. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
bot = ctx.bot
|
||||
|
||||
match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument)
|
||||
@ -295,8 +289,7 @@ class ColourConverter(Converter):
|
||||
|
||||
- The ``_`` in the name can be optionally replaced with spaces.
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
arg = argument.replace('0x', '').lower()
|
||||
|
||||
if arg[0] == '#':
|
||||
@ -323,8 +316,7 @@ class RoleConverter(IDConverter):
|
||||
2. Lookup by mention.
|
||||
3. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
guild = ctx.message.guild
|
||||
if not guild:
|
||||
raise NoPrivateMessage()
|
||||
@ -338,8 +330,7 @@ class RoleConverter(IDConverter):
|
||||
|
||||
class GameConverter(Converter):
|
||||
"""Converts to :class:`Game`."""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
return discord.Game(name=argument)
|
||||
|
||||
class InviteConverter(Converter):
|
||||
@ -347,10 +338,9 @@ class InviteConverter(Converter):
|
||||
|
||||
This is done via an HTTP request using :meth:`.Bot.get_invite`.
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
try:
|
||||
invite = yield from ctx.bot.get_invite(argument)
|
||||
invite = await ctx.bot.get_invite(argument)
|
||||
return invite
|
||||
except Exception as e:
|
||||
raise BadArgument('Invite is invalid or expired') from e
|
||||
@ -368,8 +358,7 @@ class EmojiConverter(IDConverter):
|
||||
2. Lookup by extracting ID from the emoji.
|
||||
3. Lookup by name
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
match = self._get_id_match(argument) or re.match(r'<a?:[a-zA-Z0-9\_]+:([0-9]+)>$', argument)
|
||||
result = None
|
||||
bot = ctx.bot
|
||||
@ -403,8 +392,7 @@ class PartialEmojiConverter(Converter):
|
||||
|
||||
This is done by extracting the animated flag, name and ID from the emoji.
|
||||
"""
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
match = re.match(r'<(a?):([a-zA-Z0-9\_]+):([0-9]+)>$', argument)
|
||||
|
||||
if match:
|
||||
@ -436,8 +424,7 @@ class clean_content(Converter):
|
||||
self.use_nicknames = use_nicknames
|
||||
self.escape_markdown = escape_markdown
|
||||
|
||||
@asyncio.coroutine
|
||||
def convert(self, ctx, argument):
|
||||
async def convert(self, ctx, argument):
|
||||
message = ctx.message
|
||||
transformations = {}
|
||||
|
||||
|
@ -41,10 +41,9 @@ __all__ = [ 'Command', 'Group', 'GroupMixin', 'command', 'group',
|
||||
|
||||
def wrap_callback(coro):
|
||||
@functools.wraps(coro)
|
||||
@asyncio.coroutine
|
||||
def wrapped(*args, **kwargs):
|
||||
async def wrapped(*args, **kwargs):
|
||||
try:
|
||||
ret = yield from coro(*args, **kwargs)
|
||||
ret = await coro(*args, **kwargs)
|
||||
except CommandError:
|
||||
raise
|
||||
except asyncio.CancelledError:
|
||||
@ -56,10 +55,9 @@ def wrap_callback(coro):
|
||||
|
||||
def hooked_wrapped_callback(command, ctx, coro):
|
||||
@functools.wraps(coro)
|
||||
@asyncio.coroutine
|
||||
def wrapped(*args, **kwargs):
|
||||
async def wrapped(*args, **kwargs):
|
||||
try:
|
||||
ret = yield from coro(*args, **kwargs)
|
||||
ret = await coro(*args, **kwargs)
|
||||
except CommandError:
|
||||
ctx.command_failed = True
|
||||
raise
|
||||
@ -70,7 +68,7 @@ def hooked_wrapped_callback(command, ctx, coro):
|
||||
ctx.command_failed = True
|
||||
raise CommandInvokeError(e) from e
|
||||
finally:
|
||||
yield from command.call_after_hooks(ctx)
|
||||
await command.call_after_hooks(ctx)
|
||||
return ret
|
||||
return wrapped
|
||||
|
||||
@ -182,8 +180,7 @@ class Command:
|
||||
self._before_invoke = None
|
||||
self._after_invoke = None
|
||||
|
||||
@asyncio.coroutine
|
||||
def dispatch_error(self, ctx, error):
|
||||
async def dispatch_error(self, ctx, error):
|
||||
ctx.command_failed = True
|
||||
cog = self.instance
|
||||
try:
|
||||
@ -193,9 +190,9 @@ class Command:
|
||||
else:
|
||||
injected = wrap_callback(coro)
|
||||
if cog is not None:
|
||||
yield from injected(cog, ctx, error)
|
||||
await injected(cog, ctx, error)
|
||||
else:
|
||||
yield from injected(ctx, error)
|
||||
await injected(ctx, error)
|
||||
|
||||
try:
|
||||
local = getattr(cog, '_{0.__class__.__name__}__error'.format(cog))
|
||||
@ -203,7 +200,7 @@ class Command:
|
||||
pass
|
||||
else:
|
||||
wrapped = wrap_callback(local)
|
||||
yield from wrapped(ctx, error)
|
||||
await wrapped(ctx, error)
|
||||
finally:
|
||||
ctx.bot.dispatch('command_error', ctx, error)
|
||||
|
||||
@ -212,8 +209,7 @@ class Command:
|
||||
self.instance = instance
|
||||
return self
|
||||
|
||||
@asyncio.coroutine
|
||||
def do_conversion(self, ctx, converter, argument):
|
||||
async def do_conversion(self, ctx, converter, argument):
|
||||
if converter is bool:
|
||||
return _convert_to_bool(argument)
|
||||
|
||||
@ -228,15 +224,15 @@ class Command:
|
||||
if inspect.isclass(converter):
|
||||
if issubclass(converter, converters.Converter):
|
||||
instance = converter()
|
||||
ret = yield from instance.convert(ctx, argument)
|
||||
ret = await instance.convert(ctx, argument)
|
||||
return ret
|
||||
else:
|
||||
method = getattr(converter, 'convert', None)
|
||||
if method is not None and inspect.ismethod(method):
|
||||
ret = yield from method(ctx, argument)
|
||||
ret = await method(ctx, argument)
|
||||
return ret
|
||||
elif isinstance(converter, converters.Converter):
|
||||
ret = yield from converter.convert(ctx, argument)
|
||||
ret = await converter.convert(ctx, argument)
|
||||
return ret
|
||||
|
||||
return converter(argument)
|
||||
@ -250,8 +246,7 @@ class Command:
|
||||
converter = str
|
||||
return converter
|
||||
|
||||
@asyncio.coroutine
|
||||
def transform(self, ctx, param):
|
||||
async def transform(self, ctx, param):
|
||||
required = param.default is param.empty
|
||||
converter = self._get_converter(param)
|
||||
consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw
|
||||
@ -271,7 +266,7 @@ class Command:
|
||||
argument = quoted_word(view)
|
||||
|
||||
try:
|
||||
return (yield from self.do_conversion(ctx, converter, argument))
|
||||
return (await self.do_conversion(ctx, converter, argument))
|
||||
except CommandError as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
@ -354,8 +349,7 @@ class Command:
|
||||
def __str__(self):
|
||||
return self.qualified_name
|
||||
|
||||
@asyncio.coroutine
|
||||
def _parse_arguments(self, ctx):
|
||||
async def _parse_arguments(self, ctx):
|
||||
ctx.args = [ctx] if self.instance is None else [self.instance, ctx]
|
||||
ctx.kwargs = {}
|
||||
args = ctx.args
|
||||
@ -382,21 +376,21 @@ class Command:
|
||||
|
||||
for name, param in iterator:
|
||||
if param.kind == param.POSITIONAL_OR_KEYWORD:
|
||||
transformed = yield from self.transform(ctx, param)
|
||||
transformed = await self.transform(ctx, param)
|
||||
args.append(transformed)
|
||||
elif param.kind == param.KEYWORD_ONLY:
|
||||
# kwarg only param denotes "consume rest" semantics
|
||||
if self.rest_is_raw:
|
||||
converter = self._get_converter(param)
|
||||
argument = view.read_rest()
|
||||
kwargs[name] = yield from self.do_conversion(ctx, converter, argument)
|
||||
kwargs[name] = await self.do_conversion(ctx, converter, argument)
|
||||
else:
|
||||
kwargs[name] = yield from self.transform(ctx, param)
|
||||
kwargs[name] = await self.transform(ctx, param)
|
||||
break
|
||||
elif param.kind == param.VAR_POSITIONAL:
|
||||
while not view.eof:
|
||||
try:
|
||||
transformed = yield from self.transform(ctx, param)
|
||||
transformed = await self.transform(ctx, param)
|
||||
args.append(transformed)
|
||||
except RuntimeError:
|
||||
break
|
||||
@ -405,24 +399,22 @@ class Command:
|
||||
if not view.eof:
|
||||
raise TooManyArguments('Too many arguments passed to ' + self.qualified_name)
|
||||
|
||||
@asyncio.coroutine
|
||||
def _verify_checks(self, ctx):
|
||||
async def _verify_checks(self, ctx):
|
||||
if not self.enabled:
|
||||
raise DisabledCommand('{0.name} command is disabled'.format(self))
|
||||
|
||||
if not (yield from self.can_run(ctx)):
|
||||
if not (await self.can_run(ctx)):
|
||||
raise CheckFailure('The check functions for command {0.qualified_name} failed.'.format(self))
|
||||
|
||||
@asyncio.coroutine
|
||||
def call_before_hooks(self, ctx):
|
||||
async def call_before_hooks(self, ctx):
|
||||
# now that we're done preparing we can call the pre-command hooks
|
||||
# first, call the command local hook:
|
||||
cog = self.instance
|
||||
if self._before_invoke is not None:
|
||||
if cog is None:
|
||||
yield from self._before_invoke(ctx)
|
||||
await self._before_invoke(ctx)
|
||||
else:
|
||||
yield from self._before_invoke(cog, ctx)
|
||||
await self._before_invoke(cog, ctx)
|
||||
|
||||
# call the cog local hook if applicable:
|
||||
try:
|
||||
@ -430,37 +422,35 @@ class Command:
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
yield from hook(ctx)
|
||||
await hook(ctx)
|
||||
|
||||
# call the bot global hook if necessary
|
||||
hook = ctx.bot._before_invoke
|
||||
if hook is not None:
|
||||
yield from hook(ctx)
|
||||
await hook(ctx)
|
||||
|
||||
@asyncio.coroutine
|
||||
def call_after_hooks(self, ctx):
|
||||
async def call_after_hooks(self, ctx):
|
||||
cog = self.instance
|
||||
if self._after_invoke is not None:
|
||||
if cog is None:
|
||||
yield from self._after_invoke(ctx)
|
||||
await self._after_invoke(ctx)
|
||||
else:
|
||||
yield from self._after_invoke(cog, ctx)
|
||||
await self._after_invoke(cog, ctx)
|
||||
|
||||
try:
|
||||
hook = getattr(cog, '_{0.__class__.__name__}__after_invoke'.format(cog))
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
yield from hook(ctx)
|
||||
await hook(ctx)
|
||||
|
||||
hook = ctx.bot._after_invoke
|
||||
if hook is not None:
|
||||
yield from hook(ctx)
|
||||
await hook(ctx)
|
||||
|
||||
@asyncio.coroutine
|
||||
def prepare(self, ctx):
|
||||
async def prepare(self, ctx):
|
||||
ctx.command = self
|
||||
yield from self._verify_checks(ctx)
|
||||
await self._verify_checks(ctx)
|
||||
|
||||
if self._buckets.valid:
|
||||
bucket = self._buckets.get_bucket(ctx.message)
|
||||
@ -468,8 +458,8 @@ class Command:
|
||||
if retry_after:
|
||||
raise CommandOnCooldown(bucket, retry_after)
|
||||
|
||||
yield from self._parse_arguments(ctx)
|
||||
yield from self.call_before_hooks(ctx)
|
||||
await self._parse_arguments(ctx)
|
||||
await self.call_before_hooks(ctx)
|
||||
|
||||
def is_on_cooldown(self, ctx):
|
||||
"""Checks whether the command is currently on cooldown.
|
||||
@ -502,34 +492,32 @@ class Command:
|
||||
bucket = self._buckets.get_bucket(ctx.message)
|
||||
bucket.reset()
|
||||
|
||||
@asyncio.coroutine
|
||||
def invoke(self, ctx):
|
||||
yield from self.prepare(ctx)
|
||||
async def invoke(self, ctx):
|
||||
await self.prepare(ctx)
|
||||
|
||||
# terminate the invoked_subcommand chain.
|
||||
# since we're in a regular command (and not a group) then
|
||||
# the invoked subcommand is None.
|
||||
ctx.invoked_subcommand = None
|
||||
injected = hooked_wrapped_callback(self, ctx, self.callback)
|
||||
yield from injected(*ctx.args, **ctx.kwargs)
|
||||
await injected(*ctx.args, **ctx.kwargs)
|
||||
|
||||
@asyncio.coroutine
|
||||
def reinvoke(self, ctx, *, call_hooks=False):
|
||||
async def reinvoke(self, ctx, *, call_hooks=False):
|
||||
ctx.command = self
|
||||
yield from self._parse_arguments(ctx)
|
||||
await self._parse_arguments(ctx)
|
||||
|
||||
if call_hooks:
|
||||
yield from self.call_before_hooks(ctx)
|
||||
await self.call_before_hooks(ctx)
|
||||
|
||||
ctx.invoked_subcommand = None
|
||||
try:
|
||||
yield from self.callback(*ctx.args, **ctx.kwargs)
|
||||
await self.callback(*ctx.args, **ctx.kwargs)
|
||||
except:
|
||||
ctx.command_failed = True
|
||||
raise
|
||||
finally:
|
||||
if call_hooks:
|
||||
yield from self.call_after_hooks(ctx)
|
||||
await self.call_after_hooks(ctx)
|
||||
|
||||
def error(self, coro):
|
||||
"""A decorator that registers a coroutine as a local error handler.
|
||||
@ -667,8 +655,7 @@ class Command:
|
||||
|
||||
return ' '.join(result)
|
||||
|
||||
@asyncio.coroutine
|
||||
def can_run(self, ctx):
|
||||
async def can_run(self, ctx):
|
||||
"""|coro|
|
||||
|
||||
Checks if the command can be executed by checking all the predicates
|
||||
@ -695,7 +682,7 @@ class Command:
|
||||
ctx.command = self
|
||||
|
||||
try:
|
||||
if not (yield from ctx.bot.can_run(ctx)):
|
||||
if not (await ctx.bot.can_run(ctx)):
|
||||
raise CheckFailure('The global check functions for command {0.qualified_name} failed.'.format(self))
|
||||
|
||||
cog = self.instance
|
||||
@ -705,7 +692,7 @@ class Command:
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
ret = yield from discord.utils.maybe_coroutine(local_check, ctx)
|
||||
ret = await discord.utils.maybe_coroutine(local_check, ctx)
|
||||
if not ret:
|
||||
return False
|
||||
|
||||
@ -714,7 +701,7 @@ class Command:
|
||||
# since we have no checks, then we just return True.
|
||||
return True
|
||||
|
||||
return (yield from discord.utils.async_all(predicate(ctx) for predicate in predicates))
|
||||
return (await discord.utils.async_all(predicate(ctx) for predicate in predicates))
|
||||
finally:
|
||||
ctx.command = original
|
||||
|
||||
@ -903,11 +890,10 @@ class Group(GroupMixin, Command):
|
||||
self.invoke_without_command = attrs.pop('invoke_without_command', False)
|
||||
super().__init__(**attrs)
|
||||
|
||||
@asyncio.coroutine
|
||||
def invoke(self, ctx):
|
||||
async def invoke(self, ctx):
|
||||
early_invoke = not self.invoke_without_command
|
||||
if early_invoke:
|
||||
yield from self.prepare(ctx)
|
||||
await self.prepare(ctx)
|
||||
|
||||
view = ctx.view
|
||||
previous = view.index
|
||||
@ -920,26 +906,25 @@ class Group(GroupMixin, Command):
|
||||
|
||||
if early_invoke:
|
||||
injected = hooked_wrapped_callback(self, ctx, self.callback)
|
||||
yield from injected(*ctx.args, **ctx.kwargs)
|
||||
await injected(*ctx.args, **ctx.kwargs)
|
||||
|
||||
if trigger and ctx.invoked_subcommand:
|
||||
ctx.invoked_with = trigger
|
||||
yield from ctx.invoked_subcommand.invoke(ctx)
|
||||
await ctx.invoked_subcommand.invoke(ctx)
|
||||
elif not early_invoke:
|
||||
# undo the trigger parsing
|
||||
view.index = previous
|
||||
view.previous = previous
|
||||
yield from super().invoke(ctx)
|
||||
await super().invoke(ctx)
|
||||
|
||||
@asyncio.coroutine
|
||||
def reinvoke(self, ctx, *, call_hooks=False):
|
||||
async def reinvoke(self, ctx, *, call_hooks=False):
|
||||
early_invoke = not self.invoke_without_command
|
||||
if early_invoke:
|
||||
ctx.command = self
|
||||
yield from self._parse_arguments(ctx)
|
||||
await self._parse_arguments(ctx)
|
||||
|
||||
if call_hooks:
|
||||
yield from self.call_before_hooks(ctx)
|
||||
await self.call_before_hooks(ctx)
|
||||
|
||||
view = ctx.view
|
||||
previous = view.index
|
||||
@ -952,22 +937,22 @@ class Group(GroupMixin, Command):
|
||||
|
||||
if early_invoke:
|
||||
try:
|
||||
yield from self.callback(*ctx.args, **ctx.kwargs)
|
||||
await self.callback(*ctx.args, **ctx.kwargs)
|
||||
except:
|
||||
ctx.command_failed = True
|
||||
raise
|
||||
finally:
|
||||
if call_hooks:
|
||||
yield from self.call_after_hooks(ctx)
|
||||
await self.call_after_hooks(ctx)
|
||||
|
||||
if trigger and ctx.invoked_subcommand:
|
||||
ctx.invoked_with = trigger
|
||||
yield from ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks)
|
||||
await ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks)
|
||||
elif not early_invoke:
|
||||
# undo the trigger parsing
|
||||
view.index = previous
|
||||
view.previous = previous
|
||||
yield from super().reinvoke(ctx, call_hooks=call_hooks)
|
||||
await super().reinvoke(ctx, call_hooks=call_hooks)
|
||||
|
||||
# Decorators
|
||||
|
||||
@ -1279,9 +1264,8 @@ def is_owner():
|
||||
from :exc:`.CheckFailure`.
|
||||
"""
|
||||
|
||||
@asyncio.coroutine
|
||||
def predicate(ctx):
|
||||
if not (yield from ctx.bot.is_owner(ctx.author)):
|
||||
async def predicate(ctx):
|
||||
if not (await ctx.bot.is_owner(ctx.author)):
|
||||
raise NotOwner('You do not own this bot.')
|
||||
return True
|
||||
|
||||
|
@ -199,8 +199,7 @@ class HelpFormatter:
|
||||
return "Type {0}{1} command for more info on a command.\n" \
|
||||
"You can also type {0}{1} category for more info on a category.".format(self.clean_prefix, command_name)
|
||||
|
||||
@asyncio.coroutine
|
||||
def filter_command_list(self):
|
||||
async def filter_command_list(self):
|
||||
"""Returns a filtered list of commands based on the two attributes
|
||||
provided, :attr:`show_check_failure` and :attr:`show_hidden`.
|
||||
Also filters based on if :meth:`~.HelpFormatter.is_cog` is valid.
|
||||
@ -224,14 +223,13 @@ class HelpFormatter:
|
||||
|
||||
return True
|
||||
|
||||
@asyncio.coroutine
|
||||
def predicate(tup):
|
||||
async def predicate(tup):
|
||||
if sane_no_suspension_point_predicate(tup) is False:
|
||||
return False
|
||||
|
||||
cmd = tup[1]
|
||||
try:
|
||||
return (yield from cmd.can_run(self.context))
|
||||
return (await cmd.can_run(self.context))
|
||||
except CommandError:
|
||||
return False
|
||||
|
||||
@ -242,7 +240,7 @@ class HelpFormatter:
|
||||
# Gotta run every check and verify it
|
||||
ret = []
|
||||
for elem in iterator:
|
||||
valid = yield from predicate(elem)
|
||||
valid = await predicate(elem)
|
||||
if valid:
|
||||
ret.append(elem)
|
||||
|
||||
@ -258,8 +256,7 @@ class HelpFormatter:
|
||||
shortened = self.shorten(entry)
|
||||
self._paginator.add_line(shortened)
|
||||
|
||||
@asyncio.coroutine
|
||||
def format_help_for(self, context, command_or_bot):
|
||||
async def format_help_for(self, context, command_or_bot):
|
||||
"""Formats the help page and handles the actual heavy lifting of how
|
||||
the help command looks like. To change the behaviour, override the
|
||||
:meth:`~.HelpFormatter.format` method.
|
||||
@ -278,10 +275,9 @@ class HelpFormatter:
|
||||
"""
|
||||
self.context = context
|
||||
self.command = command_or_bot
|
||||
return (yield from self.format())
|
||||
return (await self.format())
|
||||
|
||||
@asyncio.coroutine
|
||||
def format(self):
|
||||
async def format(self):
|
||||
"""Handles the actual behaviour involved with formatting.
|
||||
|
||||
To change the behaviour, this method should be overridden.
|
||||
@ -323,7 +319,7 @@ class HelpFormatter:
|
||||
# last place sorting position.
|
||||
return cog + ':' if cog is not None else '\u200bNo Category:'
|
||||
|
||||
filtered = yield from self.filter_command_list()
|
||||
filtered = await self.filter_command_list()
|
||||
if self.is_bot():
|
||||
data = sorted(filtered, key=category)
|
||||
for category, commands in itertools.groupby(data, key=category):
|
||||
|
Reference in New Issue
Block a user