Add app_commands.Parameter for parameter introspection

This commit is contained in:
Rapptz 2022-08-09 07:43:40 -04:00
parent 0e386ec2cc
commit 1727eca106
3 changed files with 130 additions and 23 deletions

View File

@ -48,7 +48,7 @@ from textwrap import TextWrapper
import re import re
from ..enums import AppCommandOptionType, AppCommandType, Locale from ..enums import AppCommandOptionType, AppCommandType, ChannelType, Locale
from .models import Choice from .models import Choice
from .transformers import annotation_to_parameter, CommandParameter, NoneType from .transformers import annotation_to_parameter, CommandParameter, NoneType
from .errors import AppCommandError, CheckFailure, CommandInvokeError, CommandSignatureMismatch, CommandAlreadyRegistered from .errors import AppCommandError, CheckFailure, CommandInvokeError, CommandSignatureMismatch, CommandAlreadyRegistered
@ -77,6 +77,7 @@ __all__ = (
'Command', 'Command',
'ContextMenu', 'ContextMenu',
'Group', 'Group',
'Parameter',
'context_menu', 'context_menu',
'command', 'command',
'describe', 'describe',
@ -457,6 +458,104 @@ def _get_context_menu_parameter(func: ContextMenuCallback) -> Tuple[str, Any, Ap
return (parameter.name, resolved, type) return (parameter.name, resolved, type)
class Parameter:
"""A class that contains the parameter information of a :class:`Command` callback.
.. versionadded:: 2.0
Attributes
-----------
name: :class:`str`
The name of the parameter. This is the Python identifier for the parameter.
display_name: :class:`str`
The displayed name of the parameter on Discord.
description: :class:`str`
The description of the parameter.
autocomplete: :class:`bool`
Whether the parameter has an autocomplete handler.
locale_name: Optional[:class:`locale_str`]
The display name's locale string, if available.
locale_description: Optional[:class:`locale_str`]
The description's locale string, if available.
required: :class:`bool`
Whether the parameter is required
choices: List[:class:`~discord.app_commands.Choice`]
A list of choices this parameter takes, if any.
type: :class:`~discord.AppCommandOptionType`
The underlying type of this parameter.
channel_types: List[:class:`~discord.ChannelType`]
The channel types that are allowed for this parameter.
min_value: Optional[Union[:class:`int`, :class:`float`]]
The minimum supported value for this parameter.
max_value: Optional[Union[:class:`int`, :class:`float`]]
The maximum supported value for this parameter.
default: Any
The default value of the parameter, if given.
If not given then this is :data:`discord.utils.MISSING`.
"""
def __init__(self, parent: CommandParameter) -> None:
self.__parent: CommandParameter = parent
@property
def name(self) -> str:
return self.__parent.name
@property
def display_name(self) -> str:
return self.__parent.display_name
@property
def description(self) -> str:
return str(self.__parent.description)
@property
def locale_name(self) -> Optional[locale_str]:
if isinstance(self.__parent._rename, locale_str):
return self.__parent._rename
return None
@property
def locale_description(self) -> Optional[locale_str]:
if isinstance(self.__parent.description, locale_str):
return self.__parent.description
return None
@property
def autocomplete(self) -> bool:
return self.__parent.autocomplete is not None
@property
def default(self) -> Any:
return self.__parent.default
@property
def type(self) -> AppCommandOptionType:
return self.__parent.type
@property
def choices(self) -> List[Choice[Union[int, float, str]]]:
choices = self.__parent.choices
if choices is MISSING:
return []
return choices.copy()
@property
def channel_types(self) -> List[ChannelType]:
channel_types = self.__parent.channel_types
if channel_types is MISSING:
return []
return channel_types.copy()
@property
def min_value(self) -> Optional[Union[int, float]]:
return self.__parent.min_value
@property
def max_value(self) -> Optional[Union[int, float]]:
return self.__parent.max_value
class Command(Generic[GroupT, P, T]): class Command(Generic[GroupT, P, T]):
"""A class that implements an application command. """A class that implements an application command.
@ -807,6 +906,28 @@ class Command(Generic[GroupT, P, T]):
def _get_internal_command(self, name: str) -> Optional[Union[Command, Group]]: def _get_internal_command(self, name: str) -> Optional[Union[Command, Group]]:
return None return None
def get_parameter(self, name: str) -> Optional[Parameter]:
"""Retrieves a parameter by its name.
The name must be the Python identifier rather than the renamed
one for display on Discord.
Parameters
-----------
name: :class:`str`
The parameter name in the callback function.
Returns
--------
Optional[:class:`Parameter`]
The parameter or ``None`` if not found.
"""
parent = self._params.get(name)
if parent is not None:
return Parameter(parent)
return None
@property @property
def root_parent(self) -> Optional[Group]: def root_parent(self) -> Optional[Group]:
"""Optional[:class:`Group`]: The root parent of this command.""" """Optional[:class:`Group`]: The root parent of this command."""

View File

@ -74,28 +74,6 @@ if TYPE_CHECKING:
@dataclass @dataclass
class CommandParameter: class CommandParameter:
"""Represents an application command parameter.
Attributes
-----------
name: :class:`str`
The name of the parameter.
description: :class:`str`
The description of the parameter
required: :class:`bool`
Whether the parameter is required
choices: List[:class:`~discord.app_commands.Choice`]
A list of choices this parameter takes
type: :class:`~discord.AppCommandOptionType`
The underlying type of this parameter.
channel_types: List[:class:`~discord.ChannelType`]
The channel types that are allowed for this parameter.
min_value: Optional[Union[:class:`int`, :class:`float`]]
The minimum supported value for this parameter.
max_value: Optional[Union[:class:`int`, :class:`float`]]
The maximum supported value for this parameter.
"""
# The name of the parameter is *always* the parameter name in the code # The name of the parameter is *always* the parameter name in the code
# Therefore, it can't be Union[str, locale_str] # Therefore, it can't be Union[str, locale_str]
name: str = MISSING name: str = MISSING

View File

@ -482,6 +482,14 @@ Command
.. autoclass:: discord.app_commands.Command .. autoclass:: discord.app_commands.Command
:members: :members:
Parameter
++++++++++
.. attributetable:: discord.app_commands.Parameter
.. autoclass:: discord.app_commands.Parameter()
:members:
ContextMenu ContextMenu
++++++++++++ ++++++++++++