From e10cae5dbc496e9e996729af53ba522561b7fe47 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Mon, 13 Feb 2017 21:01:51 -0500 Subject: [PATCH] [commands] Allow converters to be instantiated. 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. --- discord/ext/commands/converter.py | 8 +++++--- discord/ext/commands/core.py | 14 +++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index a6f921fe1..d89b163e3 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -54,6 +54,9 @@ class Converter: to do its conversion logic. This method could be a coroutine or a regular function. + Before the convert method is called, :meth:`prepare` is called. This + method must set the attributes below if overwritten. + Attributes ----------- ctx: :class:`Context` @@ -61,7 +64,7 @@ class Converter: argument: str The argument that is being converted. """ - def __init__(self, ctx, argument): + def prepare(self, ctx, argument): self.ctx = ctx self.argument = argument @@ -69,8 +72,7 @@ class Converter: raise NotImplementedError('Derived classes need to implement this.') class IDConverter(Converter): - def __init__(self, ctx, argument): - super().__init__(ctx, argument) + def __init__(self): self._id_regex = re.compile(r'([0-9]{15,21})$') def _get_id_match(self): diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index a688b84a6..2c683b241 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -203,11 +203,15 @@ class Command: converter = getattr(converters, converter.__name__ + 'Converter') if inspect.isclass(converter) and issubclass(converter, converters.Converter): - instance = converter(ctx, argument) - if asyncio.iscoroutinefunction(instance.convert): - return (yield from instance.convert()) - else: - return instance.convert() + instance = converter() + instance.prepare(ctx, argument) + ret = yield from discord.utils.maybe_coroutine(instance.convert) + return ret + + if isinstance(converter, converters.Converter): + converter.prepare(ctx, argument) + ret = yield from discord.utils.maybe_coroutine(converter.convert) + return ret return converter(argument)