mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-09-07 10:22:59 +00:00
Fix typing issues and improve typing completeness across the library
Co-authored-by: Danny <Rapptz@users.noreply.github.com> Co-authored-by: Josh <josh.ja.butt@gmail.com>
This commit is contained in:
@ -166,7 +166,7 @@ def _validate_auto_complete_callback(
|
||||
return callback
|
||||
|
||||
|
||||
def _context_menu_annotation(annotation: Any, *, _none=NoneType) -> AppCommandType:
|
||||
def _context_menu_annotation(annotation: Any, *, _none: type = NoneType) -> AppCommandType:
|
||||
if annotation is Message:
|
||||
return AppCommandType.message
|
||||
|
||||
@ -686,7 +686,7 @@ class Group:
|
||||
The parent group. ``None`` if there isn't one.
|
||||
"""
|
||||
|
||||
__discord_app_commands_group_children__: ClassVar[List[Union[Command, Group]]] = []
|
||||
__discord_app_commands_group_children__: ClassVar[List[Union[Command[Any, ..., Any], Group]]] = []
|
||||
__discord_app_commands_skip_init_binding__: bool = False
|
||||
__discord_app_commands_group_name__: str = MISSING
|
||||
__discord_app_commands_group_description__: str = MISSING
|
||||
@ -694,10 +694,12 @@ class Group:
|
||||
|
||||
def __init_subclass__(cls, *, name: str = MISSING, description: str = MISSING) -> None:
|
||||
if not cls.__discord_app_commands_group_children__:
|
||||
cls.__discord_app_commands_group_children__ = children = [
|
||||
children: List[Union[Command[Any, ..., Any], Group]] = [
|
||||
member for member in cls.__dict__.values() if isinstance(member, (Group, Command)) and member.parent is None
|
||||
]
|
||||
|
||||
cls.__discord_app_commands_group_children__ = children
|
||||
|
||||
found = set()
|
||||
for child in children:
|
||||
if child.name in found:
|
||||
@ -796,15 +798,15 @@ class Group:
|
||||
"""Optional[:class:`Group`]: The parent of this group."""
|
||||
return self.parent
|
||||
|
||||
def _get_internal_command(self, name: str) -> Optional[Union[Command, Group]]:
|
||||
def _get_internal_command(self, name: str) -> Optional[Union[Command[Any, ..., Any], Group]]:
|
||||
return self._children.get(name)
|
||||
|
||||
@property
|
||||
def commands(self) -> List[Union[Command, Group]]:
|
||||
def commands(self) -> List[Union[Command[Any, ..., Any], Group]]:
|
||||
"""List[Union[:class:`Command`, :class:`Group`]]: The commands that this group contains."""
|
||||
return list(self._children.values())
|
||||
|
||||
async def on_error(self, interaction: Interaction, command: Command, error: AppCommandError) -> None:
|
||||
async def on_error(self, interaction: Interaction, command: Command[Any, ..., Any], error: AppCommandError) -> None:
|
||||
"""|coro|
|
||||
|
||||
A callback that is called when a child's command raises an :exc:`AppCommandError`.
|
||||
@ -823,7 +825,7 @@ class Group:
|
||||
|
||||
pass
|
||||
|
||||
def add_command(self, command: Union[Command, Group], /, *, override: bool = False):
|
||||
def add_command(self, command: Union[Command[Any, ..., Any], Group], /, *, override: bool = False) -> None:
|
||||
"""Adds a command or group to this group's internal list of commands.
|
||||
|
||||
Parameters
|
||||
@ -855,7 +857,7 @@ class Group:
|
||||
if len(self._children) > 25:
|
||||
raise ValueError('maximum number of child commands exceeded')
|
||||
|
||||
def remove_command(self, name: str, /) -> Optional[Union[Command, Group]]:
|
||||
def remove_command(self, name: str, /) -> Optional[Union[Command[Any, ..., Any], Group]]:
|
||||
"""Removes a command or group from the internal list of commands.
|
||||
|
||||
Parameters
|
||||
@ -872,7 +874,7 @@ class Group:
|
||||
|
||||
self._children.pop(name, None)
|
||||
|
||||
def get_command(self, name: str, /) -> Optional[Union[Command, Group]]:
|
||||
def get_command(self, name: str, /) -> Optional[Union[Command[Any, ..., Any], Group]]:
|
||||
"""Retrieves a command or group from its name.
|
||||
|
||||
Parameters
|
||||
@ -1046,7 +1048,7 @@ def describe(**parameters: str) -> Callable[[T], T]:
|
||||
return decorator
|
||||
|
||||
|
||||
def choices(**parameters: List[Choice]) -> Callable[[T], T]:
|
||||
def choices(**parameters: List[Choice[ChoiceT]]) -> Callable[[T], T]:
|
||||
r"""Instructs the given parameters by their name to use the given choices for their choices.
|
||||
|
||||
Example:
|
||||
|
@ -79,9 +79,9 @@ class CommandInvokeError(AppCommandError):
|
||||
The command that failed.
|
||||
"""
|
||||
|
||||
def __init__(self, command: Union[Command, ContextMenu], e: Exception) -> None:
|
||||
def __init__(self, command: Union[Command[Any, ..., Any], ContextMenu], e: Exception) -> None:
|
||||
self.original: Exception = e
|
||||
self.command: Union[Command, ContextMenu] = command
|
||||
self.command: Union[Command[Any, ..., Any], ContextMenu] = command
|
||||
super().__init__(f'Command {command.name!r} raised an exception: {e.__class__.__name__}: {e}')
|
||||
|
||||
|
||||
@ -191,8 +191,8 @@ class CommandSignatureMismatch(AppCommandError):
|
||||
The command that had the signature mismatch.
|
||||
"""
|
||||
|
||||
def __init__(self, command: Union[Command, ContextMenu, Group]):
|
||||
self.command: Union[Command, ContextMenu, Group] = command
|
||||
def __init__(self, command: Union[Command[Any, ..., Any], ContextMenu, Group]):
|
||||
self.command: Union[Command[Any, ..., Any], ContextMenu, Group] = command
|
||||
msg = (
|
||||
f'The signature for command {command.name!r} is different from the one provided by Discord. '
|
||||
'This can happen because either your code is out of date or you have not synced the '
|
||||
|
@ -58,7 +58,10 @@ if TYPE_CHECKING:
|
||||
PartialChannel,
|
||||
PartialThread,
|
||||
)
|
||||
from ..types.threads import ThreadMetadata
|
||||
from ..types.threads import (
|
||||
ThreadMetadata,
|
||||
ThreadArchiveDuration,
|
||||
)
|
||||
from ..state import ConnectionState
|
||||
from ..guild import GuildChannel, Guild
|
||||
from ..channel import TextChannel
|
||||
@ -117,17 +120,19 @@ class AppCommand(Hashable):
|
||||
'_state',
|
||||
)
|
||||
|
||||
def __init__(self, *, data: ApplicationCommandPayload, state=None):
|
||||
self._state = state
|
||||
def __init__(self, *, data: ApplicationCommandPayload, state: Optional[ConnectionState] = None) -> None:
|
||||
self._state: Optional[ConnectionState] = state
|
||||
self._from_data(data)
|
||||
|
||||
def _from_data(self, data: ApplicationCommandPayload):
|
||||
def _from_data(self, data: ApplicationCommandPayload) -> None:
|
||||
self.id: int = int(data['id'])
|
||||
self.application_id: int = int(data['application_id'])
|
||||
self.name: str = data['name']
|
||||
self.description: str = data['description']
|
||||
self.type: AppCommandType = try_enum(AppCommandType, data.get('type', 1))
|
||||
self.options = [app_command_option_factory(data=d, parent=self, state=self._state) for d in data.get('options', [])]
|
||||
self.options: List[Union[Argument, AppCommandGroup]] = [
|
||||
app_command_option_factory(data=d, parent=self, state=self._state) for d in data.get('options', [])
|
||||
]
|
||||
|
||||
def to_dict(self) -> ApplicationCommandPayload:
|
||||
return {
|
||||
@ -262,12 +267,12 @@ class AppCommandChannel(Hashable):
|
||||
data: PartialChannel,
|
||||
guild_id: int,
|
||||
):
|
||||
self._state = state
|
||||
self.guild_id = guild_id
|
||||
self.id = int(data['id'])
|
||||
self.type = try_enum(ChannelType, data['type'])
|
||||
self.name = data['name']
|
||||
self.permissions = Permissions(int(data['permissions']))
|
||||
self._state: ConnectionState = state
|
||||
self.guild_id: int = guild_id
|
||||
self.id: int = int(data['id'])
|
||||
self.type: ChannelType = try_enum(ChannelType, data['type'])
|
||||
self.name: str = data['name']
|
||||
self.permissions: Permissions = Permissions(int(data['permissions']))
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
@ -405,13 +410,13 @@ class AppCommandThread(Hashable):
|
||||
data: PartialThread,
|
||||
guild_id: int,
|
||||
):
|
||||
self._state = state
|
||||
self.guild_id = guild_id
|
||||
self.id = int(data['id'])
|
||||
self.parent_id = int(data['parent_id'])
|
||||
self.type = try_enum(ChannelType, data['type'])
|
||||
self.name = data['name']
|
||||
self.permissions = Permissions(int(data['permissions']))
|
||||
self._state: ConnectionState = state
|
||||
self.guild_id: int = guild_id
|
||||
self.id: int = int(data['id'])
|
||||
self.parent_id: int = int(data['parent_id'])
|
||||
self.type: ChannelType = try_enum(ChannelType, data['type'])
|
||||
self.name: str = data['name']
|
||||
self.permissions: Permissions = Permissions(int(data['permissions']))
|
||||
self._unroll_metadata(data['thread_metadata'])
|
||||
|
||||
def __str__(self) -> str:
|
||||
@ -425,14 +430,14 @@ class AppCommandThread(Hashable):
|
||||
"""Optional[:class:`~discord.Guild`]: The channel's guild, from cache, if found."""
|
||||
return self._state._get_guild(self.guild_id)
|
||||
|
||||
def _unroll_metadata(self, data: ThreadMetadata):
|
||||
self.archived = data['archived']
|
||||
self.archiver_id = _get_as_snowflake(data, 'archiver_id')
|
||||
self.auto_archive_duration = data['auto_archive_duration']
|
||||
self.archive_timestamp = parse_time(data['archive_timestamp'])
|
||||
self.locked = data.get('locked', False)
|
||||
self.invitable = data.get('invitable', True)
|
||||
self._created_at = parse_time(data.get('create_timestamp'))
|
||||
def _unroll_metadata(self, data: ThreadMetadata) -> None:
|
||||
self.archived: bool = data['archived']
|
||||
self.archiver_id: Optional[int] = _get_as_snowflake(data, 'archiver_id')
|
||||
self.auto_archive_duration: ThreadArchiveDuration = data['auto_archive_duration']
|
||||
self.archive_timestamp: datetime = parse_time(data['archive_timestamp'])
|
||||
self.locked: bool = data.get('locked', False)
|
||||
self.invitable: bool = data.get('invitable', True)
|
||||
self._created_at: Optional[datetime] = parse_time(data.get('create_timestamp'))
|
||||
|
||||
@property
|
||||
def parent(self) -> Optional[TextChannel]:
|
||||
@ -522,20 +527,24 @@ class Argument:
|
||||
'_state',
|
||||
)
|
||||
|
||||
def __init__(self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state=None):
|
||||
self._state = state
|
||||
self.parent = parent
|
||||
def __init__(
|
||||
self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state: Optional[ConnectionState] = None
|
||||
) -> None:
|
||||
self._state: Optional[ConnectionState] = state
|
||||
self.parent: ApplicationCommandParent = parent
|
||||
self._from_data(data)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<{self.__class__.__name__} name={self.name!r} type={self.type!r} required={self.required}>'
|
||||
|
||||
def _from_data(self, data: ApplicationCommandOption):
|
||||
def _from_data(self, data: ApplicationCommandOption) -> None:
|
||||
self.type: AppCommandOptionType = try_enum(AppCommandOptionType, data['type'])
|
||||
self.name: str = data['name']
|
||||
self.description: str = data['description']
|
||||
self.required: bool = data.get('required', False)
|
||||
self.choices: List[Choice] = [Choice(name=d['name'], value=d['value']) for d in data.get('choices', [])]
|
||||
self.choices: List[Choice[Union[int, float, str]]] = [
|
||||
Choice(name=d['name'], value=d['value']) for d in data.get('choices', [])
|
||||
]
|
||||
|
||||
def to_dict(self) -> ApplicationCommandOption:
|
||||
return {
|
||||
@ -582,20 +591,24 @@ class AppCommandGroup:
|
||||
'_state',
|
||||
)
|
||||
|
||||
def __init__(self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state=None):
|
||||
self.parent = parent
|
||||
self._state = state
|
||||
def __init__(
|
||||
self, *, parent: ApplicationCommandParent, data: ApplicationCommandOption, state: Optional[ConnectionState] = None
|
||||
) -> None:
|
||||
self.parent: ApplicationCommandParent = parent
|
||||
self._state: Optional[ConnectionState] = state
|
||||
self._from_data(data)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<{self.__class__.__name__} name={self.name!r} type={self.type!r} required={self.required}>'
|
||||
|
||||
def _from_data(self, data: ApplicationCommandOption):
|
||||
def _from_data(self, data: ApplicationCommandOption) -> None:
|
||||
self.type: AppCommandOptionType = try_enum(AppCommandOptionType, data['type'])
|
||||
self.name: str = data['name']
|
||||
self.description: str = data['description']
|
||||
self.required: bool = data.get('required', False)
|
||||
self.choices: List[Choice] = [Choice(name=d['name'], value=d['value']) for d in data.get('choices', [])]
|
||||
self.choices: List[Choice[Union[int, float, str]]] = [
|
||||
Choice(name=d['name'], value=d['value']) for d in data.get('choices', [])
|
||||
]
|
||||
self.arguments: List[Argument] = [
|
||||
Argument(parent=self, state=self._state, data=d)
|
||||
for d in data.get('options', [])
|
||||
@ -614,7 +627,7 @@ class AppCommandGroup:
|
||||
|
||||
|
||||
def app_command_option_factory(
|
||||
parent: ApplicationCommandParent, data: ApplicationCommandOption, *, state=None
|
||||
parent: ApplicationCommandParent, data: ApplicationCommandOption, *, state: Optional[ConnectionState] = None
|
||||
) -> Union[Argument, AppCommandGroup]:
|
||||
if is_app_command_argument_type(data['type']):
|
||||
return Argument(parent=parent, data=data, state=state)
|
||||
|
@ -95,7 +95,7 @@ class CommandParameter:
|
||||
description: str = MISSING
|
||||
required: bool = MISSING
|
||||
default: Any = MISSING
|
||||
choices: List[Choice] = MISSING
|
||||
choices: List[Choice[Union[str, int, float]]] = MISSING
|
||||
type: AppCommandOptionType = MISSING
|
||||
channel_types: List[ChannelType] = MISSING
|
||||
min_value: Optional[Union[int, float]] = None
|
||||
@ -549,7 +549,7 @@ ALLOWED_DEFAULTS: Dict[AppCommandOptionType, Tuple[Type[Any], ...]] = {
|
||||
def get_supported_annotation(
|
||||
annotation: Any,
|
||||
*,
|
||||
_none=NoneType,
|
||||
_none: type = NoneType,
|
||||
_mapping: Dict[Any, Type[Transformer]] = BUILT_IN_TRANSFORMERS,
|
||||
) -> Tuple[Any, Any]:
|
||||
"""Returns an appropriate, yet supported, annotation along with an optional default value.
|
||||
|
@ -26,7 +26,22 @@ from __future__ import annotations
|
||||
import inspect
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Any, Callable, Dict, Generic, List, Literal, Optional, TYPE_CHECKING, Set, Tuple, TypeVar, Union, overload
|
||||
|
||||
from typing import (
|
||||
Any,
|
||||
TYPE_CHECKING,
|
||||
Callable,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Literal,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
overload,
|
||||
)
|
||||
from collections import Counter
|
||||
|
||||
|
||||
@ -194,13 +209,13 @@ class CommandTree(Generic[ClientT]):
|
||||
|
||||
def add_command(
|
||||
self,
|
||||
command: Union[Command, ContextMenu, Group],
|
||||
command: Union[Command[Any, ..., Any], ContextMenu, Group],
|
||||
/,
|
||||
*,
|
||||
guild: Optional[Snowflake] = MISSING,
|
||||
guilds: List[Snowflake] = MISSING,
|
||||
override: bool = False,
|
||||
):
|
||||
) -> None:
|
||||
"""Adds an application command to the tree.
|
||||
|
||||
This only adds the command locally -- in order to sync the commands
|
||||
@ -317,7 +332,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: Literal[AppCommandType.chat_input] = ...,
|
||||
) -> Optional[Union[Command, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], Group]]:
|
||||
...
|
||||
|
||||
@overload
|
||||
@ -328,7 +343,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: AppCommandType = ...,
|
||||
) -> Optional[Union[Command, ContextMenu, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]:
|
||||
...
|
||||
|
||||
def remove_command(
|
||||
@ -338,7 +353,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = None,
|
||||
type: AppCommandType = AppCommandType.chat_input,
|
||||
) -> Optional[Union[Command, ContextMenu, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]:
|
||||
"""Removes an application command from the tree.
|
||||
|
||||
This only removes the command locally -- in order to sync the commands
|
||||
@ -396,7 +411,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: Literal[AppCommandType.chat_input] = ...,
|
||||
) -> Optional[Union[Command, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], Group]]:
|
||||
...
|
||||
|
||||
@overload
|
||||
@ -407,7 +422,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: AppCommandType = ...,
|
||||
) -> Optional[Union[Command, ContextMenu, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]:
|
||||
...
|
||||
|
||||
def get_command(
|
||||
@ -417,7 +432,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = None,
|
||||
type: AppCommandType = AppCommandType.chat_input,
|
||||
) -> Optional[Union[Command, ContextMenu, Group]]:
|
||||
) -> Optional[Union[Command[Any, ..., Any], ContextMenu, Group]]:
|
||||
"""Gets a application command from the tree.
|
||||
|
||||
Parameters
|
||||
@ -468,7 +483,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: Literal[AppCommandType.chat_input] = ...,
|
||||
) -> List[Union[Command, Group]]:
|
||||
) -> List[Union[Command[Any, ..., Any], Group]]:
|
||||
...
|
||||
|
||||
@overload
|
||||
@ -477,7 +492,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = ...,
|
||||
type: AppCommandType = ...,
|
||||
) -> Union[List[Union[Command, Group]], List[ContextMenu]]:
|
||||
) -> Union[List[Union[Command[Any, ..., Any], Group]], List[ContextMenu]]:
|
||||
...
|
||||
|
||||
def get_commands(
|
||||
@ -485,7 +500,7 @@ class CommandTree(Generic[ClientT]):
|
||||
*,
|
||||
guild: Optional[Snowflake] = None,
|
||||
type: AppCommandType = AppCommandType.chat_input,
|
||||
) -> Union[List[Union[Command, Group]], List[ContextMenu]]:
|
||||
) -> Union[List[Union[Command[Any, ..., Any], Group]], List[ContextMenu]]:
|
||||
"""Gets all application commands from the tree.
|
||||
|
||||
Parameters
|
||||
@ -518,9 +533,11 @@ class CommandTree(Generic[ClientT]):
|
||||
value = type.value
|
||||
return [command for ((_, g, t), command) in self._context_menus.items() if g == guild_id and t == value]
|
||||
|
||||
def _get_all_commands(self, *, guild: Optional[Snowflake] = None) -> List[Union[Command, Group, ContextMenu]]:
|
||||
def _get_all_commands(
|
||||
self, *, guild: Optional[Snowflake] = None
|
||||
) -> List[Union[Command[Any, ..., Any], Group, ContextMenu]]:
|
||||
if guild is None:
|
||||
base: List[Union[Command, Group, ContextMenu]] = list(self._global_commands.values())
|
||||
base: List[Union[Command[Any, ..., Any], Group, ContextMenu]] = list(self._global_commands.values())
|
||||
base.extend(cmd for ((_, g, _), cmd) in self._context_menus.items() if g is None)
|
||||
return base
|
||||
else:
|
||||
@ -530,7 +547,7 @@ class CommandTree(Generic[ClientT]):
|
||||
guild_id = guild.id
|
||||
return [cmd for ((_, g, _), cmd) in self._context_menus.items() if g == guild_id]
|
||||
else:
|
||||
base: List[Union[Command, Group, ContextMenu]] = list(commands.values())
|
||||
base: List[Union[Command[Any, ..., Any], Group, ContextMenu]] = list(commands.values())
|
||||
guild_id = guild.id
|
||||
base.extend(cmd for ((_, g, _), cmd) in self._context_menus.items() if g == guild_id)
|
||||
return base
|
||||
@ -564,7 +581,7 @@ class CommandTree(Generic[ClientT]):
|
||||
async def on_error(
|
||||
self,
|
||||
interaction: Interaction,
|
||||
command: Optional[Union[ContextMenu, Command]],
|
||||
command: Optional[Union[ContextMenu, Command[Any, ..., Any]]],
|
||||
error: AppCommandError,
|
||||
) -> None:
|
||||
"""|coro|
|
||||
@ -742,7 +759,7 @@ class CommandTree(Generic[ClientT]):
|
||||
|
||||
self.client.loop.create_task(wrapper(), name='CommandTree-invoker')
|
||||
|
||||
async def _call_context_menu(self, interaction: Interaction, data: ApplicationCommandInteractionData, type: int):
|
||||
async def _call_context_menu(self, interaction: Interaction, data: ApplicationCommandInteractionData, type: int) -> None:
|
||||
name = data['name']
|
||||
guild_id = _get_as_snowflake(data, 'guild_id')
|
||||
ctx_menu = self._context_menus.get((name, guild_id, type))
|
||||
@ -770,7 +787,7 @@ class CommandTree(Generic[ClientT]):
|
||||
except AppCommandError as e:
|
||||
await self.on_error(interaction, ctx_menu, e)
|
||||
|
||||
async def call(self, interaction: Interaction):
|
||||
async def call(self, interaction: Interaction) -> None:
|
||||
"""|coro|
|
||||
|
||||
Given an :class:`~discord.Interaction`, calls the matching
|
||||
|
Reference in New Issue
Block a user