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:
Stocker
2022-03-13 23:52:10 -04:00
committed by GitHub
parent 603681940f
commit 5aa696ccfa
66 changed files with 1071 additions and 802 deletions

View File

@ -22,13 +22,27 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from __future__ import annotations
import itertools
import copy
import functools
import inspect
import re
from typing import Optional, TYPE_CHECKING
from typing import (
TYPE_CHECKING,
Optional,
Generator,
List,
TypeVar,
Callable,
Any,
Dict,
Tuple,
Iterable,
Sequence,
Mapping,
)
import discord.utils
@ -36,7 +50,21 @@ from .core import Group, Command, get_signature_parameters
from .errors import CommandError
if TYPE_CHECKING:
from typing_extensions import Self
import inspect
import discord.abc
from .bot import BotBase
from .context import Context
from .cog import Cog
from ._types import (
Check,
ContextT,
BotT,
_Bot,
)
__all__ = (
'Paginator',
@ -45,7 +73,9 @@ __all__ = (
'MinimalHelpCommand',
)
MISSING = discord.utils.MISSING
FuncT = TypeVar('FuncT', bound=Callable[..., Any])
MISSING: Any = discord.utils.MISSING
# help -> shows info of bot on top/bottom and lists subcommands
# help command -> shows detailed info of command
@ -80,10 +110,10 @@ class Paginator:
Attributes
-----------
prefix: :class:`str`
The prefix inserted to every page. e.g. three backticks.
suffix: :class:`str`
The suffix appended at the end of every page. e.g. three backticks.
prefix: Optional[:class:`str`]
The prefix inserted to every page. e.g. three backticks, if any.
suffix: Optional[:class:`str`]
The suffix appended at the end of every page. e.g. three backticks, if any.
max_size: :class:`int`
The maximum amount of codepoints allowed in a page.
linesep: :class:`str`
@ -91,36 +121,38 @@ class Paginator:
.. versionadded:: 1.7
"""
def __init__(self, prefix='```', suffix='```', max_size=2000, linesep='\n'):
self.prefix = prefix
self.suffix = suffix
self.max_size = max_size
self.linesep = linesep
def __init__(
self, prefix: Optional[str] = '```', suffix: Optional[str] = '```', max_size: int = 2000, linesep: str = '\n'
) -> None:
self.prefix: Optional[str] = prefix
self.suffix: Optional[str] = suffix
self.max_size: int = max_size
self.linesep: str = linesep
self.clear()
def clear(self):
def clear(self) -> None:
"""Clears the paginator to have no pages."""
if self.prefix is not None:
self._current_page = [self.prefix]
self._count = len(self.prefix) + self._linesep_len # prefix + newline
self._current_page: List[str] = [self.prefix]
self._count: int = len(self.prefix) + self._linesep_len # prefix + newline
else:
self._current_page = []
self._count = 0
self._pages = []
self._pages: List[str] = []
@property
def _prefix_len(self):
def _prefix_len(self) -> int:
return len(self.prefix) if self.prefix else 0
@property
def _suffix_len(self):
def _suffix_len(self) -> int:
return len(self.suffix) if self.suffix else 0
@property
def _linesep_len(self):
def _linesep_len(self) -> int:
return len(self.linesep)
def add_line(self, line='', *, empty=False):
def add_line(self, line: str = '', *, empty: bool = False) -> None:
"""Adds a line to the current page.
If the line exceeds the :attr:`max_size` then an exception
@ -152,7 +184,7 @@ class Paginator:
self._current_page.append('')
self._count += self._linesep_len
def close_page(self):
def close_page(self) -> None:
"""Prematurely terminate a page."""
if self.suffix is not None:
self._current_page.append(self.suffix)
@ -165,36 +197,38 @@ class Paginator:
self._current_page = []
self._count = 0
def __len__(self):
def __len__(self) -> int:
total = sum(len(p) for p in self._pages)
return total + self._count
@property
def pages(self):
def pages(self) -> List[str]:
"""List[:class:`str`]: Returns the rendered list of pages."""
# we have more than just the prefix in our current page
if len(self._current_page) > (0 if self.prefix is None else 1):
self.close_page()
return self._pages
def __repr__(self):
def __repr__(self) -> str:
fmt = '<Paginator prefix: {0.prefix!r} suffix: {0.suffix!r} linesep: {0.linesep!r} max_size: {0.max_size} count: {0._count}>'
return fmt.format(self)
def _not_overridden(f):
def _not_overridden(f: FuncT) -> FuncT:
f.__help_command_not_overridden__ = True
return f
class _HelpCommandImpl(Command):
def __init__(self, inject, *args, **kwargs):
def __init__(self, inject: HelpCommand, *args: Any, **kwargs: Any) -> None:
super().__init__(inject.command_callback, *args, **kwargs)
self._original = inject
self._injected = inject
self.params = get_signature_parameters(inject.command_callback, globals(), skip_parameters=1)
self._original: HelpCommand = inject
self._injected: HelpCommand = inject
self.params: Dict[str, inspect.Parameter] = get_signature_parameters(
inject.command_callback, globals(), skip_parameters=1
)
async def prepare(self, ctx):
async def prepare(self, ctx: Context[Any]) -> None:
self._injected = injected = self._original.copy()
injected.context = ctx
self.callback = injected.command_callback
@ -209,7 +243,7 @@ class _HelpCommandImpl(Command):
await super().prepare(ctx)
async def _parse_arguments(self, ctx):
async def _parse_arguments(self, ctx: Context[BotT]) -> None:
# Make the parser think we don't have a cog so it doesn't
# inject the parameter into `ctx.args`.
original_cog = self.cog
@ -219,22 +253,26 @@ class _HelpCommandImpl(Command):
finally:
self.cog = original_cog
async def _on_error_cog_implementation(self, dummy, ctx, error):
async def _on_error_cog_implementation(self, _, ctx: Context[BotT], error: CommandError) -> None:
await self._injected.on_help_command_error(ctx, error)
def _inject_into_cog(self, cog):
def _inject_into_cog(self, cog: Cog) -> None:
# Warning: hacky
# Make the cog think that get_commands returns this command
# as well if we inject it without modifying __cog_commands__
# since that's used for the injection and ejection of cogs.
def wrapped_get_commands(*, _original=cog.get_commands):
def wrapped_get_commands(
*, _original: Callable[[], List[Command[Any, ..., Any]]] = cog.get_commands
) -> List[Command[Any, ..., Any]]:
ret = _original()
ret.append(self)
return ret
# Ditto here
def wrapped_walk_commands(*, _original=cog.walk_commands):
def wrapped_walk_commands(
*, _original: Callable[[], Generator[Command[Any, ..., Any], None, None]] = cog.walk_commands
):
yield from _original()
yield self
@ -244,7 +282,7 @@ class _HelpCommandImpl(Command):
cog.walk_commands = wrapped_walk_commands
self.cog = cog
def _eject_cog(self):
def _eject_cog(self) -> None:
if self.cog is None:
return
@ -298,7 +336,11 @@ class HelpCommand:
MENTION_PATTERN = re.compile('|'.join(MENTION_TRANSFORMS.keys()))
def __new__(cls, *args, **kwargs):
if TYPE_CHECKING:
__original_kwargs__: Dict[str, Any]
__original_args__: Tuple[Any, ...]
def __new__(cls, *args: Any, **kwargs: Any) -> Self:
# To prevent race conditions of a single instance while also allowing
# for settings to be passed the original arguments passed must be assigned
# to allow for easier copies (which will be made when the help command is actually called)
@ -314,30 +356,31 @@ class HelpCommand:
self.__original_args__ = deepcopy(args)
return self
def __init__(self, **options):
self.show_hidden = options.pop('show_hidden', False)
self.verify_checks = options.pop('verify_checks', True)
def __init__(self, **options: Any) -> 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')
self.context: Context = MISSING
self.context: Context[_Bot] = MISSING
self._command_impl = _HelpCommandImpl(self, **self.command_attrs)
def copy(self):
def copy(self) -> Self:
obj = self.__class__(*self.__original_args__, **self.__original_kwargs__)
obj._command_impl = self._command_impl
return obj
def _add_to_bot(self, bot):
def _add_to_bot(self, bot: BotBase) -> None:
command = _HelpCommandImpl(self, **self.command_attrs)
bot.add_command(command)
self._command_impl = command
def _remove_from_bot(self, bot):
def _remove_from_bot(self, bot: BotBase) -> None:
bot.remove_command(self._command_impl.name)
self._command_impl._eject_cog()
def add_check(self, func, /):
def add_check(self, func: Check[ContextT], /) -> None:
"""
Adds a check to the help command.
@ -355,7 +398,7 @@ class HelpCommand:
self._command_impl.add_check(func)
def remove_check(self, func, /):
def remove_check(self, func: Check[ContextT], /) -> None:
"""
Removes a check from the help command.
@ -376,15 +419,15 @@ class HelpCommand:
self._command_impl.remove_check(func)
def get_bot_mapping(self):
def get_bot_mapping(self) -> Dict[Optional[Cog], List[Command[Any, ..., Any]]]:
"""Retrieves the bot mapping passed to :meth:`send_bot_help`."""
bot = self.context.bot
mapping = {cog: cog.get_commands() for cog in bot.cogs.values()}
mapping: Dict[Optional[Cog], List[Command[Any, ..., Any]]] = {cog: cog.get_commands() for cog in bot.cogs.values()}
mapping[None] = [c for c in bot.commands if c.cog is None]
return mapping
@property
def invoked_with(self):
def invoked_with(self) -> Optional[str]:
"""Similar to :attr:`Context.invoked_with` except properly handles
the case where :meth:`Context.send_help` is used.
@ -395,7 +438,7 @@ class HelpCommand:
Returns
---------
:class:`str`
Optional[:class:`str`]
The command name that triggered this invocation.
"""
command_name = self._command_impl.name
@ -404,7 +447,7 @@ class HelpCommand:
return command_name
return ctx.invoked_with
def get_command_signature(self, command):
def get_command_signature(self, command: Command[Any, ..., Any]) -> str:
"""Retrieves the signature portion of the help page.
Parameters
@ -418,14 +461,14 @@ class HelpCommand:
The signature for the command.
"""
parent = command.parent
parent: Optional[Group[Any, ..., Any]] = command.parent # type: ignore - the parent will be a Group
entries = []
while parent is not None:
if not parent.signature or parent.invoke_without_command:
entries.append(parent.name)
else:
entries.append(parent.name + ' ' + parent.signature)
parent = parent.parent
parent = parent.parent # type: ignore
parent_sig = ' '.join(reversed(entries))
if len(command.aliases) > 0:
@ -439,7 +482,7 @@ class HelpCommand:
return f'{self.context.clean_prefix}{alias} {command.signature}'
def remove_mentions(self, string):
def remove_mentions(self, string: str) -> str:
"""Removes mentions from the string to prevent abuse.
This includes ``@everyone``, ``@here``, member mentions and role mentions.
@ -450,13 +493,13 @@ class HelpCommand:
The string with mentions removed.
"""
def replace(obj, *, transforms=self.MENTION_TRANSFORMS):
def replace(obj: re.Match, *, transforms: Dict[str, str] = self.MENTION_TRANSFORMS) -> str:
return transforms.get(obj.group(0), '@invalid')
return self.MENTION_PATTERN.sub(replace, string)
@property
def cog(self):
def cog(self) -> Optional[Cog]:
"""A property for retrieving or setting the cog for the help command.
When a cog is set for the help command, it is as-if the help command
@ -473,7 +516,7 @@ class HelpCommand:
return self._command_impl.cog
@cog.setter
def cog(self, cog):
def cog(self, cog: Optional[Cog]) -> None:
# Remove whatever cog is currently valid, if any
self._command_impl._eject_cog()
@ -481,7 +524,7 @@ class HelpCommand:
if cog is not None:
self._command_impl._inject_into_cog(cog)
def command_not_found(self, string):
def command_not_found(self, string: str) -> str:
"""|maybecoro|
A method called when a command is not found in the help command.
@ -502,7 +545,7 @@ class HelpCommand:
"""
return f'No command called "{string}" found.'
def subcommand_not_found(self, command, string):
def subcommand_not_found(self, command: Command[Any, ..., Any], string: str) -> str:
"""|maybecoro|
A method called when a command did not have a subcommand requested in the help command.
@ -532,7 +575,13 @@ class HelpCommand:
return f'Command "{command.qualified_name}" has no subcommand named {string}'
return f'Command "{command.qualified_name}" has no subcommands.'
async def filter_commands(self, commands, *, sort=False, key=None):
async def filter_commands(
self,
commands: Iterable[Command[Any, ..., Any]],
*,
sort: bool = False,
key: Optional[Callable[[Command[Any, ..., Any]], Any]] = None,
) -> List[Command[Any, ..., Any]]:
"""|coro|
Returns a filtered list of commands and optionally sorts them.
@ -546,7 +595,7 @@ class HelpCommand:
An iterable of commands that are getting filtered.
sort: :class:`bool`
Whether to sort the result.
key: Optional[Callable[:class:`Command`, Any]]
key: Optional[Callable[[:class:`Command`], Any]]
An optional key function to pass to :func:`py:sorted` that
takes a :class:`Command` as its sole parameter. If ``sort`` is
passed as ``True`` then this will default as the command name.
@ -565,14 +614,14 @@ class HelpCommand:
if self.verify_checks is False:
# if we do not need to verify the checks then we can just
# run it straight through normally without using await.
return sorted(iterator, key=key) if sort else list(iterator)
return sorted(iterator, key=key) if sort else list(iterator) # type: ignore - the key shouldn't be None
if self.verify_checks is None and not self.context.guild:
# if verify_checks is None and we're in a DM, don't verify
return sorted(iterator, key=key) if sort else list(iterator)
return sorted(iterator, key=key) if sort else list(iterator) # type: ignore
# if we're here then we need to check every command if it can run
async def predicate(cmd):
async def predicate(cmd: Command[Any, ..., Any]) -> bool:
try:
return await cmd.can_run(self.context)
except CommandError:
@ -588,7 +637,7 @@ class HelpCommand:
ret.sort(key=key)
return ret
def get_max_size(self, commands):
def get_max_size(self, commands: Sequence[Command[Any, ..., Any]]) -> int:
"""Returns the largest name length of the specified command list.
Parameters
@ -605,7 +654,7 @@ class HelpCommand:
as_lengths = (discord.utils._string_width(c.name) for c in commands)
return max(as_lengths, default=0)
def get_destination(self):
def get_destination(self) -> discord.abc.MessageableChannel:
"""Returns the :class:`~discord.abc.Messageable` where the help command will be output.
You can override this method to customise the behaviour.
@ -619,7 +668,7 @@ class HelpCommand:
"""
return self.context.channel
async def send_error_message(self, error):
async def send_error_message(self, error: str) -> None:
"""|coro|
Handles the implementation when an error happens in the help command.
@ -644,7 +693,7 @@ class HelpCommand:
await destination.send(error)
@_not_overridden
async def on_help_command_error(self, ctx, error):
async def on_help_command_error(self, ctx: Context[BotT], error: CommandError) -> None:
"""|coro|
The help command's error handler, as specified by :ref:`ext_commands_error_handler`.
@ -664,7 +713,7 @@ class HelpCommand:
"""
pass
async def send_bot_help(self, mapping):
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None:
"""|coro|
Handles the implementation of the bot command page in the help command.
@ -693,7 +742,7 @@ class HelpCommand:
"""
return None
async def send_cog_help(self, cog):
async def send_cog_help(self, cog: Cog) -> None:
"""|coro|
Handles the implementation of the cog page in the help command.
@ -721,7 +770,7 @@ class HelpCommand:
"""
return None
async def send_group_help(self, group):
async def send_group_help(self, group: Group[Any, ..., Any]) -> None:
"""|coro|
Handles the implementation of the group page in the help command.
@ -749,7 +798,7 @@ class HelpCommand:
"""
return None
async def send_command_help(self, command):
async def send_command_help(self, command: Command[Any, ..., Any]) -> None:
"""|coro|
Handles the implementation of the single command page in the help command.
@ -787,7 +836,7 @@ class HelpCommand:
"""
return None
async def prepare_help_command(self, ctx, command=None):
async def prepare_help_command(self, ctx: Context[BotT], command: Optional[str] = None) -> None:
"""|coro|
A low level method that can be used to prepare the help command
@ -811,7 +860,7 @@ class HelpCommand:
"""
pass
async def command_callback(self, ctx, *, command=None):
async def command_callback(self, ctx: Context[BotT], *, command: Optional[str] = None) -> None:
"""|coro|
The actual implementation of the help command.
@ -856,7 +905,7 @@ class HelpCommand:
for key in keys[1:]:
try:
found = cmd.all_commands.get(key)
found = cmd.all_commands.get(key) # type: ignore
except AttributeError:
string = await maybe_coro(self.subcommand_not_found, cmd, self.remove_mentions(key))
return await self.send_error_message(string)
@ -908,28 +957,28 @@ class DefaultHelpCommand(HelpCommand):
The paginator used to paginate the help command output.
"""
def __init__(self, **options):
self.width = options.pop('width', 80)
self.indent = options.pop('indent', 2)
self.sort_commands = options.pop('sort_commands', True)
self.dm_help = options.pop('dm_help', False)
self.dm_help_threshold = options.pop('dm_help_threshold', 1000)
self.commands_heading = options.pop('commands_heading', "Commands:")
self.no_category = options.pop('no_category', 'No Category')
self.paginator = options.pop('paginator', None)
def __init__(self, **options: Any) -> 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_threshold: int = options.pop('dm_help_threshold', 1000)
self.commands_heading: str = options.pop('commands_heading', "Commands:")
self.no_category: str = options.pop('no_category', 'No Category')
self.paginator: Paginator = options.pop('paginator', None)
if self.paginator is None:
self.paginator = Paginator()
self.paginator: Paginator = Paginator()
super().__init__(**options)
def shorten_text(self, text):
def shorten_text(self, text: str) -> str:
""":class:`str`: Shortens text to fit into the :attr:`width`."""
if len(text) > self.width:
return text[: self.width - 3].rstrip() + '...'
return text
def get_ending_note(self):
def get_ending_note(self) -> str:
""":class:`str`: Returns help command's ending note. This is mainly useful to override for i18n purposes."""
command_name = self.invoked_with
return (
@ -937,7 +986,9 @@ class DefaultHelpCommand(HelpCommand):
f"You can also type {self.context.clean_prefix}{command_name} category for more info on a category."
)
def add_indented_commands(self, commands, *, heading, max_size=None):
def add_indented_commands(
self, commands: Sequence[Command[Any, ..., Any]], *, heading: str, max_size: Optional[int] = None
) -> None:
"""Indents a list of commands after the specified heading.
The formatting is added to the :attr:`paginator`.
@ -973,13 +1024,13 @@ class DefaultHelpCommand(HelpCommand):
entry = f'{self.indent * " "}{name:<{width}} {command.short_doc}'
self.paginator.add_line(self.shorten_text(entry))
async def send_pages(self):
async def send_pages(self) -> None:
"""A helper utility to send the page output from :attr:`paginator` to the destination."""
destination = self.get_destination()
for page in self.paginator.pages:
await destination.send(page)
def add_command_formatting(self, command):
def add_command_formatting(self, command: Command[Any, ..., Any]) -> None:
"""A utility function to format the non-indented block of commands and groups.
Parameters
@ -1002,7 +1053,7 @@ class DefaultHelpCommand(HelpCommand):
self.paginator.add_line(line)
self.paginator.add_line()
def get_destination(self):
def get_destination(self) -> discord.abc.Messageable:
ctx = self.context
if self.dm_help is True:
return ctx.author
@ -1011,11 +1062,11 @@ class DefaultHelpCommand(HelpCommand):
else:
return ctx.channel
async def prepare_help_command(self, ctx, command):
async def prepare_help_command(self, ctx: Context[BotT], command: str) -> None:
self.paginator.clear()
await super().prepare_help_command(ctx, command)
async def send_bot_help(self, mapping):
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None:
ctx = self.context
bot = ctx.bot
@ -1045,12 +1096,12 @@ class DefaultHelpCommand(HelpCommand):
await self.send_pages()
async def send_command_help(self, command):
async def send_command_help(self, command: Command[Any, ..., Any]) -> None:
self.add_command_formatting(command)
self.paginator.close_page()
await self.send_pages()
async def send_group_help(self, group):
async def send_group_help(self, group: Group[Any, ..., Any]) -> None:
self.add_command_formatting(group)
filtered = await self.filter_commands(group.commands, sort=self.sort_commands)
@ -1064,7 +1115,7 @@ class DefaultHelpCommand(HelpCommand):
await self.send_pages()
async def send_cog_help(self, cog):
async def send_cog_help(self, cog: Cog) -> None:
if cog.description:
self.paginator.add_line(cog.description, empty=True)
@ -1111,27 +1162,27 @@ class MinimalHelpCommand(HelpCommand):
The paginator used to paginate the help command output.
"""
def __init__(self, **options):
self.sort_commands = options.pop('sort_commands', True)
self.commands_heading = options.pop('commands_heading', "Commands")
self.dm_help = options.pop('dm_help', False)
self.dm_help_threshold = options.pop('dm_help_threshold', 1000)
self.aliases_heading = options.pop('aliases_heading', "Aliases:")
self.no_category = options.pop('no_category', 'No Category')
self.paginator = options.pop('paginator', None)
def __init__(self, **options: Any) -> 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:
self.paginator = Paginator(suffix=None, prefix=None)
self.paginator: Paginator = Paginator(suffix=None, prefix=None)
super().__init__(**options)
async def send_pages(self):
async def send_pages(self) -> None:
"""A helper utility to send the page output from :attr:`paginator` to the destination."""
destination = self.get_destination()
for page in self.paginator.pages:
await destination.send(page)
def get_opening_note(self):
def get_opening_note(self) -> str:
"""Returns help command's opening note. This is mainly useful to override for i18n purposes.
The default implementation returns ::
@ -1150,10 +1201,10 @@ class MinimalHelpCommand(HelpCommand):
f"You can also use `{self.context.clean_prefix}{command_name} [category]` for more info on a category."
)
def get_command_signature(self, command):
def get_command_signature(self, command: Command[Any, ..., Any]) -> str:
return f'{self.context.clean_prefix}{command.qualified_name} {command.signature}'
def get_ending_note(self):
def get_ending_note(self) -> str:
"""Return the help command's ending note. This is mainly useful to override for i18n purposes.
The default implementation does nothing.
@ -1163,9 +1214,9 @@ class MinimalHelpCommand(HelpCommand):
:class:`str`
The help command ending note.
"""
return None
return ''
def add_bot_commands_formatting(self, commands, heading):
def add_bot_commands_formatting(self, commands: Sequence[Command[Any, ..., Any]], heading: str) -> None:
"""Adds the minified bot heading with commands to the output.
The formatting should be added to the :attr:`paginator`.
@ -1186,7 +1237,7 @@ class MinimalHelpCommand(HelpCommand):
self.paginator.add_line(f'__**{heading}**__')
self.paginator.add_line(joined)
def add_subcommand_formatting(self, command):
def add_subcommand_formatting(self, command: Command[Any, ..., Any]) -> None:
"""Adds formatting information on a subcommand.
The formatting should be added to the :attr:`paginator`.
@ -1202,7 +1253,7 @@ class MinimalHelpCommand(HelpCommand):
fmt = '{0}{1} \N{EN DASH} {2}' if command.short_doc else '{0}{1}'
self.paginator.add_line(fmt.format(self.context.clean_prefix, command.qualified_name, command.short_doc))
def add_aliases_formatting(self, aliases):
def add_aliases_formatting(self, aliases: Sequence[str]) -> None:
"""Adds the formatting information on a command's aliases.
The formatting should be added to the :attr:`paginator`.
@ -1219,7 +1270,7 @@ class MinimalHelpCommand(HelpCommand):
"""
self.paginator.add_line(f'**{self.aliases_heading}** {", ".join(aliases)}', empty=True)
def add_command_formatting(self, command):
def add_command_formatting(self, command: Command[Any, ..., Any]) -> None:
"""A utility function to format commands and groups.
Parameters
@ -1246,7 +1297,7 @@ class MinimalHelpCommand(HelpCommand):
self.paginator.add_line(line)
self.paginator.add_line()
def get_destination(self):
def get_destination(self) -> discord.abc.Messageable:
ctx = self.context
if self.dm_help is True:
return ctx.author
@ -1255,11 +1306,11 @@ class MinimalHelpCommand(HelpCommand):
else:
return ctx.channel
async def prepare_help_command(self, ctx, command):
async def prepare_help_command(self, ctx: Context[BotT], command: str) -> None:
self.paginator.clear()
await super().prepare_help_command(ctx, command)
async def send_bot_help(self, mapping):
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None:
ctx = self.context
bot = ctx.bot
@ -1272,7 +1323,7 @@ class MinimalHelpCommand(HelpCommand):
no_category = f'\u200b{self.no_category}'
def get_category(command, *, no_category=no_category):
def get_category(command: Command[Any, ..., Any], *, no_category: str = no_category) -> str:
cog = command.cog
return cog.qualified_name if cog is not None else no_category
@ -1290,7 +1341,7 @@ class MinimalHelpCommand(HelpCommand):
await self.send_pages()
async def send_cog_help(self, cog):
async def send_cog_help(self, cog: Cog) -> None:
bot = self.context.bot
if bot.description:
self.paginator.add_line(bot.description, empty=True)
@ -1315,7 +1366,7 @@ class MinimalHelpCommand(HelpCommand):
await self.send_pages()
async def send_group_help(self, group):
async def send_group_help(self, group: Group[Any, ..., Any]) -> None:
self.add_command_formatting(group)
filtered = await self.filter_commands(group.commands, sort=self.sort_commands)
@ -1335,7 +1386,7 @@ class MinimalHelpCommand(HelpCommand):
await self.send_pages()
async def send_command_help(self, command):
async def send_command_help(self, command: Command[Any, ..., Any]) -> None:
self.add_command_formatting(command)
self.paginator.close_page()
await self.send_pages()