Browse Source

Change some methods to use positional-only marker

Co-authored-by: Danny <[email protected]>
pull/7750/head
Bryan Forbes 3 years ago
committed by GitHub
parent
commit
062f4d6f87
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      discord/client.py
  2. 84
      discord/ext/commands/bot.py
  3. 104
      discord/ext/commands/core.py
  4. 158
      discord/ext/commands/help.py
  5. 83
      docs/migrating.rst

19
discord/client.py

@ -390,7 +390,7 @@ class Client:
# Schedules the task # Schedules the task
return self.loop.create_task(wrapped, name=f'discord.py: {event_name}') return self.loop.create_task(wrapped, name=f'discord.py: {event_name}')
def dispatch(self, event: str, *args: Any, **kwargs: Any) -> None: def dispatch(self, event: str, /, *args: Any, **kwargs: Any) -> None:
_log.debug('Dispatching event %s', event) _log.debug('Dispatching event %s', event)
method = 'on_' + event method = 'on_' + event
@ -430,7 +430,7 @@ class Client:
else: else:
self._schedule_event(coro, method, *args, **kwargs) self._schedule_event(coro, method, *args, **kwargs)
async def on_error(self, event_method: str, *args: Any, **kwargs: Any) -> None: async def on_error(self, event_method: str, /, *args: Any, **kwargs: Any) -> None:
"""|coro| """|coro|
The default error handler provided by the client. The default error handler provided by the client.
@ -438,6 +438,10 @@ class Client:
By default this prints to :data:`sys.stderr` however it could be By default this prints to :data:`sys.stderr` however it could be
overridden to have a different implementation. overridden to have a different implementation.
Check :func:`~discord.on_error` for more details. Check :func:`~discord.on_error` for more details.
.. versionchanged:: 2.0
``event_method`` parameter is now positional-only.
""" """
print(f'Ignoring exception in {event_method}', file=sys.stderr) print(f'Ignoring exception in {event_method}', file=sys.stderr)
traceback.print_exc() traceback.print_exc()
@ -977,6 +981,7 @@ class Client:
def wait_for( def wait_for(
self, self,
event: str, event: str,
/,
*, *,
check: Optional[Callable[..., bool]] = None, check: Optional[Callable[..., bool]] = None,
timeout: Optional[float] = None, timeout: Optional[float] = None,
@ -1036,6 +1041,10 @@ class Client:
else: else:
await channel.send('\N{THUMBS UP SIGN}') await channel.send('\N{THUMBS UP SIGN}')
.. versionchanged:: 2.0
``event`` parameter is now positional-only.
Parameters Parameters
------------ ------------
@ -1082,7 +1091,7 @@ class Client:
# event registration # event registration
def event(self, coro: Coro) -> Coro: def event(self, coro: Coro, /) -> Coro:
"""A decorator that registers an event to listen to. """A decorator that registers an event to listen to.
You can find more info about the events on the :ref:`documentation below <discord-api-events>`. You can find more info about the events on the :ref:`documentation below <discord-api-events>`.
@ -1098,6 +1107,10 @@ class Client:
async def on_ready(): async def on_ready():
print('Ready!') print('Ready!')
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Raises Raises
-------- --------
TypeError TypeError

84
discord/ext/commands/bot.py

@ -92,10 +92,14 @@ T = TypeVar('T')
CFT = TypeVar('CFT', bound='CoroFunc') CFT = TypeVar('CFT', bound='CoroFunc')
def when_mentioned(bot: _Bot, msg: Message) -> List[str]: def when_mentioned(bot: _Bot, msg: Message, /) -> List[str]:
"""A callable that implements a command prefix equivalent to being mentioned. """A callable that implements a command prefix equivalent to being mentioned.
These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. These are meant to be passed into the :attr:`.Bot.command_prefix` attribute.
.. versionchanged:: 2.0
``bot`` and ``msg`` parameters are now positional-only.
""" """
# bot.user will never be None when this is called # bot.user will never be None when this is called
return [f'<@{bot.user.id}> ', f'<@!{bot.user.id}> '] # type: ignore return [f'<@{bot.user.id}> ', f'<@!{bot.user.id}> '] # type: ignore
@ -185,7 +189,7 @@ class BotBase(GroupMixin[None]):
# internal helpers # internal helpers
def dispatch(self, event_name: str, *args: Any, **kwargs: Any) -> None: def dispatch(self, event_name: str, /, *args: Any, **kwargs: Any) -> None:
# super() will resolve to Client # super() will resolve to Client
super().dispatch(event_name, *args, **kwargs) # type: ignore super().dispatch(event_name, *args, **kwargs) # type: ignore
ev = 'on_' + event_name ev = 'on_' + event_name
@ -208,7 +212,7 @@ class BotBase(GroupMixin[None]):
await super().close() # type: ignore await super().close() # type: ignore
async def on_command_error(self, context: Context[BotT], exception: errors.CommandError) -> None: async def on_command_error(self, context: Context[BotT], exception: errors.CommandError, /) -> None:
"""|coro| """|coro|
The default command error handler provided by the bot. The default command error handler provided by the bot.
@ -217,6 +221,10 @@ class BotBase(GroupMixin[None]):
overridden to have a different implementation. overridden to have a different implementation.
This only fires if you do not specify any listeners for command error. This only fires if you do not specify any listeners for command error.
.. versionchanged:: 2.0
``context`` and ``exception`` parameters are now positional-only.
""" """
if self.extra_events.get('on_command_error', None): if self.extra_events.get('on_command_error', None):
return return
@ -234,7 +242,7 @@ class BotBase(GroupMixin[None]):
# global check registration # global check registration
def check(self, func: T) -> T: def check(self, func: T, /) -> T:
r"""A decorator that adds a global check to the bot. r"""A decorator that adds a global check to the bot.
A global check is similar to a :func:`.check` that is applied A global check is similar to a :func:`.check` that is applied
@ -258,6 +266,9 @@ class BotBase(GroupMixin[None]):
def check_commands(ctx): def check_commands(ctx):
return ctx.command.qualified_name in allowed_commands return ctx.command.qualified_name in allowed_commands
.. versionchanged:: 2.0
``func`` parameter is now positional-only.
""" """
# T was used instead of Check to ensure the type matches on return # T was used instead of Check to ensure the type matches on return
self.add_check(func) # type: ignore self.add_check(func) # type: ignore
@ -312,7 +323,7 @@ class BotBase(GroupMixin[None]):
except ValueError: except ValueError:
pass pass
def check_once(self, func: CFT) -> CFT: def check_once(self, func: CFT, /) -> CFT:
r"""A decorator that adds a "call once" global check to the bot. r"""A decorator that adds a "call once" global check to the bot.
Unlike regular global checks, this one is called only once Unlike regular global checks, this one is called only once
@ -346,11 +357,15 @@ class BotBase(GroupMixin[None]):
def whitelist(ctx): def whitelist(ctx):
return ctx.message.author.id in my_whitelist return ctx.message.author.id in my_whitelist
.. versionchanged:: 2.0
``func`` parameter is now positional-only.
""" """
self.add_check(func, call_once=True) self.add_check(func, call_once=True)
return func return func
async def can_run(self, ctx: Context[BotT], *, call_once: bool = False) -> bool: async def can_run(self, ctx: Context[BotT], /, *, call_once: bool = False) -> bool:
data = self._check_once if call_once else self._checks data = self._check_once if call_once else self._checks
if len(data) == 0: if len(data) == 0:
@ -359,7 +374,7 @@ class BotBase(GroupMixin[None]):
# type-checker doesn't distinguish between functions and methods # type-checker doesn't distinguish between functions and methods
return await discord.utils.async_all(f(ctx) for f in data) # type: ignore return await discord.utils.async_all(f(ctx) for f in data) # type: ignore
async def is_owner(self, user: User) -> bool: async def is_owner(self, user: User, /) -> bool:
"""|coro| """|coro|
Checks if a :class:`~discord.User` or :class:`~discord.Member` is the owner of Checks if a :class:`~discord.User` or :class:`~discord.Member` is the owner of
@ -372,6 +387,10 @@ class BotBase(GroupMixin[None]):
The function also checks if the application is team-owned if The function also checks if the application is team-owned if
:attr:`owner_ids` is not set. :attr:`owner_ids` is not set.
.. versionchanged:: 2.0
``user`` parameter is now positional-only.
Parameters Parameters
----------- -----------
user: :class:`.abc.User` user: :class:`.abc.User`
@ -397,7 +416,7 @@ class BotBase(GroupMixin[None]):
self.owner_id = owner_id = app.owner.id self.owner_id = owner_id = app.owner.id
return user.id == owner_id return user.id == owner_id
def before_invoke(self, coro: CFT) -> CFT: def before_invoke(self, coro: CFT, /) -> CFT:
"""A decorator that registers a coroutine as a pre-invoke hook. """A decorator that registers a coroutine as a pre-invoke hook.
A pre-invoke hook is called directly before the command is A pre-invoke hook is called directly before the command is
@ -413,6 +432,10 @@ class BotBase(GroupMixin[None]):
without error. If any check or argument parsing procedures fail without error. If any check or argument parsing procedures fail
then the hooks are not called. then the hooks are not called.
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Parameters Parameters
----------- -----------
coro: :ref:`coroutine <coroutine>` coro: :ref:`coroutine <coroutine>`
@ -429,7 +452,7 @@ class BotBase(GroupMixin[None]):
self._before_invoke = coro self._before_invoke = coro
return coro return coro
def after_invoke(self, coro: CFT) -> CFT: def after_invoke(self, coro: CFT, /) -> CFT:
r"""A decorator that registers a coroutine as a post-invoke hook. r"""A decorator that registers a coroutine as a post-invoke hook.
A post-invoke hook is called directly after the command is A post-invoke hook is called directly after the command is
@ -446,6 +469,10 @@ class BotBase(GroupMixin[None]):
callback raising an error (i.e. :exc:`.CommandInvokeError`\). callback raising an error (i.e. :exc:`.CommandInvokeError`\).
This makes it ideal for clean-up scenarios. This makes it ideal for clean-up scenarios.
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Parameters Parameters
----------- -----------
coro: :ref:`coroutine <coroutine>` coro: :ref:`coroutine <coroutine>`
@ -464,9 +491,13 @@ class BotBase(GroupMixin[None]):
# listener registration # listener registration
def add_listener(self, func: CoroFunc, name: str = MISSING) -> None: def add_listener(self, func: CoroFunc, /, name: str = MISSING) -> None:
"""The non decorator alternative to :meth:`.listen`. """The non decorator alternative to :meth:`.listen`.
.. versionchanged:: 2.0
``func`` parameter is now positional-only.
Parameters Parameters
----------- -----------
func: :ref:`coroutine <coroutine>` func: :ref:`coroutine <coroutine>`
@ -496,9 +527,13 @@ class BotBase(GroupMixin[None]):
else: else:
self.extra_events[name] = [func] self.extra_events[name] = [func]
def remove_listener(self, func: CoroFunc, name: str = MISSING) -> None: def remove_listener(self, func: CoroFunc, /, name: str = MISSING) -> None:
"""Removes a listener from the pool of listeners. """Removes a listener from the pool of listeners.
.. versionchanged:: 2.0
``func`` parameter is now positional-only.
Parameters Parameters
----------- -----------
func func
@ -1023,12 +1058,16 @@ class BotBase(GroupMixin[None]):
# command processing # command processing
async def get_prefix(self, message: Message) -> Union[List[str], str]: async def get_prefix(self, message: Message, /) -> Union[List[str], str]:
"""|coro| """|coro|
Retrieves the prefix the bot is listening to Retrieves the prefix the bot is listening to
with the message as a context. with the message as a context.
.. versionchanged:: 2.0
``message`` parameter is now positional-only.
Parameters Parameters
----------- -----------
message: :class:`discord.Message` message: :class:`discord.Message`
@ -1068,6 +1107,7 @@ class BotBase(GroupMixin[None]):
async def get_context( async def get_context(
self, self,
message: Message, message: Message,
/,
) -> Context[Self]: # type: ignore ) -> Context[Self]: # type: ignore
... ...
@ -1075,6 +1115,7 @@ class BotBase(GroupMixin[None]):
async def get_context( async def get_context(
self, self,
message: Message, message: Message,
/,
*, *,
cls: Type[ContextT] = ..., cls: Type[ContextT] = ...,
) -> ContextT: ) -> ContextT:
@ -1083,6 +1124,7 @@ class BotBase(GroupMixin[None]):
async def get_context( async def get_context(
self, self,
message: Message, message: Message,
/,
*, *,
cls: Type[ContextT] = MISSING, cls: Type[ContextT] = MISSING,
) -> Any: ) -> Any:
@ -1098,6 +1140,10 @@ class BotBase(GroupMixin[None]):
If the context is not valid then it is not a valid candidate to be If the context is not valid then it is not a valid candidate to be
invoked under :meth:`~.Bot.invoke`. invoked under :meth:`~.Bot.invoke`.
.. versionchanged:: 2.0
``message`` parameter is now positional-only.
Parameters Parameters
----------- -----------
message: :class:`discord.Message` message: :class:`discord.Message`
@ -1165,12 +1211,16 @@ class BotBase(GroupMixin[None]):
ctx.command = self.all_commands.get(invoker) ctx.command = self.all_commands.get(invoker)
return ctx return ctx
async def invoke(self, ctx: Context[BotT]) -> None: async def invoke(self, ctx: Context[BotT], /) -> None:
"""|coro| """|coro|
Invokes the command given under the invocation context and Invokes the command given under the invocation context and
handles all the internal event dispatch mechanisms. handles all the internal event dispatch mechanisms.
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`.Context` ctx: :class:`.Context`
@ -1191,7 +1241,7 @@ class BotBase(GroupMixin[None]):
exc = errors.CommandNotFound(f'Command "{ctx.invoked_with}" is not found') exc = errors.CommandNotFound(f'Command "{ctx.invoked_with}" is not found')
self.dispatch('command_error', ctx, exc) self.dispatch('command_error', ctx, exc)
async def process_commands(self, message: Message) -> None: async def process_commands(self, message: Message, /) -> None:
"""|coro| """|coro|
This function processes the commands that have been registered This function processes the commands that have been registered
@ -1208,6 +1258,10 @@ class BotBase(GroupMixin[None]):
This also checks if the message's author is a bot and doesn't This also checks if the message's author is a bot and doesn't
call :meth:`~.Bot.get_context` or :meth:`~.Bot.invoke` if so. call :meth:`~.Bot.get_context` or :meth:`~.Bot.invoke` if so.
.. versionchanged:: 2.0
``message`` parameter is now positional-only.
Parameters Parameters
----------- -----------
message: :class:`discord.Message` message: :class:`discord.Message`
@ -1220,7 +1274,7 @@ class BotBase(GroupMixin[None]):
# the type of the invocation context's bot attribute will be correct # the type of the invocation context's bot attribute will be correct
await self.invoke(ctx) # type: ignore await self.invoke(ctx) # type: ignore
async def on_message(self, message: Message) -> None: async def on_message(self, message: Message, /) -> None:
await self.process_commands(message) await self.process_commands(message)

104
discord/ext/commands/core.py

@ -114,7 +114,7 @@ else:
P = TypeVar('P') P = TypeVar('P')
def unwrap_function(function: Callable[..., Any]) -> Callable[..., Any]: def unwrap_function(function: Callable[..., Any], /) -> Callable[..., Any]:
partial = functools.partial partial = functools.partial
while True: while True:
if hasattr(function, '__wrapped__'): if hasattr(function, '__wrapped__'):
@ -128,6 +128,7 @@ def unwrap_function(function: Callable[..., Any]) -> Callable[..., Any]:
def get_signature_parameters( def get_signature_parameters(
function: Callable[..., Any], function: Callable[..., Any],
globalns: Dict[str, Any], globalns: Dict[str, Any],
/,
*, *,
skip_parameters: Optional[int] = None, skip_parameters: Optional[int] = None,
) -> Dict[str, inspect.Parameter]: ) -> Dict[str, inspect.Parameter]:
@ -161,7 +162,7 @@ def get_signature_parameters(
return params return params
def wrap_callback(coro: Callable[P, Coro[T]]) -> Callable[P, Coro[Optional[T]]]: def wrap_callback(coro: Callable[P, Coro[T]], /) -> Callable[P, Coro[Optional[T]]]:
@functools.wraps(coro) @functools.wraps(coro)
async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]: async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]:
try: try:
@ -178,7 +179,7 @@ def wrap_callback(coro: Callable[P, Coro[T]]) -> Callable[P, Coro[Optional[T]]]:
def hooked_wrapped_callback( def hooked_wrapped_callback(
command: Command[Any, ..., Any], ctx: Context[BotT], coro: Callable[P, Coro[T]] command: Command[Any, ..., Any], ctx: Context[BotT], coro: Callable[P, Coro[T]], /
) -> Callable[P, Coro[Optional[T]]]: ) -> Callable[P, Coro[Optional[T]]]:
@functools.wraps(coro) @functools.wraps(coro)
async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]: async def wrapped(*args: P.args, **kwargs: P.kwargs) -> Optional[T]:
@ -322,6 +323,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
Callable[Concatenate[CogT, ContextT, P], Coro[T]], Callable[Concatenate[CogT, ContextT, P], Coro[T]],
Callable[Concatenate[ContextT, P], Coro[T]], Callable[Concatenate[ContextT, P], Coro[T]],
], ],
/,
**kwargs: Any, **kwargs: Any,
) -> None: ) -> None:
if not asyncio.iscoroutinefunction(func): if not asyncio.iscoroutinefunction(func):
@ -488,7 +490,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
self.__init__(self.callback, **dict(self.__original_kwargs__, **kwargs)) self.__init__(self.callback, **dict(self.__original_kwargs__, **kwargs))
self.cog = cog self.cog = cog
async def __call__(self, context: Context[BotT], *args: P.args, **kwargs: P.kwargs) -> T: async def __call__(self, context: Context[BotT], /, *args: P.args, **kwargs: P.kwargs) -> T:
"""|coro| """|coro|
Calls the internal callback that the command holds. Calls the internal callback that the command holds.
@ -500,6 +502,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
the proper arguments and types to this function. the proper arguments and types to this function.
.. versionadded:: 1.3 .. versionadded:: 1.3
.. versionchanged:: 2.0
``context`` parameter is now positional-only.
""" """
if self.cog is not None: if self.cog is not None:
return await self.callback(self.cog, context, *args, **kwargs) # type: ignore return await self.callback(self.cog, context, *args, **kwargs) # type: ignore
@ -543,7 +549,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
else: else:
return self.copy() return self.copy()
async def dispatch_error(self, ctx: Context[BotT], error: CommandError) -> None: async def dispatch_error(self, ctx: Context[BotT], error: CommandError, /) -> None:
ctx.command_failed = True ctx.command_failed = True
cog = self.cog cog = self.cog
try: try:
@ -566,7 +572,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
finally: finally:
ctx.bot.dispatch('command_error', ctx, error) ctx.bot.dispatch('command_error', ctx, error)
async def transform(self, ctx: Context[BotT], param: inspect.Parameter) -> Any: async def transform(self, ctx: Context[BotT], param: inspect.Parameter, /) -> Any:
required = param.default is param.empty required = param.default is param.empty
converter = get_converter(param) converter = get_converter(param)
consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw
@ -758,7 +764,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
if not self.ignore_extra and not view.eof: if not self.ignore_extra and not view.eof:
raise TooManyArguments('Too many arguments passed to ' + self.qualified_name) raise TooManyArguments('Too many arguments passed to ' + self.qualified_name)
async def call_before_hooks(self, ctx: Context[BotT]) -> None: async def call_before_hooks(self, ctx: Context[BotT], /) -> None:
# now that we're done preparing we can call the pre-command hooks # now that we're done preparing we can call the pre-command hooks
# first, call the command local hook: # first, call the command local hook:
cog = self.cog cog = self.cog
@ -783,7 +789,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
if hook is not None: if hook is not None:
await hook(ctx) await hook(ctx)
async def call_after_hooks(self, ctx: Context[BotT]) -> None: async def call_after_hooks(self, ctx: Context[BotT], /) -> None:
cog = self.cog cog = self.cog
if self._after_invoke is not None: if self._after_invoke is not None:
instance = getattr(self._after_invoke, '__self__', cog) instance = getattr(self._after_invoke, '__self__', cog)
@ -812,7 +818,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
if retry_after: if retry_after:
raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # type: ignore raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # type: ignore
async def prepare(self, ctx: Context[BotT]) -> None: async def prepare(self, ctx: Context[BotT], /) -> None:
ctx.command = self ctx.command = self
if not await self.can_run(ctx): if not await self.can_run(ctx):
@ -836,9 +842,13 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
await self._max_concurrency.release(ctx) # type: ignore await self._max_concurrency.release(ctx) # type: ignore
raise raise
def is_on_cooldown(self, ctx: Context[BotT]) -> bool: def is_on_cooldown(self, ctx: Context[BotT], /) -> bool:
"""Checks whether the command is currently on cooldown. """Checks whether the command is currently on cooldown.
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`.Context` ctx: :class:`.Context`
@ -857,9 +867,13 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() current = dt.replace(tzinfo=datetime.timezone.utc).timestamp()
return bucket.get_tokens(current) == 0 return bucket.get_tokens(current) == 0
def reset_cooldown(self, ctx: Context[BotT]) -> None: def reset_cooldown(self, ctx: Context[BotT], /) -> None:
"""Resets the cooldown on this command. """Resets the cooldown on this command.
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`.Context` ctx: :class:`.Context`
@ -869,11 +883,15 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
bucket = self._buckets.get_bucket(ctx.message) bucket = self._buckets.get_bucket(ctx.message)
bucket.reset() bucket.reset()
def get_cooldown_retry_after(self, ctx: Context[BotT]) -> float: def get_cooldown_retry_after(self, ctx: Context[BotT], /) -> float:
"""Retrieves the amount of seconds before this command can be tried again. """Retrieves the amount of seconds before this command can be tried again.
.. versionadded:: 1.4 .. versionadded:: 1.4
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`.Context` ctx: :class:`.Context`
@ -893,7 +911,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
return 0.0 return 0.0
async def invoke(self, ctx: Context[BotT]) -> None: async def invoke(self, ctx: Context[BotT], /) -> None:
await self.prepare(ctx) await self.prepare(ctx)
# terminate the invoked_subcommand chain. # terminate the invoked_subcommand chain.
@ -904,7 +922,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
injected = hooked_wrapped_callback(self, ctx, self.callback) injected = hooked_wrapped_callback(self, ctx, self.callback)
await injected(*ctx.args, **ctx.kwargs) # type: ignore await injected(*ctx.args, **ctx.kwargs) # type: ignore
async def reinvoke(self, ctx: Context[BotT], *, call_hooks: bool = False) -> None: async def reinvoke(self, ctx: Context[BotT], /, *, call_hooks: bool = False) -> None:
ctx.command = self ctx.command = self
await self._parse_arguments(ctx) await self._parse_arguments(ctx)
@ -921,13 +939,17 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
if call_hooks: if call_hooks:
await self.call_after_hooks(ctx) await self.call_after_hooks(ctx)
def error(self, coro: ErrorT) -> ErrorT: def error(self, coro: ErrorT, /) -> ErrorT:
"""A decorator that registers a coroutine as a local error handler. """A decorator that registers a coroutine as a local error handler.
A local error handler is an :func:`.on_command_error` event limited to A local error handler is an :func:`.on_command_error` event limited to
a single command. However, the :func:`.on_command_error` is still a single command. However, the :func:`.on_command_error` is still
invoked afterwards as the catch-all. invoked afterwards as the catch-all.
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Parameters Parameters
----------- -----------
coro: :ref:`coroutine <coroutine>` coro: :ref:`coroutine <coroutine>`
@ -952,7 +974,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
""" """
return hasattr(self, 'on_error') return hasattr(self, 'on_error')
def before_invoke(self, coro: HookT) -> HookT: def before_invoke(self, coro: HookT, /) -> HookT:
"""A decorator that registers a coroutine as a pre-invoke hook. """A decorator that registers a coroutine as a pre-invoke hook.
A pre-invoke hook is called directly before the command is A pre-invoke hook is called directly before the command is
@ -963,6 +985,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
See :meth:`.Bot.before_invoke` for more info. See :meth:`.Bot.before_invoke` for more info.
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Parameters Parameters
----------- -----------
coro: :ref:`coroutine <coroutine>` coro: :ref:`coroutine <coroutine>`
@ -979,7 +1005,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
self._before_invoke = coro self._before_invoke = coro
return coro return coro
def after_invoke(self, coro: HookT) -> HookT: def after_invoke(self, coro: HookT, /) -> HookT:
"""A decorator that registers a coroutine as a post-invoke hook. """A decorator that registers a coroutine as a post-invoke hook.
A post-invoke hook is called directly after the command is A post-invoke hook is called directly after the command is
@ -990,6 +1016,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
See :meth:`.Bot.after_invoke` for more info. See :meth:`.Bot.after_invoke` for more info.
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Parameters Parameters
----------- -----------
coro: :ref:`coroutine <coroutine>` coro: :ref:`coroutine <coroutine>`
@ -1081,7 +1111,7 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
return ' '.join(result) return ' '.join(result)
async def can_run(self, ctx: Context[BotT]) -> bool: async def can_run(self, ctx: Context[BotT], /) -> bool:
"""|coro| """|coro|
Checks if the command can be executed by checking all the predicates Checks if the command can be executed by checking all the predicates
@ -1091,6 +1121,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
.. versionchanged:: 1.3 .. versionchanged:: 1.3
Checks whether the command is disabled or not Checks whether the command is disabled or not
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`.Context` ctx: :class:`.Context`
@ -1469,7 +1503,7 @@ class Group(GroupMixin[CogT], Command[CogT, P, T]):
ret.add_command(cmd.copy()) ret.add_command(cmd.copy())
return ret return ret
async def invoke(self, ctx: Context[BotT]) -> None: async def invoke(self, ctx: Context[BotT], /) -> None:
ctx.invoked_subcommand = None ctx.invoked_subcommand = None
ctx.subcommand_passed = None ctx.subcommand_passed = None
early_invoke = not self.invoke_without_command early_invoke = not self.invoke_without_command
@ -1500,7 +1534,7 @@ class Group(GroupMixin[CogT], Command[CogT, P, T]):
view.previous = previous view.previous = previous
await super().invoke(ctx) await super().invoke(ctx)
async def reinvoke(self, ctx: Context[BotT], *, call_hooks: bool = False) -> None: async def reinvoke(self, ctx: Context[BotT], /, *, call_hooks: bool = False) -> None:
ctx.invoked_subcommand = None ctx.invoked_subcommand = None
early_invoke = not self.invoke_without_command early_invoke = not self.invoke_without_command
if early_invoke: if early_invoke:
@ -1685,7 +1719,7 @@ def group(
return command(name=name, cls=cls, **attrs) return command(name=name, cls=cls, **attrs)
def check(predicate: Check[ContextT]) -> Callable[[T], T]: def check(predicate: Check[ContextT], /) -> Callable[[T], T]:
r"""A decorator that adds a check to the :class:`.Command` or its r"""A decorator that adds a check to the :class:`.Command` or its
subclasses. These checks could be accessed via :attr:`.Command.checks`. subclasses. These checks could be accessed via :attr:`.Command.checks`.
@ -1750,6 +1784,10 @@ def check(predicate: Check[ContextT]) -> Callable[[T], T]:
async def only_me(ctx): async def only_me(ctx):
await ctx.send('Only you!') await ctx.send('Only you!')
.. versionchanged:: 2.0
``predicate`` parameter is now positional-only.
Parameters Parameters
----------- -----------
predicate: Callable[[:class:`Context`], :class:`bool`] predicate: Callable[[:class:`Context`], :class:`bool`]
@ -1849,7 +1887,7 @@ def check_any(*checks: Check[ContextT]) -> Callable[[T], T]:
return check(predicate) return check(predicate)
def has_role(item: Union[int, str]) -> Callable[[T], T]: def has_role(item: Union[int, str], /) -> Callable[[T], T]:
"""A :func:`.check` that is added that checks if the member invoking the """A :func:`.check` that is added that checks if the member invoking the
command has the role specified via the name or ID specified. command has the role specified via the name or ID specified.
@ -1870,6 +1908,10 @@ def has_role(item: Union[int, str]) -> Callable[[T], T]:
Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage` Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage`
instead of generic :exc:`.CheckFailure` instead of generic :exc:`.CheckFailure`
.. versionchanged:: 2.0
``item`` parameter is now positional-only.
Parameters Parameters
----------- -----------
item: Union[:class:`int`, :class:`str`] item: Union[:class:`int`, :class:`str`]
@ -1937,7 +1979,7 @@ def has_any_role(*items: Union[int, str]) -> Callable[[T], T]:
return check(predicate) return check(predicate)
def bot_has_role(item: int) -> Callable[[T], T]: def bot_has_role(item: int, /) -> Callable[[T], T]:
"""Similar to :func:`.has_role` except checks if the bot itself has the """Similar to :func:`.has_role` except checks if the bot itself has the
role. role.
@ -1949,6 +1991,10 @@ def bot_has_role(item: int) -> Callable[[T], T]:
Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage` Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage`
instead of generic :exc:`.CheckFailure` instead of generic :exc:`.CheckFailure`
.. versionchanged:: 2.0
``item`` parameter is now positional-only.
""" """
def predicate(ctx): def predicate(ctx):
@ -2320,7 +2366,7 @@ def max_concurrency(number: int, per: BucketType = BucketType.default, *, wait:
return decorator # type: ignore return decorator # type: ignore
def before_invoke(coro: Hook[ContextT]) -> Callable[[T], T]: def before_invoke(coro: Hook[ContextT], /) -> Callable[[T], T]:
"""A decorator that registers a coroutine as a pre-invoke hook. """A decorator that registers a coroutine as a pre-invoke hook.
This allows you to refer to one before invoke hook for several commands that This allows you to refer to one before invoke hook for several commands that
@ -2328,6 +2374,10 @@ def before_invoke(coro: Hook[ContextT]) -> Callable[[T], T]:
.. versionadded:: 1.4 .. versionadded:: 1.4
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
Example Example
--------- ---------
@ -2368,13 +2418,17 @@ def before_invoke(coro: Hook[ContextT]) -> Callable[[T], T]:
return decorator # type: ignore return decorator # type: ignore
def after_invoke(coro: Hook[ContextT]) -> Callable[[T], T]: def after_invoke(coro: Hook[ContextT], /) -> Callable[[T], T]:
"""A decorator that registers a coroutine as a post-invoke hook. """A decorator that registers a coroutine as a post-invoke hook.
This allows you to refer to one after invoke hook for several commands that This allows you to refer to one after invoke hook for several commands that
do not have to be within the same cog. do not have to be within the same cog.
.. versionadded:: 1.4 .. versionadded:: 1.4
.. versionchanged:: 2.0
``coro`` parameter is now positional-only.
""" """
def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]: def decorator(func: Union[Command, CoroFunc]) -> Union[Command, CoroFunc]:

158
discord/ext/commands/help.py

@ -274,7 +274,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
if not hasattr(self.on_help_command_error, '__help_command_not_overridden__'): if not hasattr(self.on_help_command_error, '__help_command_not_overridden__'):
self.on_error = self.on_help_command_error self.on_error = self.on_help_command_error
async def __call__(self, context: ContextT, *args: Any, **kwargs: Any) -> Any: async def __call__(self, context: ContextT, /, *args: Any, **kwargs: Any) -> Any:
return await self._set_context(context, *args, **kwargs) return await self._set_context(context, *args, **kwargs)
async def _set_context(self, context: ContextT, *args: Any, **kwargs: Any) -> Any: async def _set_context(self, context: ContextT, *args: Any, **kwargs: Any) -> Any:
@ -306,13 +306,13 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
async def _parse_arguments(self, ctx: ContextT) -> None: async def _parse_arguments(self, ctx: ContextT) -> None:
return await self._call_without_cog(super()._parse_arguments, ctx) return await self._call_without_cog(super()._parse_arguments, ctx)
async def call_before_hooks(self, ctx: ContextT) -> None: async def call_before_hooks(self, ctx: ContextT, /) -> None:
return await self._call_without_cog(super().call_before_hooks, ctx) return await self._call_without_cog(super().call_before_hooks, ctx)
async def call_after_hooks(self, ctx: ContextT) -> None: async def call_after_hooks(self, ctx: ContextT, /) -> None:
return await self._call_without_cog(super().call_after_hooks, ctx) return await self._call_without_cog(super().call_after_hooks, ctx)
async def can_run(self, ctx: ContextT) -> bool: async def can_run(self, ctx: ContextT, /) -> bool:
return await self._call_without_cog(super().can_run, ctx) return await self._call_without_cog(super().can_run, ctx)
def get_bot_mapping(self) -> Dict[Optional[Cog], List[Command[Any, ..., Any]]]: def get_bot_mapping(self) -> Dict[Optional[Cog], List[Command[Any, ..., Any]]]:
@ -343,9 +343,13 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
return command_name return command_name
return ctx.invoked_with return ctx.invoked_with
def get_command_signature(self, command: Command[Any, ..., Any]) -> str: def get_command_signature(self, command: Command[Any, ..., Any], /) -> str:
"""Retrieves the signature portion of the help page. """Retrieves the signature portion of the help page.
.. versionchanged:: 2.0
``command`` parameter is now positional-only.
Parameters Parameters
------------ ------------
command: :class:`Command` command: :class:`Command`
@ -378,11 +382,15 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
return f'{self.context.clean_prefix}{alias} {command.signature}' return f'{self.context.clean_prefix}{alias} {command.signature}'
def remove_mentions(self, string: str) -> str: def remove_mentions(self, string: str, /) -> str:
"""Removes mentions from the string to prevent abuse. """Removes mentions from the string to prevent abuse.
This includes ``@everyone``, ``@here``, member mentions and role mentions. This includes ``@everyone``, ``@here``, member mentions and role mentions.
.. versionchanged:: 2.0
``string`` parameter is now positional-only.
Returns Returns
------- -------
:class:`str` :class:`str`
@ -450,7 +458,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
if cog is not None: if cog is not None:
self._inject_into_cog(cog) self._inject_into_cog(cog)
def command_not_found(self, string: str) -> str: def command_not_found(self, string: str, /) -> str:
"""|maybecoro| """|maybecoro|
A method called when a command is not found in the help command. A method called when a command is not found in the help command.
@ -458,6 +466,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
Defaults to ``No command called {0} found.`` Defaults to ``No command called {0} found.``
.. versionchanged:: 2.0
``string`` parameter is now positional-only.
Parameters Parameters
------------ ------------
string: :class:`str` string: :class:`str`
@ -471,7 +483,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return f'No command called "{string}" found.' return f'No command called "{string}" found.'
def subcommand_not_found(self, command: Command[Any, ..., Any], string: str) -> str: def subcommand_not_found(self, command: Command[Any, ..., Any], string: str, /) -> str:
"""|maybecoro| """|maybecoro|
A method called when a command did not have a subcommand requested in the help command. A method called when a command did not have a subcommand requested in the help command.
@ -484,6 +496,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
- ``'Command "{command.qualified_name}" has no subcommand named {string}'`` - ``'Command "{command.qualified_name}" has no subcommand named {string}'``
- If the ``command`` parameter has subcommands but not one named ``string``. - If the ``command`` parameter has subcommands but not one named ``string``.
.. versionchanged:: 2.0
``command`` and ``string`` parameters are now positional-only.
Parameters Parameters
------------ ------------
command: :class:`Command` command: :class:`Command`
@ -504,6 +520,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
async def filter_commands( async def filter_commands(
self, self,
commands: Iterable[Command[Any, ..., Any]], commands: Iterable[Command[Any, ..., Any]],
/,
*, *,
sort: bool = False, sort: bool = False,
key: Optional[Callable[[Command[Any, ..., Any]], Any]] = None, key: Optional[Callable[[Command[Any, ..., Any]], Any]] = None,
@ -515,6 +532,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
This takes into account the :attr:`verify_checks` and :attr:`show_hidden` This takes into account the :attr:`verify_checks` and :attr:`show_hidden`
attributes. attributes.
.. versionchanged:: 2.0
``commands`` parameter is now positional-only.
Parameters Parameters
------------ ------------
commands: Iterable[:class:`Command`] commands: Iterable[:class:`Command`]
@ -563,9 +584,13 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
ret.sort(key=key) ret.sort(key=key)
return ret return ret
def get_max_size(self, commands: Sequence[Command[Any, ..., Any]]) -> int: def get_max_size(self, commands: Sequence[Command[Any, ..., Any]], /) -> int:
"""Returns the largest name length of the specified command list. """Returns the largest name length of the specified command list.
.. versionchanged:: 2.0
``commands`` parameter is now positional-only.
Parameters Parameters
------------ ------------
commands: Sequence[:class:`Command`] commands: Sequence[:class:`Command`]
@ -594,7 +619,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return self.context.channel return self.context.channel
async def send_error_message(self, error: str) -> None: async def send_error_message(self, error: str, /) -> None:
"""|coro| """|coro|
Handles the implementation when an error happens in the help command. Handles the implementation when an error happens in the help command.
@ -609,6 +634,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
You can access the invocation context with :attr:`HelpCommand.context`. You can access the invocation context with :attr:`HelpCommand.context`.
.. versionchanged:: 2.0
``error`` parameter is now positional-only.
Parameters Parameters
------------ ------------
error: :class:`str` error: :class:`str`
@ -619,7 +648,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
await destination.send(error) await destination.send(error)
@_not_overridden @_not_overridden
async def on_help_command_error(self, ctx: ContextT, error: CommandError) -> None: async def on_help_command_error(self, ctx: ContextT, error: CommandError, /) -> None:
"""|coro| """|coro|
The help command's error handler, as specified by :ref:`ext_commands_error_handler`. The help command's error handler, as specified by :ref:`ext_commands_error_handler`.
@ -630,6 +659,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
By default this method does nothing and just propagates to the default By default this method does nothing and just propagates to the default
error handlers. error handlers.
.. versionchanged:: 2.0
``ctx`` and ``error`` parameters are now positional-only.
Parameters Parameters
------------ ------------
ctx: :class:`Context` ctx: :class:`Context`
@ -639,7 +672,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
pass pass
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None: async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]], /) -> None:
"""|coro| """|coro|
Handles the implementation of the bot command page in the help command. Handles the implementation of the bot command page in the help command.
@ -659,6 +692,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
Also, the commands in the mapping are not filtered. To do the filtering Also, the commands in the mapping are not filtered. To do the filtering
you will have to call :meth:`filter_commands` yourself. you will have to call :meth:`filter_commands` yourself.
.. versionchanged:: 2.0
``mapping`` parameter is now positional-only.
Parameters Parameters
------------ ------------
mapping: Mapping[Optional[:class:`Cog`], List[:class:`Command`]] mapping: Mapping[Optional[:class:`Cog`], List[:class:`Command`]]
@ -668,7 +705,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return None return None
async def send_cog_help(self, cog: Cog) -> None: async def send_cog_help(self, cog: Cog, /) -> None:
"""|coro| """|coro|
Handles the implementation of the cog page in the help command. Handles the implementation of the cog page in the help command.
@ -689,6 +726,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
The commands returned not filtered. To do the filtering you will have to call The commands returned not filtered. To do the filtering you will have to call
:meth:`filter_commands` yourself. :meth:`filter_commands` yourself.
.. versionchanged:: 2.0
``cog`` parameter is now positional-only.
Parameters Parameters
----------- -----------
cog: :class:`Cog` cog: :class:`Cog`
@ -696,7 +737,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return None return None
async def send_group_help(self, group: Group[Any, ..., Any]) -> None: async def send_group_help(self, group: Group[Any, ..., Any], /) -> None:
"""|coro| """|coro|
Handles the implementation of the group page in the help command. Handles the implementation of the group page in the help command.
@ -717,6 +758,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
:attr:`Group.commands`. The commands returned not filtered. To do the :attr:`Group.commands`. The commands returned not filtered. To do the
filtering you will have to call :meth:`filter_commands` yourself. filtering you will have to call :meth:`filter_commands` yourself.
.. versionchanged:: 2.0
``group`` parameter is now positional-only.
Parameters Parameters
----------- -----------
group: :class:`Group` group: :class:`Group`
@ -724,7 +769,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return None return None
async def send_command_help(self, command: Command[Any, ..., Any]) -> None: async def send_command_help(self, command: Command[Any, ..., Any], /) -> None:
"""|coro| """|coro|
Handles the implementation of the single command page in the help command. Handles the implementation of the single command page in the help command.
@ -755,6 +800,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
There are more than just these attributes but feel free to play around with There are more than just these attributes but feel free to play around with
these to help you get started to get the output that you want. these to help you get started to get the output that you want.
.. versionchanged:: 2.0
``command`` parameter is now positional-only.
Parameters Parameters
----------- -----------
command: :class:`Command` command: :class:`Command`
@ -762,7 +811,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
return None return None
async def prepare_help_command(self, ctx: ContextT, command: Optional[str] = None) -> None: async def prepare_help_command(self, ctx: ContextT, command: Optional[str] = None, /) -> None:
"""|coro| """|coro|
A low level method that can be used to prepare the help command A low level method that can be used to prepare the help command
@ -777,6 +826,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
This is called *inside* the help command callback body. So all This is called *inside* the help command callback body. So all
the usual rules that happen inside apply here as well. the usual rules that happen inside apply here as well.
.. versionchanged:: 2.0
``ctx`` and ``command`` parameters are now positional-only.
Parameters Parameters
----------- -----------
ctx: :class:`Context` ctx: :class:`Context`
@ -786,7 +839,7 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
""" """
pass pass
async def command_callback(self, ctx: ContextT, *, command: Optional[str] = None) -> Any: async def command_callback(self, ctx: ContextT, /, *, command: Optional[str] = None) -> Any:
"""|coro| """|coro|
The actual implementation of the help command. The actual implementation of the help command.
@ -804,6 +857,10 @@ class HelpCommand(HelpCommandCommand, Generic[ContextT]):
- :meth:`send_error_message` - :meth:`send_error_message`
- :meth:`on_help_command_error` - :meth:`on_help_command_error`
- :meth:`prepare_help_command` - :meth:`prepare_help_command`
.. versionchanged:: 2.0
``ctx`` parameter is now positional-only.
""" """
await self.prepare_help_command(ctx, command) await self.prepare_help_command(ctx, command)
@ -899,8 +956,13 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
super().__init__(**options) super().__init__(**options)
def shorten_text(self, text: str) -> str: def shorten_text(self, text: str, /) -> str:
""":class:`str`: Shortens text to fit into the :attr:`width`.""" """:class:`str`: Shortens text to fit into the :attr:`width`.
.. versionchanged:: 2.0
``text`` parameter is now positional-only.
"""
if len(text) > self.width: if len(text) > self.width:
return text[: self.width - 3].rstrip() + '...' return text[: self.width - 3].rstrip() + '...'
return text return text
@ -914,7 +976,7 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
) )
def add_indented_commands( def add_indented_commands(
self, commands: Sequence[Command[Any, ..., Any]], *, heading: str, max_size: Optional[int] = None self, commands: Sequence[Command[Any, ..., Any]], /, *, heading: str, max_size: Optional[int] = None
) -> None: ) -> None:
"""Indents a list of commands after the specified heading. """Indents a list of commands after the specified heading.
@ -925,6 +987,10 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
the command's :attr:`Command.short_doc` and then shortened the command's :attr:`Command.short_doc` and then shortened
to fit into the :attr:`width`. to fit into the :attr:`width`.
.. versionchanged:: 2.0
``commands`` parameter is now positional-only.
Parameters Parameters
----------- -----------
commands: Sequence[:class:`Command`] commands: Sequence[:class:`Command`]
@ -957,9 +1023,13 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
for page in self.paginator.pages: for page in self.paginator.pages:
await destination.send(page) await destination.send(page)
def add_command_formatting(self, command: Command[Any, ..., Any]) -> None: def add_command_formatting(self, command: Command[Any, ..., Any], /) -> None:
"""A utility function to format the non-indented block of commands and groups. """A utility function to format the non-indented block of commands and groups.
.. versionchanged:: 2.0
``command`` parameter is now positional-only.
Parameters Parameters
------------ ------------
command: :class:`Command` command: :class:`Command`
@ -989,11 +1059,11 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
else: else:
return ctx.channel return ctx.channel
async def prepare_help_command(self, ctx: ContextT, command: str) -> None: async def prepare_help_command(self, ctx: ContextT, command: Optional[str] = None, /) -> None:
self.paginator.clear() self.paginator.clear()
await super().prepare_help_command(ctx, command) await super().prepare_help_command(ctx, command)
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None: async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]], /) -> None:
ctx = self.context ctx = self.context
bot = ctx.bot bot = ctx.bot
@ -1023,12 +1093,12 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
await self.send_pages() await self.send_pages()
async def send_command_help(self, command: Command[Any, ..., Any]) -> None: async def send_command_help(self, command: Command[Any, ..., Any], /) -> None:
self.add_command_formatting(command) self.add_command_formatting(command)
self.paginator.close_page() self.paginator.close_page()
await self.send_pages() await self.send_pages()
async def send_group_help(self, group: Group[Any, ..., Any]) -> None: async def send_group_help(self, group: Group[Any, ..., Any], /) -> None:
self.add_command_formatting(group) self.add_command_formatting(group)
filtered = await self.filter_commands(group.commands, sort=self.sort_commands) filtered = await self.filter_commands(group.commands, sort=self.sort_commands)
@ -1042,7 +1112,7 @@ class DefaultHelpCommand(HelpCommand[ContextT]):
await self.send_pages() await self.send_pages()
async def send_cog_help(self, cog: Cog) -> None: async def send_cog_help(self, cog: Cog, /) -> None:
if cog.description: if cog.description:
self.paginator.add_line(cog.description, empty=True) self.paginator.add_line(cog.description, empty=True)
@ -1128,7 +1198,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
f"You can also use `{self.context.clean_prefix}{command_name} [category]` for more info on a category." f"You can also use `{self.context.clean_prefix}{command_name} [category]` for more info on a category."
) )
def get_command_signature(self, command: Command[Any, ..., Any]) -> str: def get_command_signature(self, command: Command[Any, ..., Any], /) -> str:
return f'{self.context.clean_prefix}{command.qualified_name} {command.signature}' return f'{self.context.clean_prefix}{command.qualified_name} {command.signature}'
def get_ending_note(self) -> str: def get_ending_note(self) -> str:
@ -1143,7 +1213,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
""" """
return '' return ''
def add_bot_commands_formatting(self, commands: Sequence[Command[Any, ..., Any]], heading: str) -> None: def add_bot_commands_formatting(self, commands: Sequence[Command[Any, ..., Any]], heading: str, /) -> None:
"""Adds the minified bot heading with commands to the output. """Adds the minified bot heading with commands to the output.
The formatting should be added to the :attr:`paginator`. The formatting should be added to the :attr:`paginator`.
@ -1151,6 +1221,10 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
The default implementation is a bold underline heading followed The default implementation is a bold underline heading followed
by commands separated by an EN SPACE (U+2002) in the next line. by commands separated by an EN SPACE (U+2002) in the next line.
.. versionchanged:: 2.0
``commands`` and ``heading`` parameters are now positional-only.
Parameters Parameters
----------- -----------
commands: Sequence[:class:`Command`] commands: Sequence[:class:`Command`]
@ -1164,7 +1238,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
self.paginator.add_line(f'__**{heading}**__') self.paginator.add_line(f'__**{heading}**__')
self.paginator.add_line(joined) self.paginator.add_line(joined)
def add_subcommand_formatting(self, command: Command[Any, ..., Any]) -> None: def add_subcommand_formatting(self, command: Command[Any, ..., Any], /) -> None:
"""Adds formatting information on a subcommand. """Adds formatting information on a subcommand.
The formatting should be added to the :attr:`paginator`. The formatting should be added to the :attr:`paginator`.
@ -1172,6 +1246,10 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
The default implementation is the prefix and the :attr:`Command.qualified_name` The default implementation is the prefix and the :attr:`Command.qualified_name`
optionally followed by an En dash and the command's :attr:`Command.short_doc`. optionally followed by an En dash and the command's :attr:`Command.short_doc`.
.. versionchanged:: 2.0
``command`` parameter is now positional-only.
Parameters Parameters
----------- -----------
command: :class:`Command` command: :class:`Command`
@ -1180,7 +1258,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
fmt = '{0}{1} \N{EN DASH} {2}' if command.short_doc else '{0}{1}' 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)) self.paginator.add_line(fmt.format(self.context.clean_prefix, command.qualified_name, command.short_doc))
def add_aliases_formatting(self, aliases: Sequence[str]) -> None: def add_aliases_formatting(self, aliases: Sequence[str], /) -> None:
"""Adds the formatting information on a command's aliases. """Adds the formatting information on a command's aliases.
The formatting should be added to the :attr:`paginator`. The formatting should be added to the :attr:`paginator`.
@ -1190,6 +1268,10 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
This is not called if there are no aliases to format. This is not called if there are no aliases to format.
.. versionchanged:: 2.0
``aliases`` parameter is now positional-only.
Parameters Parameters
----------- -----------
aliases: Sequence[:class:`str`] aliases: Sequence[:class:`str`]
@ -1197,9 +1279,13 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
""" """
self.paginator.add_line(f'**{self.aliases_heading}** {", ".join(aliases)}', empty=True) self.paginator.add_line(f'**{self.aliases_heading}** {", ".join(aliases)}', empty=True)
def add_command_formatting(self, command: Command[Any, ..., Any]) -> None: def add_command_formatting(self, command: Command[Any, ..., Any], /) -> None:
"""A utility function to format commands and groups. """A utility function to format commands and groups.
.. versionchanged:: 2.0
``command`` parameter is now positional-only.
Parameters Parameters
------------ ------------
command: :class:`Command` command: :class:`Command`
@ -1233,11 +1319,11 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
else: else:
return ctx.channel return ctx.channel
async def prepare_help_command(self, ctx: ContextT, command: str) -> None: async def prepare_help_command(self, ctx: ContextT, command: Optional[str] = None, /) -> None:
self.paginator.clear() self.paginator.clear()
await super().prepare_help_command(ctx, command) await super().prepare_help_command(ctx, command)
async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]]) -> None: async def send_bot_help(self, mapping: Mapping[Optional[Cog], List[Command[Any, ..., Any]]], /) -> None:
ctx = self.context ctx = self.context
bot = ctx.bot bot = ctx.bot
@ -1268,7 +1354,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
await self.send_pages() await self.send_pages()
async def send_cog_help(self, cog: Cog) -> None: async def send_cog_help(self, cog: Cog, /) -> None:
bot = self.context.bot bot = self.context.bot
if bot.description: if bot.description:
self.paginator.add_line(bot.description, empty=True) self.paginator.add_line(bot.description, empty=True)
@ -1293,7 +1379,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
await self.send_pages() await self.send_pages()
async def send_group_help(self, group: Group[Any, ..., Any]) -> None: async def send_group_help(self, group: Group[Any, ..., Any], /) -> None:
self.add_command_formatting(group) self.add_command_formatting(group)
filtered = await self.filter_commands(group.commands, sort=self.sort_commands) filtered = await self.filter_commands(group.commands, sort=self.sort_commands)
@ -1313,7 +1399,7 @@ class MinimalHelpCommand(HelpCommand[ContextT]):
await self.send_pages() await self.send_pages()
async def send_command_help(self, command: Command[Any, ..., Any]) -> None: async def send_command_help(self, command: Command[Any, ..., Any], /) -> None:
self.add_command_formatting(command) self.add_command_formatting(command)
self.paginator.close_page() self.paginator.close_page()
await self.send_pages() await self.send_pages()

