From b27c689e437f7b6080d2e44c86822268c193fe52 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 27 Aug 2025 17:55:50 +0200 Subject: [PATCH 01/11] Allow extra kwargs for commands.Cog Requires pyright version 1.1.403+ --- discord/ext/commands/cog.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py index 371a9f8c1047..55e70fdb869a 100644 --- a/discord/ext/commands/cog.py +++ b/discord/ext/commands/cog.py @@ -45,13 +45,12 @@ Tuple, TypeVar, Union, - TypedDict, ) from ._types import _BaseCommand, BotT if TYPE_CHECKING: - from typing_extensions import Self, Unpack + from typing_extensions import Self, Unpack, TypedDict from discord.abc import Snowflake from discord._types import ClientT @@ -59,7 +58,7 @@ from .context import Context from .core import Command, _CommandDecoratorKwargs - class _CogKwargs(TypedDict, total=False): + class _CogKwargs(TypedDict, total=False, extra_items=Any): name: str group_name: Union[str, app_commands.locale_str] description: str From 987f17eb0a8a9ad7a89784786b3012ddd0388985 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 27 Aug 2025 17:57:17 +0200 Subject: [PATCH 02/11] Fix group kwargs not being allowed in command_attrs --- discord/ext/commands/cog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py index 55e70fdb869a..54f1169210e3 100644 --- a/discord/ext/commands/cog.py +++ b/discord/ext/commands/cog.py @@ -56,7 +56,7 @@ from .bot import BotBase from .context import Context - from .core import Command, _CommandDecoratorKwargs + from .core import Command, _GroupDecoratorKwargs class _CogKwargs(TypedDict, total=False, extra_items=Any): name: str @@ -66,7 +66,7 @@ class _CogKwargs(TypedDict, total=False, extra_items=Any): group_nsfw: bool group_auto_locale_strings: bool group_extras: Dict[Any, Any] - command_attrs: _CommandDecoratorKwargs + command_attrs: _GroupDecoratorKwargs __all__ = ( From 0e975367afb6ef5ececa0bfba45740c00e93183f Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 27 Aug 2025 18:11:48 +0200 Subject: [PATCH 03/11] Fix various kwargs not being none-able --- discord/client.py | 20 ++++++++++---------- discord/ext/commands/bot.py | 4 ++-- discord/ext/commands/core.py | 6 +++--- discord/ext/commands/help.py | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/discord/client.py b/discord/client.py index cfd8fb1225a8..63c86f352485 100644 --- a/discord/client.py +++ b/discord/client.py @@ -124,25 +124,25 @@ from .flags import MemberCacheFlags class _ClientOptions(TypedDict, total=False): - max_messages: int - proxy: str - proxy_auth: aiohttp.BasicAuth - shard_id: int - shard_count: int + max_messages: Optional[int] + proxy: Optional[str] + proxy_auth: Optional[aiohttp.BasicAuth] + shard_id: Optional[int] + shard_count: Optional[int] application_id: int member_cache_flags: MemberCacheFlags chunk_guilds_at_startup: bool - status: Status - activity: BaseActivity - allowed_mentions: AllowedMentions + status: Optional[Status] + activity: Optional[BaseActivity] + allowed_mentions: Optional[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 + max_ratelimit_timeout: Optional[float] + connector: Optional[aiohttp.BaseConnector] # fmt: off diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py index 3a916d69e0b4..0bb4cf95f5ed 100644 --- a/discord/ext/commands/bot.py +++ b/discord/ext/commands/bot.py @@ -89,8 +89,8 @@ PrefixType = Union[_Prefix, _PrefixCallable[BotT]] class _BotOptions(_ClientOptions, total=False): - owner_id: int - owner_ids: Collection[int] + owner_id: Optional[int] + owner_ids: Optional[Collection[int]] strip_after_prefix: bool case_insensitive: bool diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 9ec0dd484438..f719e977dc72 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -68,9 +68,9 @@ class _CommandDecoratorKwargs(TypedDict, total=False): enabled: bool - help: str - brief: str - usage: str + help: Optional[str] + brief: Optional[str] + usage: Optional[str] rest_is_raw: bool aliases: List[str] description: str diff --git a/discord/ext/commands/help.py b/discord/ext/commands/help.py index dabbd9ef9c8d..8fee7b1c6056 100644 --- a/discord/ext/commands/help.py +++ b/discord/ext/commands/help.py @@ -69,13 +69,13 @@ class _HelpCommandOptions(TypedDict, total=False): show_hidden: bool - verify_checks: bool + verify_checks: Optional[bool] command_attrs: _CommandKwargs class _BaseHelpCommandOptions(_HelpCommandOptions, total=False): sort_commands: bool - dm_help: bool - dm_help_threshold: int + dm_help: Optional[bool] + dm_help_threshold: Optional[int] no_category: str paginator: Paginator commands_heading: str @@ -1364,8 +1364,8 @@ class MinimalHelpCommand(HelpCommand): 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.dm_help: Optional[bool] = options.pop('dm_help', False) + self.dm_help_threshold: Optional[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') From 04a41a276719ba4ac924c223624887066d95d6f2 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 27 Aug 2025 18:35:06 +0200 Subject: [PATCH 04/11] dm_help_threshold cannot be None --- discord/ext/commands/help.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/ext/commands/help.py b/discord/ext/commands/help.py index 8fee7b1c6056..d84a50681888 100644 --- a/discord/ext/commands/help.py +++ b/discord/ext/commands/help.py @@ -75,7 +75,7 @@ class _HelpCommandOptions(TypedDict, total=False): class _BaseHelpCommandOptions(_HelpCommandOptions, total=False): sort_commands: bool dm_help: Optional[bool] - dm_help_threshold: Optional[int] + dm_help_threshold: int no_category: str paginator: Paginator commands_heading: str @@ -1365,7 +1365,7 @@ 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: Optional[bool] = options.pop('dm_help', False) - self.dm_help_threshold: Optional[int] = options.pop('dm_help_threshold', 1000) + 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') From 53b417889b0efe9e0148624c3eba0cc98c035575 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 27 Aug 2025 18:36:02 +0200 Subject: [PATCH 05/11] type dm_help as Optional[bool] on DefaultHelpCommand --- discord/ext/commands/help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/help.py b/discord/ext/commands/help.py index d84a50681888..3731ec6493c8 100644 --- a/discord/ext/commands/help.py +++ b/discord/ext/commands/help.py @@ -1070,7 +1070,7 @@ 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) - self.dm_help: bool = options.pop('dm_help', False) + self.dm_help: Optional[bool] = options.pop('dm_help', False) self.dm_help_threshold: int = options.pop('dm_help_threshold', 1000) self.arguments_heading: str = options.pop('arguments_heading', 'Arguments:') self.commands_heading: str = options.pop('commands_heading', 'Commands:') From 7d0986afd5ffd8c2b21b0520fc006027ee4b84c3 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:10:56 +0200 Subject: [PATCH 06/11] Add missing case_insensitive, fallback_locale and fix fallback type for hybrids --- discord/ext/commands/hybrid.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/discord/ext/commands/hybrid.py b/discord/ext/commands/hybrid.py index 70d18f5d14cd..2e88a46d0a95 100644 --- a/discord/ext/commands/hybrid.py +++ b/discord/ext/commands/hybrid.py @@ -67,10 +67,12 @@ class _HybridGroupKwargs(_HybridCommandDecoratorKwargs, total=False): default_permissions: bool nsfw: bool description: str + case_insensitive: bool class _HybridGroupDecoratorKwargs(_HybridGroupKwargs, total=False): description: Union[str, app_commands.locale_str] - fallback: Union[str, app_commands.locale_str] + fallback: str + fallback_locale: Optional[app_commands.locale_str] __all__ = ( From ecb7d5a170d287a31522fbfba5644965835124ab Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:16:18 +0200 Subject: [PATCH 07/11] aliases can be list | tuple --- discord/ext/commands/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index f719e977dc72..3cc96fea8950 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -72,7 +72,7 @@ class _CommandDecoratorKwargs(TypedDict, total=False): brief: Optional[str] usage: Optional[str] rest_is_raw: bool - aliases: List[str] + aliases: Union[List[str], Tuple[str, ...]] description: str hidden: bool checks: List[UserCheck[Context[Any]]] From 6f27845e6dd43242409f9c1310149e187acff334 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:41:55 +0200 Subject: [PATCH 08/11] fallback can be None --- discord/ext/commands/hybrid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/hybrid.py b/discord/ext/commands/hybrid.py index 2e88a46d0a95..6687104cbff4 100644 --- a/discord/ext/commands/hybrid.py +++ b/discord/ext/commands/hybrid.py @@ -71,7 +71,7 @@ class _HybridGroupKwargs(_HybridCommandDecoratorKwargs, total=False): class _HybridGroupDecoratorKwargs(_HybridGroupKwargs, total=False): description: Union[str, app_commands.locale_str] - fallback: str + fallback: Optional[str] fallback_locale: Optional[app_commands.locale_str] From 93ac32839d17916b07b9cc475c1a111f77dd4193 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:57:05 +0200 Subject: [PATCH 09/11] Tuple[str] -> Tuple[str, ...] for aliases --- discord/ext/commands/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py index 3cc96fea8950..949539b61176 100644 --- a/discord/ext/commands/core.py +++ b/discord/ext/commands/core.py @@ -449,7 +449,7 @@ def __init__( self.brief: Optional[str] = kwargs.get('brief') self.usage: Optional[str] = kwargs.get('usage') self.rest_is_raw: bool = kwargs.get('rest_is_raw', False) - self.aliases: Union[List[str], Tuple[str]] = kwargs.get('aliases', []) + self.aliases: Union[List[str], Tuple[str, ...]] = kwargs.get('aliases', []) self.extras: Dict[Any, Any] = kwargs.get('extras', {}) if not isinstance(self.aliases, (list, tuple)): From cc4d4614ff5c794c823b640dd2af90f9da049400 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Thu, 28 Aug 2025 18:58:32 +0200 Subject: [PATCH 10/11] verify_checks can be bool | None as documented --- discord/ext/commands/help.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/ext/commands/help.py b/discord/ext/commands/help.py index 3731ec6493c8..10648b4cc1cc 100644 --- a/discord/ext/commands/help.py +++ b/discord/ext/commands/help.py @@ -394,7 +394,7 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Self: 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.verify_checks: Optional[bool] = options.pop('verify_checks', True) self.command_attrs = attrs = options.pop('command_attrs', {}) attrs.setdefault('name', 'help') attrs.setdefault('help', 'Shows this message') From 3aada1ab592280282a81194fce90373c0ac11332 Mon Sep 17 00:00:00 2001 From: Soheab_ <33902984+Soheab@users.noreply.github.com> Date: Wed, 3 Sep 2025 13:08:46 +0200 Subject: [PATCH 11/11] Remove _CogKwargs --- discord/ext/commands/cog.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py index 54f1169210e3..b6d2ab0c1805 100644 --- a/discord/ext/commands/cog.py +++ b/discord/ext/commands/cog.py @@ -50,23 +50,13 @@ from ._types import _BaseCommand, BotT if TYPE_CHECKING: - from typing_extensions import Self, Unpack, TypedDict + from typing_extensions import Self from discord.abc import Snowflake from discord._types import ClientT from .bot import BotBase from .context import Context - from .core import Command, _GroupDecoratorKwargs - - class _CogKwargs(TypedDict, total=False, extra_items=Any): - 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: _GroupDecoratorKwargs + from .core import Command __all__ = ( @@ -181,7 +171,7 @@ async def bar(self, ctx): __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: Unpack[_CogKwargs]) -> CogMeta: + def __new__(cls, *args: Any, **kwargs: Any) -> CogMeta: name, bases, attrs = args if any(issubclass(base, app_commands.Group) for base in bases): raise TypeError(