mirror of
https://github.com/stoatchat/python-client-sdk.git
synced 2026-07-25 08:25:28 -04:00
rename typevars to be more informative
This commit is contained in:
@@ -9,15 +9,15 @@ from .command import Command
|
||||
from .context import Context
|
||||
from .errors import (MissingPermissionsError, NotBotOwner, NotServerOwner,
|
||||
ServerOnly)
|
||||
from .utils import ClientT
|
||||
from .utils import ClientT_D
|
||||
|
||||
__all__ = ("check", "Check", "is_bot_owner", "is_server_owner", "has_permissions", "has_channel_permissions")
|
||||
|
||||
T = TypeVar("T", Callable[..., Any], Command, default=Command)
|
||||
|
||||
Check = Callable[[Context[ClientT]], Union[Any, Coroutine[Any, Any, Any]]]
|
||||
Check = Callable[[Context[ClientT_D]], Union[Any, Coroutine[Any, Any, Any]]]
|
||||
|
||||
def check(check: Check[ClientT]) -> Callable[[T], T]:
|
||||
def check(check: Check[ClientT_D]) -> Callable[[T], T]:
|
||||
"""A decorator for adding command checks
|
||||
|
||||
Parameters
|
||||
@@ -27,7 +27,7 @@ def check(check: Check[ClientT]) -> Callable[[T], T]:
|
||||
"""
|
||||
def inner(func: T) -> T:
|
||||
if isinstance(func, Command):
|
||||
command = cast(Command[ClientT], func) # cant verify generic at runtime so must cast
|
||||
command = cast(Command[ClientT_D], func) # cant verify generic at runtime so must cast
|
||||
command.checks.append(check)
|
||||
else:
|
||||
checks = getattr(func, "_checks", [])
|
||||
@@ -41,7 +41,7 @@ def check(check: Check[ClientT]) -> Callable[[T], T]:
|
||||
def is_bot_owner() -> Callable[[T], T]:
|
||||
"""A command check for limiting the command to only the bot's owner"""
|
||||
@check
|
||||
def inner(context: Context[ClientT]):
|
||||
def inner(context: Context[ClientT_D]):
|
||||
if user_id := context.client.user.owner_id:
|
||||
if context.author.id == user_id:
|
||||
return True
|
||||
@@ -56,7 +56,7 @@ def is_bot_owner() -> Callable[[T], T]:
|
||||
def is_server_owner() -> Callable[[T], T]:
|
||||
"""A command check for limiting the command to only a server's owner"""
|
||||
@check
|
||||
def inner(context: Context[ClientT]) -> bool:
|
||||
def inner(context: Context[ClientT_D]) -> bool:
|
||||
if not context.server_id:
|
||||
raise ServerOnly
|
||||
|
||||
@@ -69,7 +69,7 @@ def is_server_owner() -> Callable[[T], T]:
|
||||
|
||||
def has_permissions(**permissions: bool) -> Callable[[T], T]:
|
||||
@check
|
||||
def inner(context: Context[ClientT]) -> bool:
|
||||
def inner(context: Context[ClientT_D]) -> bool:
|
||||
author = context.author
|
||||
|
||||
if not author.has_permissions(**permissions):
|
||||
@@ -81,7 +81,7 @@ def has_permissions(**permissions: bool) -> Callable[[T], T]:
|
||||
|
||||
def has_channel_permissions(**permissions: bool) -> Callable[[T], T]:
|
||||
@check
|
||||
def inner(context: Context[ClientT]) -> bool:
|
||||
def inner(context: Context[ClientT_D]) -> bool:
|
||||
author = context.author
|
||||
|
||||
if not isinstance(author, revolt.Member):
|
||||
|
||||
+15
-11
@@ -4,30 +4,34 @@ from typing import Any, Generic, Optional, cast
|
||||
from typing_extensions import Self
|
||||
|
||||
from .command import Command
|
||||
from .utils import ClientT
|
||||
from .utils import ClientT_D
|
||||
|
||||
__all__ = ("Cog", "CogMeta")
|
||||
|
||||
class CogMeta(type, Generic[ClientT]):
|
||||
_commands: list[Command[ClientT]]
|
||||
class CogMeta(type, Generic[ClientT_D]):
|
||||
_commands: list[Command[ClientT_D]]
|
||||
qualified_name: str
|
||||
|
||||
def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any], *, qualified_name: Optional[str] = None) -> Self:
|
||||
commands: list[Command[ClientT]] = []
|
||||
def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any], *, qualified_name: Optional[str] = None, extras: dict[str, Any] | None = None) -> Self:
|
||||
commands: list[Command[ClientT_D]] = []
|
||||
self = super().__new__(cls, name, bases, attrs)
|
||||
extras = extras or {}
|
||||
|
||||
for base in reversed(self.__mro__):
|
||||
for value in base.__dict__.values():
|
||||
if isinstance(value, Command):
|
||||
commands.append(cast(Command[ClientT], value)) # cant verify generic at runtime so must cast
|
||||
for key, value in extras.items():
|
||||
setattr(value, key, value)
|
||||
|
||||
commands.append(cast(Command[ClientT_D], value)) # cant verify generic at runtime so must cast
|
||||
|
||||
|
||||
self._commands = commands
|
||||
self.qualified_name = qualified_name or name
|
||||
return self
|
||||
|
||||
class Cog(Generic[ClientT], metaclass=CogMeta):
|
||||
_commands: list[Command[ClientT]]
|
||||
class Cog(Generic[ClientT_D], metaclass=CogMeta):
|
||||
_commands: list[Command[ClientT_D]]
|
||||
qualified_name: str
|
||||
|
||||
def cog_load(self) -> None:
|
||||
@@ -38,7 +42,7 @@ class Cog(Generic[ClientT], metaclass=CogMeta):
|
||||
"""A special method that is called when the cog gets removed."""
|
||||
pass
|
||||
|
||||
def _inject(self, client: ClientT) -> None:
|
||||
def _inject(self, client: ClientT_D) -> None:
|
||||
client.cogs[self.qualified_name] = self
|
||||
|
||||
for command in self._commands:
|
||||
@@ -49,7 +53,7 @@ class Cog(Generic[ClientT], metaclass=CogMeta):
|
||||
|
||||
self.cog_load()
|
||||
|
||||
def _uninject(self, client: ClientT) -> None:
|
||||
def _uninject(self, client: ClientT_D) -> None:
|
||||
for name, command in client.all_commands.copy().items():
|
||||
if command in self._commands:
|
||||
del client.all_commands[name]
|
||||
@@ -57,5 +61,5 @@ class Cog(Generic[ClientT], metaclass=CogMeta):
|
||||
self.cog_unload()
|
||||
|
||||
@property
|
||||
def commands(self) -> list[Command[ClientT]]:
|
||||
def commands(self) -> list[Command[ClientT_D]]:
|
||||
return self._commands
|
||||
|
||||
@@ -10,7 +10,7 @@ from typing_extensions import ParamSpec
|
||||
from revolt.utils import maybe_coroutine
|
||||
|
||||
from .errors import InvalidLiteralArgument, UnionConverterError
|
||||
from .utils import ClientCoT, evaluate_parameters
|
||||
from .utils import ClientT_Co_D, evaluate_parameters, ClientT_Co
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .checks import Check
|
||||
@@ -26,7 +26,7 @@ __all__: tuple[str, ...] = (
|
||||
NoneType: type[None] = type(None)
|
||||
P = ParamSpec("P")
|
||||
|
||||
class Command(Generic[ClientCoT]):
|
||||
class Command(Generic[ClientT_Co_D]):
|
||||
"""Class for holding info about a command.
|
||||
|
||||
Parameters
|
||||
@@ -43,8 +43,14 @@ class Command(Generic[ClientCoT]):
|
||||
The cog the command is apart of.
|
||||
usage: Optional[:class:`str`]
|
||||
The usage string for the command
|
||||
checks: list[Callable]
|
||||
The list of checks the command has
|
||||
description: Optional[:class:`str`]
|
||||
The commands description if it has one
|
||||
hidden: :class:`bool`
|
||||
Whether or not the command should be hidden from the help command
|
||||
"""
|
||||
__slots__ = ("callback", "name", "aliases", "signature", "checks", "parent", "_error_handler", "cog", "description", "usage", "parameters")
|
||||
__slots__ = ("callback", "name", "aliases", "signature", "checks", "parent", "_error_handler", "cog", "description", "usage", "parameters", "hidden")
|
||||
|
||||
def __init__(self, callback: Callable[..., Coroutine[Any, Any, Any]], name: str, aliases: list[str], usage: Optional[str] = None):
|
||||
self.callback: Callable[..., Coroutine[Any, Any, Any]] = callback
|
||||
@@ -53,13 +59,14 @@ class Command(Generic[ClientCoT]):
|
||||
self.usage: str | None = usage
|
||||
self.signature: inspect.Signature = inspect.signature(self.callback)
|
||||
self.parameters: list[inspect.Parameter] = evaluate_parameters(self.signature.parameters.values(), getattr(callback, "__globals__", {}))
|
||||
self.checks: list[Check[ClientCoT]] = getattr(callback, "_checks", [])
|
||||
self.parent: Optional[Group[ClientCoT]] = None
|
||||
self.cog: Optional[Cog[ClientCoT]] = None
|
||||
self._error_handler: Callable[[Any, Context[ClientCoT], Exception], Coroutine[Any, Any, Any]] = type(self)._default_error_handler
|
||||
self.checks: list[Check[ClientT_Co_D]] = getattr(callback, "_checks", [])
|
||||
self.parent: Optional[Group[ClientT_Co_D]] = None
|
||||
self.cog: Optional[Cog[ClientT_Co_D]] = None
|
||||
self._error_handler: Callable[[Any, Context[ClientT_Co_D], Exception], Coroutine[Any, Any, Any]] = type(self)._default_error_handler
|
||||
self.description: str | None = callback.__doc__
|
||||
self.hidden: bool = False
|
||||
|
||||
async def invoke(self, context: Context[ClientCoT], *args: Any, **kwargs: Any) -> Any:
|
||||
async def invoke(self, context: Context[ClientT_Co_D], *args: Any, **kwargs: Any) -> Any:
|
||||
"""Runs the command and calls the error handler if the command errors.
|
||||
|
||||
Parameters
|
||||
@@ -74,7 +81,7 @@ class Command(Generic[ClientCoT]):
|
||||
except Exception as err:
|
||||
return await self._error_handler(self.cog or context.client, context, err)
|
||||
|
||||
def __call__(self, context: Context[ClientCoT], *args: Any, **kwargs: Any) -> Any:
|
||||
def __call__(self, context: Context[ClientT_Co_D], *args: Any, **kwargs: Any) -> Any:
|
||||
return self.invoke(context, *args, **kwargs)
|
||||
|
||||
def error(self, func: Callable[..., Coroutine[Any, Any, Any]]) -> Callable[..., Coroutine[Any, Any, Any]]:
|
||||
@@ -97,11 +104,11 @@ class Command(Generic[ClientCoT]):
|
||||
self._error_handler = func
|
||||
return func
|
||||
|
||||
async def _default_error_handler(self, ctx: Context[ClientCoT], error: Exception):
|
||||
async def _default_error_handler(self, ctx: Context[ClientT_Co_D], error: Exception):
|
||||
traceback.print_exception(type(error), error, error.__traceback__)
|
||||
|
||||
@classmethod
|
||||
async def handle_origin(cls, context: Context[ClientCoT], origin: Any, annotation: Any, arg: str) -> Any:
|
||||
async def handle_origin(cls, context: Context[ClientT_Co_D], origin: Any, annotation: Any, arg: str) -> Any:
|
||||
if origin is Union:
|
||||
for converter in get_args(annotation):
|
||||
try:
|
||||
@@ -128,7 +135,7 @@ class Command(Generic[ClientCoT]):
|
||||
raise InvalidLiteralArgument(arg)
|
||||
|
||||
@classmethod
|
||||
async def convert_argument(cls, arg: str, annotation: Any, context: Context[ClientCoT]) -> Any:
|
||||
async def convert_argument(cls, arg: str, annotation: Any, context: Context[ClientT_Co_D]) -> Any:
|
||||
if annotation is not inspect.Signature.empty:
|
||||
if annotation is str: # no converting is needed - its already a string
|
||||
return arg
|
||||
@@ -141,7 +148,7 @@ class Command(Generic[ClientCoT]):
|
||||
else:
|
||||
return arg
|
||||
|
||||
async def parse_arguments(self, context: Context[ClientCoT]) -> None:
|
||||
async def parse_arguments(self, context: Context[ClientT_Co_D]) -> None:
|
||||
# please pr if you can think of a better way to do this
|
||||
|
||||
for parameter in self.parameters[2:]:
|
||||
@@ -214,7 +221,13 @@ class Command(Generic[ClientCoT]):
|
||||
|
||||
return f"{' '.join(parents[::-1])} {self.name} {' '.join(parameters)}"
|
||||
|
||||
def command(*, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: type[Command[ClientCoT]] = Command, usage: Optional[str] = None) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Command[ClientCoT]]:
|
||||
def command(
|
||||
*,
|
||||
name: Optional[str] = None,
|
||||
aliases: Optional[list[str]] = None,
|
||||
cls: type[Command[ClientT_Co]] = Command,
|
||||
usage: Optional[str] = None
|
||||
) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Command[ClientT_Co]]:
|
||||
"""A decorator that turns a function into a :class:`Command`.n
|
||||
|
||||
Parameters
|
||||
@@ -231,7 +244,7 @@ def command(*, name: Optional[str] = None, aliases: Optional[list[str]] = None,
|
||||
Callable[Callable[..., Coroutine], :class:`Command`]
|
||||
A function that takes the command callback and returns a :class:`Command`
|
||||
"""
|
||||
def inner(func: Callable[..., Coroutine[Any, Any, Any]]):
|
||||
def inner(func: Callable[..., Coroutine[Any, Any, Any]]) -> Command[ClientT_Co]:
|
||||
return cls(func, name or func.__name__, aliases or [], usage)
|
||||
|
||||
return inner
|
||||
|
||||
@@ -7,7 +7,7 @@ from revolt.utils import maybe_coroutine
|
||||
|
||||
from .command import Command
|
||||
from .group import Group
|
||||
from .utils import ClientCoT
|
||||
from .utils import ClientT_Co_D
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .view import StringView
|
||||
@@ -17,7 +17,7 @@ __all__ = (
|
||||
"Context",
|
||||
)
|
||||
|
||||
class Context(revolt.Messageable, Generic[ClientCoT]):
|
||||
class Context(revolt.Messageable, Generic[ClientT_Co_D]):
|
||||
"""Stores metadata the commands execution.
|
||||
|
||||
Attributes
|
||||
@@ -46,12 +46,12 @@ class Context(revolt.Messageable, Generic[ClientCoT]):
|
||||
async def _get_channel_id(self) -> str:
|
||||
return self.channel.id
|
||||
|
||||
def __init__(self, command: Optional[Command[ClientCoT]], invoked_with: str, view: StringView, message: revolt.Message, client: ClientCoT):
|
||||
self.command: Command[ClientCoT] | None = command
|
||||
def __init__(self, command: Optional[Command[ClientT_Co_D]], invoked_with: str, view: StringView, message: revolt.Message, client: ClientT_Co_D):
|
||||
self.command: Command[ClientT_Co_D] | None = command
|
||||
self.invoked_with: str = invoked_with
|
||||
self.view: StringView = view
|
||||
self.message: revolt.Message = message
|
||||
self.client: ClientCoT = client
|
||||
self.client: ClientT_Co_D = client
|
||||
self.args: list[Any] = []
|
||||
self.kwargs: dict[str, Any] = {}
|
||||
self.server_id: str | None = message.server_id
|
||||
@@ -100,13 +100,13 @@ class Context(revolt.Messageable, Generic[ClientCoT]):
|
||||
await command.parse_arguments(self)
|
||||
return await command.invoke(self, *self.args, **self.kwargs)
|
||||
|
||||
async def can_run(self, command: Optional[Command[ClientCoT]] = None) -> bool:
|
||||
async def can_run(self, command: Optional[Command[ClientT_Co_D]] = None) -> bool:
|
||||
"""Runs all of the commands checks, and returns true if all of them pass"""
|
||||
command = command or self.command
|
||||
|
||||
return all([await maybe_coroutine(check, self) for check in (command.checks if command else [])])
|
||||
|
||||
async def send_help(self, argument: Command[Any] | Group[Any] | ClientCoT | None = None) -> None:
|
||||
async def send_help(self, argument: Command[Any] | Group[Any] | ClientT_Co_D | None = None) -> None:
|
||||
argument = argument or self.client
|
||||
|
||||
command = self.client.get_command("help")
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from typing import Any, Callable, Coroutine, Optional
|
||||
|
||||
from .command import Command
|
||||
from .utils import ClientCoT, ClientT
|
||||
from .utils import ClientT_Co_D, ClientT_D
|
||||
|
||||
|
||||
__all__ = (
|
||||
@@ -11,7 +11,7 @@ __all__ = (
|
||||
"group"
|
||||
)
|
||||
|
||||
class Group(Command[ClientCoT]):
|
||||
class Group(Command[ClientT_Co_D]):
|
||||
"""Class for holding info about a group command.
|
||||
|
||||
Parameters
|
||||
@@ -29,10 +29,10 @@ class Group(Command[ClientCoT]):
|
||||
__slots__: tuple[str, ...] = ("subcommands",)
|
||||
|
||||
def __init__(self, callback: Callable[..., Coroutine[Any, Any, Any]], name: str, aliases: list[str]):
|
||||
self.subcommands: dict[str, Command[ClientCoT]] = {}
|
||||
self.subcommands: dict[str, Command[ClientT_Co_D]] = {}
|
||||
super().__init__(callback, name, aliases)
|
||||
|
||||
def command(self, *, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: type[Command[ClientCoT]] = Command[ClientCoT]) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Command[ClientCoT]]:
|
||||
def command(self, *, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: type[Command[ClientT_Co_D]] = Command[ClientT_Co_D]) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Command[ClientT_Co_D]]:
|
||||
"""A decorator that turns a function into a :class:`Command` and registers the command as a subcommand.
|
||||
|
||||
Parameters
|
||||
@@ -61,7 +61,7 @@ class Group(Command[ClientCoT]):
|
||||
|
||||
return inner
|
||||
|
||||
def group(self, *, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: Optional[type[Group[ClientCoT]]] = None) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Group[ClientCoT]]:
|
||||
def group(self, *, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: Optional[type[Group[ClientT_Co_D]]] = None) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Group[ClientT_Co_D]]:
|
||||
"""A decorator that turns a function into a :class:`Group` and registers the command as a subcommand
|
||||
|
||||
Parameters
|
||||
@@ -96,7 +96,7 @@ class Group(Command[ClientCoT]):
|
||||
return f"<Group name=\"{self.name}\">"
|
||||
|
||||
@property
|
||||
def commands(self) -> list[Command[ClientCoT]]:
|
||||
def commands(self) -> list[Command[ClientT_Co_D]]:
|
||||
"""Gets all commands registered
|
||||
|
||||
Returns
|
||||
@@ -106,7 +106,7 @@ class Group(Command[ClientCoT]):
|
||||
"""
|
||||
return list(set(self.subcommands.values()))
|
||||
|
||||
def get_command(self, name: str) -> Command[ClientCoT]:
|
||||
def get_command(self, name: str) -> Command[ClientT_Co_D]:
|
||||
"""Gets a command.
|
||||
|
||||
Parameters
|
||||
@@ -121,7 +121,7 @@ class Group(Command[ClientCoT]):
|
||||
"""
|
||||
return self.subcommands[name]
|
||||
|
||||
def add_command(self, command: Command[ClientCoT]) -> None:
|
||||
def add_command(self, command: Command[ClientT_Co_D]) -> None:
|
||||
"""Adds a command, this is typically only used for dynamic commands, you should use the `commands.command` decorator for most usecases.
|
||||
|
||||
Parameters
|
||||
@@ -136,7 +136,7 @@ class Group(Command[ClientCoT]):
|
||||
for alias in command.aliases:
|
||||
self.subcommands[alias] = command
|
||||
|
||||
def remove_command(self, name: str) -> Optional[Command[ClientCoT]]:
|
||||
def remove_command(self, name: str) -> Optional[Command[ClientT_Co_D]]:
|
||||
"""Removes a command.
|
||||
|
||||
Parameters
|
||||
@@ -157,7 +157,7 @@ class Group(Command[ClientCoT]):
|
||||
|
||||
return command
|
||||
|
||||
def group(*, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: type[Group[ClientT]] = Group) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Group[ClientT]]:
|
||||
def group(*, name: Optional[str] = None, aliases: Optional[list[str]] = None, cls: type[Group[ClientT_D]] = Group) -> Callable[[Callable[..., Coroutine[Any, Any, Any]]], Group[ClientT_D]]:
|
||||
"""A decorator that turns a function into a :class:`Group`
|
||||
|
||||
Parameters
|
||||
|
||||
+29
-26
@@ -9,7 +9,7 @@ from .cog import Cog
|
||||
from .command import Command
|
||||
from .context import Context
|
||||
from .group import Group
|
||||
from .utils import ClientCoT, ClientT
|
||||
from .utils import ClientT_Co_D, ClientT_D
|
||||
|
||||
from revolt import File, Message, Messageable, MessageReply, SendableEmbed
|
||||
|
||||
@@ -26,30 +26,33 @@ class MessagePayload(TypedDict):
|
||||
attachments: NotRequired[list[File]]
|
||||
replies: NotRequired[list[MessageReply]]
|
||||
|
||||
class HelpCommand(ABC, Generic[ClientCoT]):
|
||||
class HelpCommand(ABC, Generic[ClientT_Co_D]):
|
||||
@abstractmethod
|
||||
async def create_global_help(self, context: Context[ClientCoT], commands: dict[Optional[Cog[ClientCoT]], list[Command[ClientCoT]]]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_global_help(self, context: Context[ClientT_Co_D], commands: dict[Optional[Cog[ClientT_Co_D]], list[Command[ClientT_Co_D]]]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
async def create_command_help(self, context: Context[ClientCoT], command: Command[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_command_help(self, context: Context[ClientT_Co_D], command: Command[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
async def create_group_help(self, context: Context[ClientCoT], group: Group[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_group_help(self, context: Context[ClientT_Co_D], group: Group[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
async def create_cog_help(self, context: Context[ClientCoT], cog: Cog[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_cog_help(self, context: Context[ClientT_Co_D], cog: Cog[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def send_help_command(self, context: Context[ClientCoT], message_payload: MessagePayload) -> Message:
|
||||
async def send_help_command(self, context: Context[ClientT_Co_D], message_payload: MessagePayload) -> Message:
|
||||
return await context.send(**message_payload)
|
||||
|
||||
async def filter_commands(self, context: Context[ClientCoT], commands: list[Command[ClientCoT]]) -> list[Command[ClientCoT]]:
|
||||
filtered: list[Command[ClientCoT]] = []
|
||||
async def filter_commands(self, context: Context[ClientT_Co_D], commands: list[Command[ClientT_Co_D]]) -> list[Command[ClientT_Co_D]]:
|
||||
filtered: list[Command[ClientT_Co_D]] = []
|
||||
|
||||
for command in commands:
|
||||
if command.hidden:
|
||||
continue
|
||||
|
||||
try:
|
||||
if await context.can_run(command):
|
||||
filtered.append(command)
|
||||
@@ -58,29 +61,29 @@ class HelpCommand(ABC, Generic[ClientCoT]):
|
||||
|
||||
return filtered
|
||||
|
||||
async def group_commands(self, context: Context[ClientCoT], commands: list[Command[ClientCoT]]) -> dict[Optional[Cog[ClientCoT]], list[Command[ClientCoT]]]:
|
||||
cogs: dict[Optional[Cog[ClientCoT]], list[Command[ClientCoT]]] = {}
|
||||
async def group_commands(self, context: Context[ClientT_Co_D], commands: list[Command[ClientT_Co_D]]) -> dict[Optional[Cog[ClientT_Co_D]], list[Command[ClientT_Co_D]]]:
|
||||
cogs: dict[Optional[Cog[ClientT_Co_D]], list[Command[ClientT_Co_D]]] = {}
|
||||
|
||||
for command in commands:
|
||||
cogs.setdefault(command.cog, []).append(command)
|
||||
|
||||
return cogs
|
||||
|
||||
async def handle_message(self, context: Context[ClientCoT], message: Message) -> None:
|
||||
async def handle_message(self, context: Context[ClientT_Co_D], message: Message) -> None:
|
||||
pass
|
||||
|
||||
async def get_channel(self, context: Context) -> Messageable:
|
||||
return context
|
||||
|
||||
@abstractmethod
|
||||
async def handle_no_command_found(self, context: Context[ClientCoT], name: str) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def handle_no_command_found(self, context: Context[ClientT_Co_D], name: str) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
raise NotImplementedError
|
||||
|
||||
class DefaultHelpCommand(HelpCommand[ClientCoT]):
|
||||
class DefaultHelpCommand(HelpCommand[ClientT_Co_D]):
|
||||
def __init__(self, default_cog_name: str = "No Cog"):
|
||||
self.default_cog_name = default_cog_name
|
||||
|
||||
async def create_global_help(self, context: Context[ClientCoT], commands: dict[Optional[Cog[ClientCoT]], list[Command[ClientCoT]]]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_global_help(self, context: Context[ClientT_Co_D], commands: dict[Optional[Cog[ClientT_Co_D]], list[Command[ClientT_Co_D]]]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
lines = ["```"]
|
||||
|
||||
for cog, cog_commands in commands.items():
|
||||
@@ -95,7 +98,7 @@ class DefaultHelpCommand(HelpCommand[ClientCoT]):
|
||||
lines.append("```")
|
||||
return "\n".join(lines)
|
||||
|
||||
async def create_cog_help(self, context: Context[ClientCoT], cog: Cog[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_cog_help(self, context: Context[ClientT_Co_D], cog: Cog[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
lines = ["```"]
|
||||
|
||||
lines.append(f"{cog.qualified_name}:")
|
||||
@@ -106,7 +109,7 @@ class DefaultHelpCommand(HelpCommand[ClientCoT]):
|
||||
lines.append("```")
|
||||
return "\n".join(lines)
|
||||
|
||||
async def create_command_help(self, context: Context[ClientCoT], command: Command[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_command_help(self, context: Context[ClientT_Co_D], command: Command[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
lines = ["```"]
|
||||
|
||||
lines.append(f"{command.name}:")
|
||||
@@ -122,7 +125,7 @@ class DefaultHelpCommand(HelpCommand[ClientCoT]):
|
||||
lines.append("```")
|
||||
return "\n".join(lines)
|
||||
|
||||
async def create_group_help(self, context: Context[ClientCoT], group: Group[ClientCoT]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
async def create_group_help(self, context: Context[ClientT_Co_D], group: Group[ClientT_Co_D]) -> Union[str, SendableEmbed, MessagePayload]:
|
||||
lines = ["```"]
|
||||
|
||||
lines.append(f"{group.name}:")
|
||||
@@ -140,21 +143,21 @@ class DefaultHelpCommand(HelpCommand[ClientCoT]):
|
||||
lines.append("```")
|
||||
return "\n".join(lines)
|
||||
|
||||
async def handle_no_command_found(self, context: Context[ClientCoT], name: str) -> str:
|
||||
async def handle_no_command_found(self, context: Context[ClientT_Co_D], name: str) -> str:
|
||||
return f"Command `{name}` not found."
|
||||
|
||||
class HelpCommandImpl(Command[ClientCoT]):
|
||||
def __init__(self, client: ClientCoT):
|
||||
class HelpCommandImpl(Command[ClientT_Co_D]):
|
||||
def __init__(self, client: ClientT_Co_D):
|
||||
self.client = client
|
||||
|
||||
async def callback(_: Union[ClientCoT, Cog[ClientCoT]], context: Context[ClientCoT], *args: str) -> None:
|
||||
async def callback(_: Union[ClientT_Co_D, Cog[ClientT_Co_D]], context: Context[ClientT_Co_D], *args: str) -> None:
|
||||
await help_command_impl(context.client, context, *args)
|
||||
|
||||
super().__init__(callback=callback, name="help", aliases=[])
|
||||
self.description: str | None = "Shows help for a command, cog or the entire bot"
|
||||
|
||||
|
||||
async def help_command_impl(client: ClientT, context: Context[ClientT], *arguments: str) -> None:
|
||||
async def help_command_impl(client: ClientT_D, context: Context[ClientT_D], *arguments: str) -> None:
|
||||
help_command = client.help_command
|
||||
|
||||
if not help_command:
|
||||
@@ -167,7 +170,7 @@ async def help_command_impl(client: ClientT, context: Context[ClientT], *argumen
|
||||
payload = await help_command.create_global_help(context, commands)
|
||||
|
||||
else:
|
||||
parent: ClientT | Group[ClientT] = client
|
||||
parent: ClientT_D | Group[ClientT_D] = client
|
||||
|
||||
for param in arguments:
|
||||
try:
|
||||
@@ -183,7 +186,7 @@ async def help_command_impl(client: ClientT, context: Context[ClientT], *argumen
|
||||
break
|
||||
|
||||
if isinstance(command, Group):
|
||||
command = cast(Group[ClientT], command)
|
||||
command = cast(Group[ClientT_D], command)
|
||||
parent = command
|
||||
else:
|
||||
payload = await help_command.create_command_help(context, command)
|
||||
@@ -191,7 +194,7 @@ async def help_command_impl(client: ClientT, context: Context[ClientT], *argumen
|
||||
else:
|
||||
|
||||
if TYPE_CHECKING:
|
||||
command = cast(Command[ClientT], ...)
|
||||
command = cast(Command[ClientT_D], ...)
|
||||
|
||||
if isinstance(command, Group):
|
||||
payload = await help_command.create_group_help(context, command)
|
||||
|
||||
@@ -12,9 +12,10 @@ if TYPE_CHECKING:
|
||||
|
||||
__all__ = ("evaluate_parameters",)
|
||||
|
||||
ClientT = TypeVar("ClientT", bound="CommandsClient", default="CommandsClient")
|
||||
ClientCoT = TypeVar("ClientCoT", bound="CommandsClient", default="CommandsClient", covariant=True)
|
||||
ContextT = TypeVar("ContextT", bound="Context")
|
||||
ClientT_Co = TypeVar("ClientT_Co", bound="CommandsClient", covariant=True)
|
||||
ClientT_D = TypeVar("ClientT_D", bound="CommandsClient", default="CommandsClient")
|
||||
ClientT_Co_D = TypeVar("ClientT_Co_D", bound="CommandsClient", default="CommandsClient", covariant=True)
|
||||
ContextT = TypeVar("ContextT", bound="Context", default="Context")
|
||||
|
||||
def evaluate_parameters(parameters: Iterable[Parameter], globals: dict[str, Any]) -> list[Parameter]:
|
||||
new_parameters: list[Parameter] = []
|
||||
|
||||
Reference in New Issue
Block a user