[commands] Implement commands.parameter

This commit is contained in:
James Hilton-Balfe
2022-04-04 23:01:21 +01:00
committed by GitHub
parent deb7958797
commit 55c5be78cf
11 changed files with 435 additions and 148 deletions

View File

@ -429,6 +429,35 @@ Flag Converter
.. autofunction:: discord.ext.commands.flag
Defaults
--------
.. autoclass:: discord.ext.commands.Parameter()
:members:
.. autofunction:: discord.ext.commands.parameter
.. autofunction:: discord.ext.commands.param
.. data:: discord.ext.commands.Author
A default :class:`.Parameter` which returns the :attr:`~.Context.author` for this context.
.. versionadded:: 2.0
.. data:: discord.ext.commands.CurrentChannel
A default :class:`.Parameter` which returns the :attr:`~.Context.channel` for this context.
.. versionadded:: 2.0
.. data:: discord.ext.commands.CurrentGuild
A default :class:`.Parameter` which returns the :attr:`~.Context.guild` for this context. This will never be ``None``.
.. versionadded:: 2.0
.. _ext_commands_api_errors:
Exceptions

View File

@ -768,6 +768,58 @@ A :class:`dict` annotation is functionally equivalent to ``List[Tuple[K, V]]`` e
given as a :class:`dict` rather than a :class:`list`.
.. _ext_commands_parameter:
Parameter Metadata
-------------------
:func:`~ext.commands.parameter` assigns custom metadata to a :class:`~ext.commands.Command`'s parameter.
This is useful for:
- Custom converters as annotating a parameter with a custom converter works at runtime, type checkers don't like it
because they can't understand what's going on.
.. code-block:: python3
class SomeType:
foo: int
class MyVeryCoolConverter(commands.Converter[SomeType]):
... # implementation left as an exercise for the reader
@bot.command()
async def bar(ctx, cool_value: MyVeryCoolConverter):
cool_value.foo # type checker warns MyVeryCoolConverter has no value foo (uh-oh)
However, fear not we can use :func:`~ext.commands.parameter` to tell type checkers what's going on.
.. code-block:: python3
@bot.command()
async def bar(ctx, cool_value: SomeType = commands.parameter(converter=MyVeryCoolConverter)):
cool_value.foo # no error (hurray)
- Late binding behaviour
.. code-block:: python3
@bot.command()
async def wave(to: discord.User = commands.parameter(default=lambda ctx: ctx.author)):
await ctx.send(f'Hello {to.mention} :wave:')
Because this is such a common use-case, the library provides :obj:`~.ext.commands.Author`, :obj:`~.ext.commands.CurrentChannel` and
:obj:`~.ext.commands.CurrentGuild`, armed with this we can simplify ``wave`` to:
.. code-block:: python3
@bot.command()
async def wave(to: discord.User = commands.Author):
await ctx.send(f'Hello {to.mention} :wave:')
:obj:`~.ext.commands.Author` and co also have other benefits like having the displayed default being filled.
.. _ext_commands_error_handler:
Error Handling

View File

@ -112,7 +112,7 @@ Quick example:
With this change, constructor of :class:`Client` no longer accepts ``connector`` and ``loop`` parameters.
In parallel with this change, changes were made to loading and unloading of commands extension extensions and cogs,
In parallel with this change, changes were made to loading and unloading of commands extension extensions and cogs,
see :ref:`migrating_2_0_commands_extension_cog_async` for more information.
Abstract Base Classes Changes
@ -1240,7 +1240,7 @@ Quick example of loading an extension:
async with bot:
await bot.load_extension('my_extension')
await bot.start(TOKEN)
asyncio.run(main())
@ -1422,6 +1422,7 @@ Miscellaneous Changes
- ``BotMissingPermissions.missing_perms`` has been renamed to :attr:`ext.commands.BotMissingPermissions.missing_permissions`.
- :meth:`ext.commands.Cog.cog_load` has been added as part of the :ref:`migrating_2_0_commands_extension_cog_async` changes.
- :meth:`ext.commands.Cog.cog_unload` may now be a :term:`coroutine` due to the :ref:`migrating_2_0_commands_extension_cog_async` changes.
- :attr:`ext.commands.Command.clean_params` type now uses a custom :class:`inspect.Parameter` to handle defaults.
.. _migrating_2_0_tasks: