mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-08-22 19:32:06 +00:00
Use Unpack where it's possible
This commit is contained in:
parent
13432591c6
commit
983a9b8f94
@ -77,7 +77,7 @@ __all__ = (
|
||||
T = TypeVar('T', bound=VoiceProtocol)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
from .client import Client
|
||||
from .user import ClientUser
|
||||
@ -112,6 +112,7 @@ if TYPE_CHECKING:
|
||||
from .types.snowflake import (
|
||||
SnowflakeList,
|
||||
)
|
||||
from .permissions import _PermissionOverwriteKwargs
|
||||
|
||||
PartialMessageableChannel = Union[TextChannel, VoiceChannel, StageChannel, Thread, DMChannel, PartialMessageable]
|
||||
MessageableChannel = Union[PartialMessageableChannel, GroupChannel]
|
||||
@ -915,7 +916,7 @@ class GuildChannel:
|
||||
target: Union[Member, Role],
|
||||
*,
|
||||
reason: Optional[str] = ...,
|
||||
**permissions: Optional[bool],
|
||||
**permissions: Unpack[_PermissionOverwriteKwargs],
|
||||
) -> None:
|
||||
...
|
||||
|
||||
@ -925,7 +926,7 @@ class GuildChannel:
|
||||
*,
|
||||
overwrite: Any = _undefined,
|
||||
reason: Optional[str] = None,
|
||||
**permissions: Optional[bool],
|
||||
**permissions: Unpack[_PermissionOverwriteKwargs],
|
||||
) -> None:
|
||||
r"""|coro|
|
||||
|
||||
|
@ -55,8 +55,9 @@ from ..utils import get as utils_get, MISSING, maybe_coroutine
|
||||
T = TypeVar('T')
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
from ..interactions import Interaction
|
||||
from ..permissions import _PermissionsKwargs
|
||||
|
||||
CooldownFunction = Union[
|
||||
Callable[[Interaction[Any]], Coroutine[Any, Any, T]],
|
||||
@ -286,7 +287,7 @@ def has_any_role(*items: Union[int, str]) -> Callable[[T], T]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def has_permissions(**perms: bool) -> Callable[[T], T]:
|
||||
def has_permissions(**perms: Unpack[_PermissionsKwargs]) -> Callable[[T], T]:
|
||||
r"""A :func:`~discord.app_commands.check` that is added that checks if the member
|
||||
has all of the permissions necessary.
|
||||
|
||||
@ -341,7 +342,7 @@ def has_permissions(**perms: bool) -> Callable[[T], T]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def bot_has_permissions(**perms: bool) -> Callable[[T], T]:
|
||||
def bot_has_permissions(**perms: Unpack[_PermissionsKwargs]) -> Callable[[T], T]:
|
||||
"""Similar to :func:`has_permissions` except checks if the bot itself has
|
||||
the permissions listed. This relies on :attr:`discord.Interaction.app_permissions`.
|
||||
|
||||
|
@ -61,7 +61,7 @@ from ..permissions import Permissions
|
||||
from ..utils import resolve_annotation, MISSING, is_inside_class, maybe_coroutine, async_all, _shorten, _to_kebab_case
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import ParamSpec, Concatenate
|
||||
from typing_extensions import ParamSpec, Concatenate, Unpack
|
||||
from ..interactions import Interaction
|
||||
from ..abc import Snowflake
|
||||
from .namespace import Namespace
|
||||
@ -73,6 +73,7 @@ if TYPE_CHECKING:
|
||||
# However, for type hinting purposes it's unfortunately necessary for one to
|
||||
# reference the other to prevent type checking errors in callbacks
|
||||
from discord.ext import commands
|
||||
from discord.permissions import _PermissionsKwargs
|
||||
|
||||
ErrorFunc = Callable[[Interaction, AppCommandError], Coroutine[Any, Any, None]]
|
||||
|
||||
@ -2840,7 +2841,7 @@ def allowed_installs(
|
||||
return inner
|
||||
|
||||
|
||||
def default_permissions(perms_obj: Optional[Permissions] = None, /, **perms: bool) -> Callable[[T], T]:
|
||||
def default_permissions(perms_obj: Optional[Permissions] = None, /, **perms: Unpack[_PermissionsKwargs]) -> Callable[[T], T]:
|
||||
r"""A decorator that sets the default permissions needed to execute this command.
|
||||
|
||||
When this decorator is used, by default users must have these permissions to execute the command.
|
||||
|
@ -39,6 +39,7 @@ from typing import (
|
||||
Sequence,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
TypedDict,
|
||||
Union,
|
||||
overload,
|
||||
)
|
||||
@ -85,7 +86,7 @@ __all__ = (
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
from .types.threads import ThreadArchiveDuration
|
||||
from .role import Role
|
||||
@ -120,6 +121,44 @@ if TYPE_CHECKING:
|
||||
|
||||
OverwriteKeyT = TypeVar('OverwriteKeyT', Role, BaseUser, Object, Union[Role, Member, Object])
|
||||
|
||||
class _BaseCreateChannelOptions(TypedDict, total=False):
|
||||
reason: Optional[str]
|
||||
position: int
|
||||
|
||||
class _CreateTextChannelOptions(_BaseCreateChannelOptions, total=False):
|
||||
topic: str
|
||||
slowmode_delay: int
|
||||
nsfw: bool
|
||||
overwrites: Mapping[Union[Role, Member, Object], PermissionOverwrite]
|
||||
default_auto_archive_duration: int
|
||||
default_thread_slowmode_delay: int
|
||||
|
||||
class _CreateVoiceChannelOptions(_BaseCreateChannelOptions, total=False):
|
||||
bitrate: int
|
||||
user_limit: int
|
||||
rtc_region: Optional[str]
|
||||
video_quality_mode: VideoQualityMode
|
||||
overwrites: Mapping[Union[Role, Member, Object], PermissionOverwrite]
|
||||
|
||||
class _CreateStageChannelOptions(_CreateVoiceChannelOptions, total=False):
|
||||
bitrate: int
|
||||
user_limit: int
|
||||
rtc_region: Optional[str]
|
||||
video_quality_mode: VideoQualityMode
|
||||
overwrites: Mapping[Union[Role, Member, Object], PermissionOverwrite]
|
||||
|
||||
class _CreateForumChannelOptions(_CreateTextChannelOptions, total=False):
|
||||
topic: str
|
||||
slowmode_delay: int
|
||||
nsfw: bool
|
||||
overwrites: Mapping[Union[Role, Member, Object], PermissionOverwrite]
|
||||
default_auto_archive_duration: int
|
||||
default_thread_slowmode_delay: int
|
||||
default_sort_order: ForumOrderType
|
||||
default_reaction_emoji: EmojiInputType
|
||||
default_layout: ForumLayoutType
|
||||
available_tags: Sequence[ForumTag]
|
||||
|
||||
|
||||
class ThreadWithMessage(NamedTuple):
|
||||
thread: Thread
|
||||
@ -2194,7 +2233,7 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
|
||||
r.sort(key=lambda c: (c.position, c.id))
|
||||
return r
|
||||
|
||||
async def create_text_channel(self, name: str, **options: Any) -> TextChannel:
|
||||
async def create_text_channel(self, name: str, **options: Unpack[_CreateTextChannelOptions]) -> TextChannel:
|
||||
"""|coro|
|
||||
|
||||
A shortcut method to :meth:`Guild.create_text_channel` to create a :class:`TextChannel` in the category.
|
||||
@ -2206,7 +2245,7 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
|
||||
"""
|
||||
return await self.guild.create_text_channel(name, category=self, **options)
|
||||
|
||||
async def create_voice_channel(self, name: str, **options: Any) -> VoiceChannel:
|
||||
async def create_voice_channel(self, name: str, **options: Unpack[_CreateVoiceChannelOptions]) -> VoiceChannel:
|
||||
"""|coro|
|
||||
|
||||
A shortcut method to :meth:`Guild.create_voice_channel` to create a :class:`VoiceChannel` in the category.
|
||||
@ -2218,7 +2257,7 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
|
||||
"""
|
||||
return await self.guild.create_voice_channel(name, category=self, **options)
|
||||
|
||||
async def create_stage_channel(self, name: str, **options: Any) -> StageChannel:
|
||||
async def create_stage_channel(self, name: str, **options: Unpack[_CreateStageChannelOptions]) -> StageChannel:
|
||||
"""|coro|
|
||||
|
||||
A shortcut method to :meth:`Guild.create_stage_channel` to create a :class:`StageChannel` in the category.
|
||||
@ -2232,7 +2271,7 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
|
||||
"""
|
||||
return await self.guild.create_stage_channel(name, category=self, **options)
|
||||
|
||||
async def create_forum(self, name: str, **options: Any) -> ForumChannel:
|
||||
async def create_forum(self, name: str, **options: Unpack[_CreateForumChannelOptions]) -> ForumChannel:
|
||||
"""|coro|
|
||||
|
||||
A shortcut method to :meth:`Guild.create_forum` to create a :class:`ForumChannel` in the category.
|
||||
|
@ -42,6 +42,7 @@ from typing import (
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
TypedDict,
|
||||
Union,
|
||||
overload,
|
||||
)
|
||||
@ -82,7 +83,7 @@ from .soundboard import SoundboardDefaultSound, SoundboardSound
|
||||
if TYPE_CHECKING:
|
||||
from types import TracebackType
|
||||
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
from .abc import Messageable, PrivateChannel, Snowflake, SnowflakeTime
|
||||
from .app_commands import Command, ContextMenu
|
||||
@ -120,6 +121,28 @@ if TYPE_CHECKING:
|
||||
from .audit_logs import AuditLogEntry
|
||||
from .poll import PollAnswer
|
||||
from .subscription import Subscription
|
||||
from .flags import MemberCacheFlags
|
||||
|
||||
class _ClientOptions(TypedDict, total=False):
|
||||
max_messages: int
|
||||
proxy: str
|
||||
proxy_auth: aiohttp.BasicAuth
|
||||
shard_id: int
|
||||
shard_count: int
|
||||
application_id: int
|
||||
member_cache_flags: MemberCacheFlags
|
||||
chunk_guilds_at_startup: bool
|
||||
status: Status
|
||||
activity: BaseActivity
|
||||
allowed_mentions: AllowedMentions
|
||||
heartbeat_timeout: float
|
||||
guild_ready_timeout: float
|
||||
assume_unsync_clock: bool
|
||||
enable_debug_events: bool
|
||||
enable_raw_presences: bool
|
||||
http_trace: aiohttp.TraceConfig
|
||||
max_ratelimit_timeout: float
|
||||
connector: aiohttp.BaseConnector
|
||||
|
||||
|
||||
# fmt: off
|
||||
@ -272,7 +295,7 @@ class Client:
|
||||
The websocket gateway the client is currently connected to. Could be ``None``.
|
||||
"""
|
||||
|
||||
def __init__(self, *, intents: Intents, **options: Any) -> None:
|
||||
def __init__(self, *, intents: Intents, **options: Unpack[_ClientOptions]) -> None:
|
||||
self.loop: asyncio.AbstractEventLoop = _loop
|
||||
# self.ws is set in the connect method
|
||||
self.ws: DiscordWebSocket = None # type: ignore
|
||||
|
@ -64,7 +64,7 @@ from .cog import Cog
|
||||
from .hybrid import hybrid_command, hybrid_group, HybridCommand, HybridGroup
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
import importlib.machinery
|
||||
|
||||
@ -80,12 +80,24 @@ if TYPE_CHECKING:
|
||||
MaybeAwaitableFunc,
|
||||
)
|
||||
from .core import Command
|
||||
from .hybrid import CommandCallback, ContextT, P
|
||||
from .hybrid import CommandCallback, ContextT, P, _HybridCommandDecoratorKwargs, _HybridGroupDecoratorKwargs
|
||||
from discord.client import _ClientOptions
|
||||
from discord.shard import _AutoShardedClientOptions
|
||||
|
||||
_Prefix = Union[Iterable[str], str]
|
||||
_PrefixCallable = MaybeAwaitableFunc[[BotT, Message], _Prefix]
|
||||
PrefixType = Union[_Prefix, _PrefixCallable[BotT]]
|
||||
|
||||
class _BotOptions(_ClientOptions, total=False):
|
||||
owner_id: int
|
||||
owner_ids: Collection[int]
|
||||
strip_after_prefix: bool
|
||||
case_insensitive: bool
|
||||
|
||||
class _AutoShardedBotOptions(_AutoShardedClientOptions, _BotOptions):
|
||||
...
|
||||
|
||||
|
||||
__all__ = (
|
||||
'when_mentioned',
|
||||
'when_mentioned_or',
|
||||
@ -169,7 +181,7 @@ class BotBase(GroupMixin[None]):
|
||||
allowed_contexts: app_commands.AppCommandContext = MISSING,
|
||||
allowed_installs: app_commands.AppInstallationType = MISSING,
|
||||
intents: discord.Intents,
|
||||
**options: Any,
|
||||
**options: Unpack[_BotOptions],
|
||||
) -> None:
|
||||
super().__init__(intents=intents, **options)
|
||||
self.command_prefix: PrefixType[BotT] = command_prefix # type: ignore
|
||||
@ -281,7 +293,7 @@ class BotBase(GroupMixin[None]):
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
with_app_command: bool = True,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_HybridCommandDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[Any, ContextT, P, T]], HybridCommand[Any, P, T]]:
|
||||
"""A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_command` and adds it to
|
||||
the internal command list via :meth:`add_command`.
|
||||
@ -293,8 +305,8 @@ class BotBase(GroupMixin[None]):
|
||||
"""
|
||||
|
||||
def decorator(func: CommandCallback[Any, ContextT, P, T]):
|
||||
kwargs.setdefault('parent', self)
|
||||
result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
|
||||
kwargs.setdefault('parent', self) # type: ignore # parent is not for the user to set
|
||||
result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func) # type: ignore # name, with_app_command
|
||||
self.add_command(result)
|
||||
return result
|
||||
|
||||
@ -305,7 +317,7 @@ class BotBase(GroupMixin[None]):
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
with_app_command: bool = True,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_HybridGroupDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[Any, ContextT, P, T]], HybridGroup[Any, P, T]]:
|
||||
"""A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_group` and adds it to
|
||||
the internal command list via :meth:`add_command`.
|
||||
@ -317,8 +329,8 @@ class BotBase(GroupMixin[None]):
|
||||
"""
|
||||
|
||||
def decorator(func: CommandCallback[Any, ContextT, P, T]):
|
||||
kwargs.setdefault('parent', self)
|
||||
result = hybrid_group(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
|
||||
kwargs.setdefault('parent', self) # type: ignore # parent is not for the user to set
|
||||
result = hybrid_group(name=name, *args, with_app_command=with_app_command, **kwargs)(func) # type: ignore # name, with_app_command
|
||||
self.add_command(result)
|
||||
return result
|
||||
|
||||
@ -1527,4 +1539,18 @@ class AutoShardedBot(BotBase, discord.AutoShardedClient):
|
||||
.. versionadded:: 2.0
|
||||
"""
|
||||
|
||||
pass
|
||||
if TYPE_CHECKING:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
command_prefix: PrefixType[BotT],
|
||||
*,
|
||||
help_command: Optional[HelpCommand] = _default,
|
||||
tree_cls: Type[app_commands.CommandTree[Any]] = app_commands.CommandTree,
|
||||
description: Optional[str] = None,
|
||||
allowed_contexts: app_commands.AppCommandContext = MISSING,
|
||||
allowed_installs: app_commands.AppInstallationType = MISSING,
|
||||
intents: discord.Intents,
|
||||
**kwargs: Unpack[_AutoShardedBotOptions],
|
||||
) -> None:
|
||||
...
|
||||
|
@ -44,18 +44,30 @@ from typing import (
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
TypedDict,
|
||||
)
|
||||
|
||||
from ._types import _BaseCommand, BotT
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
from discord.abc import Snowflake
|
||||
from discord._types import ClientT
|
||||
|
||||
from .bot import BotBase
|
||||
from .context import Context
|
||||
from .core import Command
|
||||
from .core import Command, _CommandDecoratorKwargs
|
||||
|
||||
class _CogKwargs(TypedDict, total=False):
|
||||
name: str
|
||||
group_name: Union[str, app_commands.locale_str]
|
||||
description: str
|
||||
group_description: Union[str, app_commands.locale_str]
|
||||
group_nsfw: bool
|
||||
group_auto_locale_strings: bool
|
||||
group_extras: Dict[Any, Any]
|
||||
command_attrs: _CommandDecoratorKwargs
|
||||
|
||||
|
||||
__all__ = (
|
||||
'CogMeta',
|
||||
@ -169,7 +181,7 @@ class CogMeta(type):
|
||||
__cog_app_commands__: List[Union[app_commands.Group, app_commands.Command[Any, ..., Any]]]
|
||||
__cog_listeners__: List[Tuple[str, str]]
|
||||
|
||||
def __new__(cls, *args: Any, **kwargs: Any) -> CogMeta:
|
||||
def __new__(cls, *args: Any, **kwargs: Unpack[_CogKwargs]) -> CogMeta:
|
||||
name, bases, attrs = args
|
||||
if any(issubclass(base, app_commands.Group) for base in bases):
|
||||
raise TypeError(
|
||||
|
@ -43,6 +43,7 @@ from typing import (
|
||||
TypeVar,
|
||||
Union,
|
||||
overload,
|
||||
TypedDict,
|
||||
)
|
||||
import re
|
||||
|
||||
@ -58,10 +59,39 @@ from .parameters import Parameter, Signature
|
||||
from discord.app_commands.commands import NUMPY_DOCSTRING_ARG_REGEX
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Concatenate, ParamSpec, Self
|
||||
from typing_extensions import Concatenate, ParamSpec, Self, Unpack
|
||||
|
||||
from ._types import BotT, Check, ContextT, Coro, CoroFunc, Error, Hook, UserCheck
|
||||
|
||||
from discord.permissions import _PermissionsKwargs
|
||||
|
||||
class _CommandDecoratorKwargs(TypedDict, total=False):
|
||||
enabled: bool
|
||||
help: str
|
||||
brief: str
|
||||
usage: str
|
||||
rest_is_raw: bool
|
||||
aliases: List[str]
|
||||
description: str
|
||||
hidden: bool
|
||||
checks: List[UserCheck[Context[Any]]]
|
||||
cooldown: CooldownMapping[Context[Any]]
|
||||
max_concurrency: MaxConcurrency
|
||||
require_var_positional: bool
|
||||
cooldown_after_parsing: bool
|
||||
ignore_extra: bool
|
||||
extras: Dict[Any, Any]
|
||||
|
||||
class _CommandKwargs(_CommandDecoratorKwargs, total=False):
|
||||
name: str
|
||||
|
||||
class _GroupDecoratorKwargs(_CommandDecoratorKwargs, total=False):
|
||||
invoke_without_command: bool
|
||||
case_insensitive: bool
|
||||
|
||||
class _GroupKwargs(_GroupDecoratorKwargs, total=False):
|
||||
name: str
|
||||
|
||||
|
||||
__all__ = (
|
||||
'Command',
|
||||
@ -393,7 +423,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
||||
Callable[Concatenate[Context[Any], P], Coro[T]],
|
||||
],
|
||||
/,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_CommandKwargs],
|
||||
) -> None:
|
||||
if not asyncio.iscoroutinefunction(func):
|
||||
raise TypeError('Callback must be a coroutine.')
|
||||
@ -556,7 +586,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
def update(self, **kwargs: Any) -> None:
|
||||
def update(self, **kwargs: Unpack[_CommandKwargs]) -> None:
|
||||
"""Updates :class:`Command` instance with updated attribute.
|
||||
|
||||
This works similarly to the :func:`~discord.ext.commands.command` decorator in terms
|
||||
@ -1468,7 +1498,7 @@ class GroupMixin(Generic[CogT]):
|
||||
self: GroupMixin[CogT],
|
||||
name: str = ...,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1486,7 +1516,7 @@ class GroupMixin(Generic[CogT]):
|
||||
name: str = ...,
|
||||
cls: Type[CommandT] = ..., # type: ignore # previous overload handles case where cls is not set
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1503,7 +1533,7 @@ class GroupMixin(Generic[CogT]):
|
||||
name: str = MISSING,
|
||||
cls: Type[Command[Any, ..., Any]] = MISSING,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> Any:
|
||||
"""A shortcut decorator that invokes :func:`~discord.ext.commands.command` and adds it to
|
||||
the internal command list via :meth:`~.GroupMixin.add_command`.
|
||||
@ -1515,8 +1545,7 @@ class GroupMixin(Generic[CogT]):
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
|
||||
kwargs.setdefault('parent', self)
|
||||
kwargs.setdefault('parent', self) # type: ignore # the parent kwarg is not for users to set.
|
||||
result = command(name=name, cls=cls, *args, **kwargs)(func)
|
||||
self.add_command(result)
|
||||
return result
|
||||
@ -1528,7 +1557,7 @@ class GroupMixin(Generic[CogT]):
|
||||
self: GroupMixin[CogT],
|
||||
name: str = ...,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1546,7 +1575,7 @@ class GroupMixin(Generic[CogT]):
|
||||
name: str = ...,
|
||||
cls: Type[GroupT] = ..., # type: ignore # previous overload handles case where cls is not set
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1563,7 +1592,7 @@ class GroupMixin(Generic[CogT]):
|
||||
name: str = MISSING,
|
||||
cls: Type[Group[Any, ..., Any]] = MISSING,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> Any:
|
||||
"""A shortcut decorator that invokes :func:`.group` and adds it to
|
||||
the internal command list via :meth:`~.GroupMixin.add_command`.
|
||||
@ -1575,7 +1604,7 @@ class GroupMixin(Generic[CogT]):
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
kwargs.setdefault('parent', self)
|
||||
kwargs.setdefault('parent', self) # type: ignore # the parent kwarg is not for users to set.
|
||||
result = group(name=name, cls=cls, *args, **kwargs)(func)
|
||||
self.add_command(result)
|
||||
return result
|
||||
@ -1606,7 +1635,7 @@ class Group(GroupMixin[CogT], Command[CogT, P, T]):
|
||||
Defaults to ``False``.
|
||||
"""
|
||||
|
||||
def __init__(self, *args: Any, **attrs: Any) -> None:
|
||||
def __init__(self, *args: Any, **attrs: Unpack[_GroupKwargs]) -> None:
|
||||
self.invoke_without_command: bool = attrs.pop('invoke_without_command', False)
|
||||
super().__init__(*args, **attrs)
|
||||
|
||||
@ -1728,7 +1757,7 @@ if TYPE_CHECKING:
|
||||
@overload
|
||||
def command(
|
||||
name: str = ...,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> _CommandDecorator:
|
||||
...
|
||||
|
||||
@ -1737,7 +1766,7 @@ def command(
|
||||
def command(
|
||||
name: str = ...,
|
||||
cls: Type[CommandT] = ..., # type: ignore # previous overload handles case where cls is not set
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1753,7 +1782,7 @@ def command(
|
||||
def command(
|
||||
name: str = MISSING,
|
||||
cls: Type[Command[Any, ..., Any]] = MISSING,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_CommandDecoratorKwargs],
|
||||
) -> Any:
|
||||
"""A decorator that transforms a function into a :class:`.Command`
|
||||
or if called with :func:`.group`, :class:`.Group`.
|
||||
@ -1798,7 +1827,7 @@ def command(
|
||||
@overload
|
||||
def group(
|
||||
name: str = ...,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> _GroupDecorator:
|
||||
...
|
||||
|
||||
@ -1807,7 +1836,7 @@ def group(
|
||||
def group(
|
||||
name: str = ...,
|
||||
cls: Type[GroupT] = ..., # type: ignore # previous overload handles case where cls is not set
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> Callable[
|
||||
[
|
||||
Union[
|
||||
@ -1823,7 +1852,7 @@ def group(
|
||||
def group(
|
||||
name: str = MISSING,
|
||||
cls: Type[Group[Any, ..., Any]] = MISSING,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_GroupDecoratorKwargs],
|
||||
) -> Any:
|
||||
"""A decorator that transforms a function into a :class:`.Group`.
|
||||
|
||||
@ -2165,7 +2194,7 @@ def bot_has_any_role(*items: int) -> Callable[[T], T]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def has_permissions(**perms: bool) -> Check[Any]:
|
||||
def has_permissions(**perms: Unpack[_PermissionsKwargs]) -> Check[Any]:
|
||||
"""A :func:`.check` that is added that checks if the member has all of
|
||||
the permissions necessary.
|
||||
|
||||
@ -2212,7 +2241,7 @@ def has_permissions(**perms: bool) -> Check[Any]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def bot_has_permissions(**perms: bool) -> Check[Any]:
|
||||
def bot_has_permissions(**perms: Unpack[_PermissionsKwargs]) -> Check[Any]:
|
||||
"""Similar to :func:`.has_permissions` except checks if the bot itself has
|
||||
the permissions listed.
|
||||
|
||||
@ -2237,7 +2266,7 @@ def bot_has_permissions(**perms: bool) -> Check[Any]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def has_guild_permissions(**perms: bool) -> Check[Any]:
|
||||
def has_guild_permissions(**perms: Unpack[_PermissionsKwargs]) -> Check[Any]:
|
||||
"""Similar to :func:`.has_permissions`, but operates on guild wide
|
||||
permissions instead of the current channel permissions.
|
||||
|
||||
@ -2266,7 +2295,7 @@ def has_guild_permissions(**perms: bool) -> Check[Any]:
|
||||
return check(predicate)
|
||||
|
||||
|
||||
def bot_has_guild_permissions(**perms: bool) -> Check[Any]:
|
||||
def bot_has_guild_permissions(**perms: Unpack[_PermissionsKwargs]) -> Check[Any]:
|
||||
"""Similar to :func:`.has_guild_permissions`, but checks the bot
|
||||
members guild permissions.
|
||||
|
||||
|
@ -42,6 +42,7 @@ from typing import (
|
||||
Iterable,
|
||||
Sequence,
|
||||
Mapping,
|
||||
TypedDict,
|
||||
)
|
||||
|
||||
import discord.utils
|
||||
@ -50,7 +51,7 @@ from .core import Group, Command, get_signature_parameters
|
||||
from .errors import CommandError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
import discord.abc
|
||||
|
||||
@ -58,6 +59,7 @@ if TYPE_CHECKING:
|
||||
from .context import Context
|
||||
from .cog import Cog
|
||||
from .parameters import Parameter
|
||||
from .core import _CommandKwargs
|
||||
|
||||
from ._types import (
|
||||
UserCheck,
|
||||
@ -65,6 +67,30 @@ if TYPE_CHECKING:
|
||||
_Bot,
|
||||
)
|
||||
|
||||
class _HelpCommandOptions(TypedDict, total=False):
|
||||
show_hidden: bool
|
||||
verify_checks: bool
|
||||
command_attrs: _CommandKwargs
|
||||
|
||||
class _BaseHelpCommandOptions(_HelpCommandOptions, total=False):
|
||||
sort_commands: bool
|
||||
dm_help: bool
|
||||
dm_help_threshold: int
|
||||
no_category: str
|
||||
paginator: Paginator
|
||||
commands_heading: str
|
||||
|
||||
class _DefaultHelpCommandOptions(_BaseHelpCommandOptions, total=False):
|
||||
width: int
|
||||
indent: int
|
||||
arguments_heading: str
|
||||
default_argument_description: str
|
||||
show_parameter_descriptions: bool
|
||||
|
||||
class _MinimalHelpCommandOptions(_BaseHelpCommandOptions, total=False):
|
||||
aliases_heading: str
|
||||
|
||||
|
||||
__all__ = (
|
||||
'Paginator',
|
||||
'HelpCommand',
|
||||
@ -224,7 +250,7 @@ def _not_overridden(f: FuncT) -> FuncT:
|
||||
|
||||
|
||||
class _HelpCommandImpl(Command):
|
||||
def __init__(self, inject: HelpCommand, *args: Any, **kwargs: Any) -> None:
|
||||
def __init__(self, inject: HelpCommand, *args: Any, **kwargs: Unpack[_CommandKwargs]) -> None:
|
||||
super().__init__(inject.command_callback, *args, **kwargs)
|
||||
self._original: HelpCommand = inject
|
||||
self._injected: HelpCommand = inject
|
||||
@ -299,7 +325,7 @@ class _HelpCommandImpl(Command):
|
||||
|
||||
def update(self, **kwargs: Any) -> None:
|
||||
cog = self.cog
|
||||
self.__init__(self._original, **dict(self.__original_kwargs__, **kwargs))
|
||||
self.__init__(self._original, **dict(self.__original_kwargs__, **kwargs)) # type: ignore
|
||||
self.cog = cog
|
||||
|
||||
|
||||
@ -366,10 +392,9 @@ class HelpCommand:
|
||||
self.__original_args__ = deepcopy(args)
|
||||
return self
|
||||
|
||||
def __init__(self, **options: Any) -> None:
|
||||
def __init__(self, **options: Unpack[_HelpCommandOptions]) -> None:
|
||||
self.show_hidden: bool = options.pop('show_hidden', False)
|
||||
self.verify_checks: bool = options.pop('verify_checks', True)
|
||||
self.command_attrs: Dict[str, Any]
|
||||
self.command_attrs = attrs = options.pop('command_attrs', {})
|
||||
attrs.setdefault('name', 'help')
|
||||
attrs.setdefault('help', 'Shows this message')
|
||||
@ -1041,7 +1066,7 @@ class DefaultHelpCommand(HelpCommand):
|
||||
The paginator used to paginate the help command output.
|
||||
"""
|
||||
|
||||
def __init__(self, **options: Any) -> None:
|
||||
def __init__(self, **options: Unpack[_DefaultHelpCommandOptions]) -> None:
|
||||
self.width: int = options.pop('width', 80)
|
||||
self.indent: int = options.pop('indent', 2)
|
||||
self.sort_commands: bool = options.pop('sort_commands', True)
|
||||
@ -1051,11 +1076,13 @@ class DefaultHelpCommand(HelpCommand):
|
||||
self.commands_heading: str = options.pop('commands_heading', 'Commands:')
|
||||
self.default_argument_description: str = options.pop('default_argument_description', 'No description given')
|
||||
self.no_category: str = options.pop('no_category', 'No Category')
|
||||
self.paginator: Paginator = options.pop('paginator', None)
|
||||
self.show_parameter_descriptions: bool = options.pop('show_parameter_descriptions', True)
|
||||
|
||||
if self.paginator is None:
|
||||
paginator = options.pop('paginator', None)
|
||||
if paginator is None:
|
||||
self.paginator: Paginator = Paginator()
|
||||
else:
|
||||
self.paginator: Paginator = paginator
|
||||
|
||||
super().__init__(**options)
|
||||
|
||||
@ -1334,17 +1361,19 @@ class MinimalHelpCommand(HelpCommand):
|
||||
The paginator used to paginate the help command output.
|
||||
"""
|
||||
|
||||
def __init__(self, **options: Any) -> None:
|
||||
def __init__(self, **options: Unpack[_MinimalHelpCommandOptions]) -> None:
|
||||
self.sort_commands: bool = options.pop('sort_commands', True)
|
||||
self.commands_heading: str = options.pop('commands_heading', 'Commands')
|
||||
self.dm_help: bool = options.pop('dm_help', False)
|
||||
self.dm_help_threshold: int = options.pop('dm_help_threshold', 1000)
|
||||
self.aliases_heading: str = options.pop('aliases_heading', 'Aliases:')
|
||||
self.no_category: str = options.pop('no_category', 'No Category')
|
||||
self.paginator: Paginator = options.pop('paginator', None)
|
||||
|
||||
if self.paginator is None:
|
||||
paginator = options.pop('paginator', None)
|
||||
if paginator is None:
|
||||
self.paginator: Paginator = Paginator(suffix=None, prefix=None)
|
||||
else:
|
||||
self.paginator: Paginator = paginator
|
||||
|
||||
super().__init__(**options)
|
||||
|
||||
|
@ -24,19 +24,7 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Callable,
|
||||
ClassVar,
|
||||
Dict,
|
||||
List,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
Optional,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, List, Tuple, Type, TypeVar, Union, Optional
|
||||
|
||||
import discord
|
||||
import inspect
|
||||
@ -51,7 +39,7 @@ from .cog import Cog
|
||||
from .view import StringView
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self, ParamSpec, Concatenate
|
||||
from typing_extensions import Self, ParamSpec, Concatenate, Unpack
|
||||
from ._types import ContextT, Coro, BotT
|
||||
from .bot import Bot
|
||||
from .context import Context
|
||||
@ -60,6 +48,29 @@ if TYPE_CHECKING:
|
||||
AutocompleteCallback,
|
||||
ChoiceT,
|
||||
)
|
||||
from .core import _CommandKwargs
|
||||
|
||||
class _HybridCommandKwargs(_CommandKwargs, total=False):
|
||||
guild_ids: list[int]
|
||||
guild_only: bool
|
||||
default_permissions: bool
|
||||
nsfw: bool
|
||||
with_app_command: bool
|
||||
|
||||
class _HybridCommandDecoratorKwargs(_HybridCommandKwargs, total=False):
|
||||
description: Union[str, app_commands.locale_str]
|
||||
|
||||
class _HybridGroupKwargs(_HybridCommandDecoratorKwargs, total=False):
|
||||
with_app_command: bool
|
||||
guild_ids: list[int]
|
||||
guild_only: bool
|
||||
default_permissions: bool
|
||||
nsfw: bool
|
||||
description: str
|
||||
|
||||
class _HybridGroupDecoratorKwargs(_HybridGroupKwargs, total=False):
|
||||
description: Union[str, app_commands.locale_str]
|
||||
fallback: Union[str, app_commands.locale_str]
|
||||
|
||||
|
||||
__all__ = (
|
||||
@ -501,7 +512,7 @@ class HybridCommand(Command[CogT, P, T]):
|
||||
*,
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
description: Union[str, app_commands.locale_str] = MISSING,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_HybridCommandKwargs], # type: ignore # name, description
|
||||
) -> None:
|
||||
name, name_locale = (name.message, name) if isinstance(name, app_commands.locale_str) else (name, None)
|
||||
if name is not MISSING:
|
||||
@ -621,7 +632,7 @@ class HybridGroup(Group[CogT, P, T]):
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
description: Union[str, app_commands.locale_str] = MISSING,
|
||||
fallback: Optional[Union[str, app_commands.locale_str]] = None,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_HybridGroupKwargs], # type: ignore # name, description
|
||||
) -> None:
|
||||
name, name_locale = (name.message, name) if isinstance(name, app_commands.locale_str) else (name, None)
|
||||
if name is not MISSING:
|
||||
@ -825,7 +836,7 @@ class HybridGroup(Group[CogT, P, T]):
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
*args: Any,
|
||||
with_app_command: bool = True,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_HybridCommandDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[CogT, ContextT, P2, U]], HybridCommand[CogT, P2, U]]:
|
||||
"""A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_command` and adds it to
|
||||
the internal command list via :meth:`add_command`.
|
||||
@ -837,8 +848,8 @@ class HybridGroup(Group[CogT, P, T]):
|
||||
"""
|
||||
|
||||
def decorator(func: CommandCallback[CogT, ContextT, P2, U]):
|
||||
kwargs.setdefault('parent', self)
|
||||
result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
|
||||
kwargs.setdefault('parent', self) # type: ignore # parent is not for users to set
|
||||
result = hybrid_command(name=name, *args, with_app_command=with_app_command, **kwargs)(func) # type: ignore # name, with_app_command
|
||||
self.add_command(result)
|
||||
return result
|
||||
|
||||
@ -849,7 +860,7 @@ class HybridGroup(Group[CogT, P, T]):
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
*args: Any,
|
||||
with_app_command: bool = True,
|
||||
**kwargs: Any,
|
||||
**kwargs: Unpack[_HybridGroupDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[CogT, ContextT, P2, U]], HybridGroup[CogT, P2, U]]:
|
||||
"""A shortcut decorator that invokes :func:`~discord.ext.commands.hybrid_group` and adds it to
|
||||
the internal command list via :meth:`~.GroupMixin.add_command`.
|
||||
@ -861,8 +872,8 @@ class HybridGroup(Group[CogT, P, T]):
|
||||
"""
|
||||
|
||||
def decorator(func: CommandCallback[CogT, ContextT, P2, U]):
|
||||
kwargs.setdefault('parent', self)
|
||||
result = hybrid_group(name=name, *args, with_app_command=with_app_command, **kwargs)(func)
|
||||
kwargs.setdefault('parent', self) # type: ignore # parent is not for users to set
|
||||
result = hybrid_group(name=name, *args, with_app_command=with_app_command, **kwargs)(func) # type: ignore # name, with_app_command
|
||||
self.add_command(result)
|
||||
return result
|
||||
|
||||
@ -873,7 +884,7 @@ def hybrid_command(
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
*,
|
||||
with_app_command: bool = True,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_HybridCommandDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[CogT, ContextT, P, T]], HybridCommand[CogT, P, T]]:
|
||||
r"""A decorator that transforms a function into a :class:`.HybridCommand`.
|
||||
|
||||
@ -916,7 +927,7 @@ def hybrid_command(
|
||||
if isinstance(func, Command):
|
||||
raise TypeError('Callback is already a command.')
|
||||
# Pyright does not allow Command[Any] to be assigned to Command[CogT] despite it being okay here
|
||||
return HybridCommand(func, name=name, with_app_command=with_app_command, **attrs) # type: ignore
|
||||
return HybridCommand(func, name=name, with_app_command=with_app_command, **attrs) # type: ignore # name, with_app_command
|
||||
|
||||
return decorator
|
||||
|
||||
@ -925,7 +936,7 @@ def hybrid_group(
|
||||
name: Union[str, app_commands.locale_str] = MISSING,
|
||||
*,
|
||||
with_app_command: bool = True,
|
||||
**attrs: Any,
|
||||
**attrs: Unpack[_HybridGroupDecoratorKwargs], # type: ignore # name, with_app_command
|
||||
) -> Callable[[CommandCallback[CogT, ContextT, P, T]], HybridGroup[CogT, P, T]]:
|
||||
"""A decorator that transforms a function into a :class:`.HybridGroup`.
|
||||
|
||||
@ -949,6 +960,6 @@ def hybrid_group(
|
||||
def decorator(func: CommandCallback[CogT, ContextT, P, T]) -> HybridGroup[CogT, P, T]:
|
||||
if isinstance(func, Command):
|
||||
raise TypeError('Callback is already a command.')
|
||||
return HybridGroup(func, name=name, with_app_command=with_app_command, **attrs)
|
||||
return HybridGroup(func, name=name, with_app_command=with_app_command, **attrs) # type: ignore # name, with_app_command
|
||||
|
||||
return decorator
|
||||
|
@ -40,12 +40,48 @@ from typing import (
|
||||
Type,
|
||||
TypeVar,
|
||||
overload,
|
||||
TypedDict,
|
||||
)
|
||||
|
||||
from .enums import UserFlags
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
class _IntentsFlagsKwargs(TypedDict, total=False):
|
||||
guilds: bool
|
||||
members: bool
|
||||
moderation: bool
|
||||
bans: bool
|
||||
emojis: bool
|
||||
emojis_and_stickers: bool
|
||||
expressions: bool
|
||||
integrations: bool
|
||||
webhooks: bool
|
||||
invites: bool
|
||||
voice_states: bool
|
||||
presences: bool
|
||||
messages: bool
|
||||
guild_messages: bool
|
||||
dm_messages: bool
|
||||
reactions: bool
|
||||
guild_reactions: bool
|
||||
dm_reactions: bool
|
||||
typing: bool
|
||||
guild_typing: bool
|
||||
dm_typing: bool
|
||||
message_content: bool
|
||||
guild_scheduled_events: bool
|
||||
auto_moderation: bool
|
||||
auto_moderation_configuration: bool
|
||||
auto_moderation_execution: bool
|
||||
polls: bool
|
||||
guild_polls: bool
|
||||
dm_polls: bool
|
||||
|
||||
class _MemberCacheFlagsKwargs(TypedDict, total=False):
|
||||
voice: bool
|
||||
joined: bool
|
||||
|
||||
|
||||
__all__ = (
|
||||
@ -765,12 +801,12 @@ class Intents(BaseFlags):
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, value: int = 0, **kwargs: bool) -> None:
|
||||
def __init__(self, value: int = 0, **kwargs: Unpack[_IntentsFlagsKwargs]) -> None:
|
||||
self.value: int = value
|
||||
for key, value in kwargs.items():
|
||||
for key, kwvalue in kwargs.items():
|
||||
if key not in self.VALID_FLAGS:
|
||||
raise TypeError(f'{key!r} is not a valid flag name.')
|
||||
setattr(self, key, value)
|
||||
setattr(self, key, kwvalue)
|
||||
|
||||
@classmethod
|
||||
def all(cls: Type[Intents]) -> Intents:
|
||||
@ -1426,7 +1462,7 @@ class MemberCacheFlags(BaseFlags):
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, **kwargs: bool):
|
||||
def __init__(self, **kwargs: Unpack[_MemberCacheFlagsKwargs]) -> None:
|
||||
bits = max(self.VALID_FLAGS.values()).bit_length()
|
||||
self.value: int = (1 << bits) - 1
|
||||
for key, value in kwargs.items():
|
||||
|
@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, Any, ClassVar, Dict, Iterator, Set, TYPE_CHECKING, Tuple, Optional
|
||||
from typing import Callable, Any, ClassVar, Dict, Iterator, Set, TYPE_CHECKING, Tuple, Optional, TypedDict, Generic, TypeVar
|
||||
from .flags import BaseFlags, flag_value, fill_with_flags, alias_flag_value
|
||||
|
||||
__all__ = (
|
||||
@ -33,7 +33,73 @@ __all__ = (
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
BoolOrNoneT = TypeVar('BoolOrNoneT', bound=Optional[bool])
|
||||
|
||||
class _BasePermissionsKwargs(Generic[BoolOrNoneT], TypedDict, total=False):
|
||||
create_instant_invite: BoolOrNoneT
|
||||
kick_members: BoolOrNoneT
|
||||
ban_members: BoolOrNoneT
|
||||
administrator: BoolOrNoneT
|
||||
manage_channels: BoolOrNoneT
|
||||
manage_guild: BoolOrNoneT
|
||||
add_reactions: BoolOrNoneT
|
||||
view_audit_log: BoolOrNoneT
|
||||
priority_speaker: BoolOrNoneT
|
||||
stream: BoolOrNoneT
|
||||
read_messages: BoolOrNoneT
|
||||
view_channel: BoolOrNoneT
|
||||
send_messages: BoolOrNoneT
|
||||
send_tts_messages: BoolOrNoneT
|
||||
manage_messages: BoolOrNoneT
|
||||
embed_links: BoolOrNoneT
|
||||
attach_files: BoolOrNoneT
|
||||
read_message_history: BoolOrNoneT
|
||||
mention_everyone: BoolOrNoneT
|
||||
external_emojis: BoolOrNoneT
|
||||
use_external_emojis: BoolOrNoneT
|
||||
view_guild_insights: BoolOrNoneT
|
||||
connect: BoolOrNoneT
|
||||
speak: BoolOrNoneT
|
||||
mute_members: BoolOrNoneT
|
||||
deafen_members: BoolOrNoneT
|
||||
move_members: BoolOrNoneT
|
||||
use_voice_activation: BoolOrNoneT
|
||||
change_nickname: BoolOrNoneT
|
||||
manage_nicknames: BoolOrNoneT
|
||||
manage_roles: BoolOrNoneT
|
||||
manage_permissions: BoolOrNoneT
|
||||
manage_webhooks: BoolOrNoneT
|
||||
manage_expressions: BoolOrNoneT
|
||||
manage_emojis: BoolOrNoneT
|
||||
manage_emojis_and_stickers: BoolOrNoneT
|
||||
use_application_commands: BoolOrNoneT
|
||||
request_to_speak: BoolOrNoneT
|
||||
manage_events: BoolOrNoneT
|
||||
manage_threads: BoolOrNoneT
|
||||
create_public_threads: BoolOrNoneT
|
||||
create_private_threads: BoolOrNoneT
|
||||
send_messages_in_threads: BoolOrNoneT
|
||||
external_stickers: BoolOrNoneT
|
||||
use_external_stickers: BoolOrNoneT
|
||||
use_embedded_activities: BoolOrNoneT
|
||||
moderate_members: BoolOrNoneT
|
||||
use_soundboard: BoolOrNoneT
|
||||
use_external_sounds: BoolOrNoneT
|
||||
send_voice_messages: BoolOrNoneT
|
||||
create_expressions: BoolOrNoneT
|
||||
create_events: BoolOrNoneT
|
||||
send_polls: BoolOrNoneT
|
||||
create_polls: BoolOrNoneT
|
||||
use_external_apps: BoolOrNoneT
|
||||
|
||||
class _PermissionsKwargs(_BasePermissionsKwargs[bool]):
|
||||
...
|
||||
|
||||
class _PermissionOverwriteKwargs(_BasePermissionsKwargs[Optional[bool]]):
|
||||
...
|
||||
|
||||
|
||||
# A permission alias works like a regular flag but is marked
|
||||
# So the PermissionOverwrite knows to work with it
|
||||
@ -135,18 +201,18 @@ class Permissions(BaseFlags):
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(self, permissions: int = 0, **kwargs: bool):
|
||||
def __init__(self, permissions: int = 0, **kwargs: Unpack[_PermissionsKwargs]):
|
||||
if not isinstance(permissions, int):
|
||||
raise TypeError(f'Expected int parameter, received {permissions.__class__.__name__} instead.')
|
||||
|
||||
self.value = permissions
|
||||
for key, value in kwargs.items():
|
||||
for key, kwvalue in kwargs.items():
|
||||
try:
|
||||
flag = self.VALID_FLAGS[key]
|
||||
except KeyError:
|
||||
raise TypeError(f'{key!r} is not a valid permission name.') from None
|
||||
else:
|
||||
self._set_flag(flag, value)
|
||||
self._set_flag(flag, kwvalue) # type: ignore # TypedDict annoyance where kwvalue is an object instead of bool
|
||||
|
||||
def is_subset(self, other: Permissions) -> bool:
|
||||
"""Returns ``True`` if self has the same or fewer permissions as other."""
|
||||
@ -391,7 +457,7 @@ class Permissions(BaseFlags):
|
||||
"""
|
||||
return cls(1 << 3)
|
||||
|
||||
def update(self, **kwargs: bool) -> None:
|
||||
def update(self, **kwargs: Unpack[_PermissionsKwargs]) -> None:
|
||||
r"""Bulk updates this permission object.
|
||||
|
||||
Allows you to set multiple attributes by using keyword
|
||||
@ -406,7 +472,7 @@ class Permissions(BaseFlags):
|
||||
for key, value in kwargs.items():
|
||||
flag = self.VALID_FLAGS.get(key)
|
||||
if flag is not None:
|
||||
self._set_flag(flag, value)
|
||||
self._set_flag(flag, value) # type: ignore
|
||||
|
||||
def handle_overwrite(self, allow: int, deny: int) -> None:
|
||||
# Basically this is what's happening here.
|
||||
@ -918,7 +984,7 @@ class PermissionOverwrite:
|
||||
create_polls: Optional[bool]
|
||||
use_external_apps: Optional[bool]
|
||||
|
||||
def __init__(self, **kwargs: Optional[bool]):
|
||||
def __init__(self, **kwargs: Unpack[_PermissionOverwriteKwargs]) -> None:
|
||||
self._values: Dict[str, Optional[bool]] = {}
|
||||
|
||||
for key, value in kwargs.items():
|
||||
@ -980,7 +1046,7 @@ class PermissionOverwrite:
|
||||
"""
|
||||
return len(self._values) == 0
|
||||
|
||||
def update(self, **kwargs: Optional[bool]) -> None:
|
||||
def update(self, **kwargs: Unpack[_PermissionOverwriteKwargs]) -> None:
|
||||
r"""Bulk updates this permission overwrite object.
|
||||
|
||||
Allows you to set multiple attributes by using keyword
|
||||
|
@ -52,6 +52,12 @@ if TYPE_CHECKING:
|
||||
from .activity import BaseActivity
|
||||
from .flags import Intents
|
||||
from .types.gateway import SessionStartLimit
|
||||
from .client import _ClientOptions
|
||||
|
||||
class _AutoShardedClientOptions(_ClientOptions, total=False):
|
||||
shard_ids: List[int]
|
||||
shard_connect_timeout: Optional[float]
|
||||
|
||||
|
||||
__all__ = (
|
||||
'AutoShardedClient',
|
||||
@ -365,7 +371,7 @@ class AutoShardedClient(Client):
|
||||
if TYPE_CHECKING:
|
||||
_connection: AutoShardedConnectionState
|
||||
|
||||
def __init__(self, *args: Any, intents: Intents, **kwargs: Any) -> None:
|
||||
def __init__(self, *args: Any, intents: Intents, **kwargs: Unpack[_AutoShardedClientOptions]) -> None:
|
||||
kwargs.pop('shard_id', None)
|
||||
self.shard_ids: Optional[List[int]] = kwargs.pop('shard_ids', None)
|
||||
self.shard_connect_timeout: Optional[float] = kwargs.pop('shard_connect_timeout', 180.0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user