[commands] Add support for typing.Annotated

This commit is contained in:
Rapptz 2022-04-22 06:21:10 -04:00
parent ab33551553
commit 5fcd4e411f
3 changed files with 35 additions and 0 deletions

View File

@ -625,6 +625,9 @@ def get_supported_annotation(
if hasattr(annotation, '__discord_app_commands_transform__'):
return (annotation.metadata, MISSING)
if hasattr(annotation, '__metadata__'):
return get_supported_annotation(annotation.__metadata__[0])
if inspect.isclass(annotation):
if issubclass(annotation, Transformer):
return (annotation, MISSING)

View File

@ -161,6 +161,12 @@ def get_signature_parameters(
if annotation is Greedy:
raise TypeError('Unparameterized Greedy[...] is disallowed in signature.')
if hasattr(annotation, '__metadata__'):
# Annotated[X, Y] can access Y via __metadata__
metadata = annotation.__metadata__
if len(metadata) >= 1:
annotation = metadata[0]
if isinstance(annotation, discord.app_commands.transformers._TransformMetadata):
annotation = annotation.metadata

View File

@ -530,6 +530,8 @@ resumes handling, which in this case would be to pass it into the ``liquid`` par
typing.Literal
^^^^^^^^^^^^^^^^
.. versionadded:: 2.0
A :data:`typing.Literal` is a special type hint that requires the passed parameter to be equal to one of the listed values
after being converted to the same type. For example, given the following:
@ -548,6 +550,30 @@ The ``buy_sell`` parameter must be either the literal string ``"buy"`` or ``"sel
Note that ``typing.Literal[True]`` and ``typing.Literal[False]`` still follow the :class:`bool` converter rules.
typing.Annotated
^^^^^^^^^^^^^^^^^
.. versionadded:: 2.0
A :data:`typing.Annotated` is a special type introduced in Python 3.9 that allows the type checker to see one type, but allows the library to see another type. This is useful for appeasing the type checker for complicated converters. The second parameter of ``Annotated`` must be the converter that the library should use.
For example, given the following:
.. code-block:: python3
from typing import Annotated
@bot.command()
async def fun(ctx, arg: Annotated[str, lambda s: s.upper()]):
await ctx.send(arg)
The type checker will see ``arg`` as a regular :class:`str` but the library will know you wanted to change the input into all upper-case.
.. note::
For Python versions below 3.9, it is recommended to install the ``typing_extensions`` library and import ``Annotated`` from there.
Greedy
^^^^^^^^