83
docs/migrating.rst

@ -939,6 +939,7 @@ Parameters in the following methods are now all positional-only:
- :meth:`Client.fetch_webhook` - :meth:`Client.fetch_webhook`
- :meth:`Client.fetch_widget` - :meth:`Client.fetch_widget`
- :meth:`Message.add_reaction` - :meth:`Message.add_reaction`
- :meth:`Client.error`
- :meth:`abc.Messageable.fetch_message` - :meth:`abc.Messageable.fetch_message`
- :meth:`abc.GuildChannel.permissions_for` - :meth:`abc.GuildChannel.permissions_for`
- :meth:`DMChannel.get_partial_message` - :meth:`DMChannel.get_partial_message`
@ -950,6 +951,9 @@ Parameters in the following methods are now all positional-only:
The following parameters are now positional-only: The following parameters are now positional-only:
- ``iterable`` in :meth:`utils.get` - ``iterable`` in :meth:`utils.get`
- ``event`` in :meth:`Client.dispatch`
- ``event_method`` in :meth:`Client.on_error`
- ``event`` in :meth:`Client.wait_for`
The following are now keyword-only: The following are now keyword-only:
@ -1247,14 +1251,93 @@ define their type hints more accurately.
Function Signature Changes Function Signature Changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Parameters in the following methods are now all positional-only:
- :meth:`ext.commands.when_mentioned`
- :meth:`ext.commands.Bot.on_command_error`
- :meth:`ext.commands.Bot.check`
- :meth:`ext.commands.Bot.check_once`
- :meth:`ext.commands.Bot.is_owner`
- :meth:`ext.commands.Bot.before_invoke`
- :meth:`ext.commands.Bot.after_invoke`
- :meth:`ext.commands.Bot.get_prefix`
- :meth:`ext.commands.Bot.invoke`
- :meth:`ext.commands.Bot.process_commands`
- :meth:`ext.commands.Bot.on_message`
- :meth:`ext.commands.Command.dispatch_error`
- :meth:`ext.commands.Command.transform`
- :meth:`ext.commands.Command.call_before_hooks`
- :meth:`ext.commands.Command.call_after_hooks`
- :meth:`ext.commands.Command.prepare`
- :meth:`ext.commands.Command.is_on_cooldown`
- :meth:`ext.commands.Command.reset_cooldown`
- :meth:`ext.commands.Command.get_cooldown_retry_after`
- :meth:`ext.commands.Command.invoke`
- :meth:`ext.commands.Command.error`
- :meth:`ext.commands.Command.before_invoke`
- :meth:`ext.commands.Command.after_invoke`
- :meth:`ext.commands.Command.can_run`
- :meth:`ext.commands.Group.invoke`
- :meth:`ext.commands.check`
- :meth:`ext.commands.has_role`
- :meth:`ext.commands.bot_has_role`
- :meth:`ext.commands.before_invoke`
- :meth:`ext.commands.after_invoke`
- :meth:`ext.commands.HelpCommand.call_before_hooks`
- :meth:`ext.commands.HelpCommand.call_after_hooks`
- :meth:`ext.commands.HelpCommand.can_run`
- :meth:`ext.commands.HelpCommand.get_command_signature`
- :meth:`ext.commands.HelpCommand.remove_mentions`
- :meth:`ext.commands.HelpCommand.command_not_found`
- :meth:`ext.commands.HelpCommand.subcommand_not_found`
- :meth:`ext.commands.HelpCommand.get_max_size`
- :meth:`ext.commands.HelpCommand.send_error_message`
- :meth:`ext.commands.HelpCommand.on_help_command_error`
- :meth:`ext.commands.HelpCommand.send_bot_help`
- :meth:`ext.commands.HelpCommand.send_cog_help`
- :meth:`ext.commands.HelpCommand.send_group_help`
- :meth:`ext.commands.HelpCommand.send_command_help`
- :meth:`ext.commands.HelpCommand.prepare_help_command`
- :meth:`ext.commands.DefaultHelpCommand.shorten_text`
- :meth:`ext.commands.DefaultHelpCommand.add_command_formatting`
- :meth:`ext.commands.DefaultHelpCommand.prepare_help_command`
- :meth:`ext.commands.DefaultHelpCommand.send_bot_help`
- :meth:`ext.commands.DefaultHelpCommand.send_command_help`
- :meth:`ext.commands.DefaultHelpCommand.send_group_help`
- :meth:`ext.commands.DefaultHelpCommand.send_cog_help`
- :meth:`ext.commands.MinimalHelpCommand.get_command_signature`
- :meth:`ext.commands.MinimalHelpCommand.add_bot_commands_formatting`
- :meth:`ext.commands.MinimalHelpCommand.add_subcommand_formatting`
- :meth:`ext.commands.MinimalHelpCommand.add_aliases_formatting`
- :meth:`ext.commands.MinimalHelpCommand.add_command_formatting`
- :meth:`ext.commands.MinimalHelpCommand.prepare_help_command`
- :meth:`ext.commands.MinimalHelpCommand.send_bot_help`
- :meth:`ext.commands.MinimalHelpCommand.send_cog_help`
- :meth:`ext.commands.MinimalHelpCommand.send_group_help`
- :meth:`ext.commands.MinimalHelpCommand.send_command_help`
The following parameters are now positional-only: The following parameters are now positional-only:
- ``event_name`` in :meth:`ext.commands.Bot.dispatch`
- ``func`` in :meth:`ext.commands.Bot.check`
- ``func`` in :meth:`ext.commands.Bot.add_check` - ``func`` in :meth:`ext.commands.Bot.add_check`
- ``func`` in :meth:`ext.commands.Bot.remove_check` - ``func`` in :meth:`ext.commands.Bot.remove_check`
- ``func`` in :meth:`ext.commands.Bot.check_once`
- ``ctx`` in :meth:`ext.commands.Bot.can_run`
- ``func`` in :meth:`ext.commands.Bot.add_listener`
- ``func`` in :meth:`ext.commands.Bot.remove_listener`
- ``message`` in :meth:`ext.commands.Bot.get_context`
- ``func`` in :meth:`ext.commands.Command.add_check` - ``func`` in :meth:`ext.commands.Command.add_check`
- ``func`` in :meth:`ext.commands.Command.remove_check` - ``func`` in :meth:`ext.commands.Command.remove_check`
- ``context`` in :meth:`ext.commands.Command.__call__`
- ``ctx`` in :meth:`ext.commands.Command.reinvoke`
- ``ctx`` in :meth:`ext.commands.Group.reinvoke`
- ``context`` in :meth:`ext.commands.HelpCommand.__call__`
- ``commands`` in :meth:`ext.commands.HelpCommand.filter_commands`
- ``ctx`` in :meth:`ext.commands.HelpCommand.command_callback`
- ``func`` in :meth:`ext.commands.HelpCommand.add_check` - ``func`` in :meth:`ext.commands.HelpCommand.add_check`
- ``func`` in :meth:`ext.commands.HelpCommand.remove_check` - ``func`` in :meth:`ext.commands.HelpCommand.remove_check`
- ``commands`` in :meth:`ext.commands.DefaultHelpCommand.add_indented_commands`
- ``cog`` in :meth:`ext.commands.Bot.add_cog` - ``cog`` in :meth:`ext.commands.Bot.add_cog`
- ``name`` in :meth:`ext.commands.Bot.get_cog` - ``name`` in :meth:`ext.commands.Bot.get_cog`
- ``name`` in :meth:`ext.commands.Bot.remove_cog` - ``name`` in :meth:`ext.commands.Bot.remove_cog`

Loading…
Cancel
Save