diff --git a/discord/app_commands/commands.py b/discord/app_commands/commands.py index dc4021e63..a164b34ea 100644 --- a/discord/app_commands/commands.py +++ b/discord/app_commands/commands.py @@ -44,7 +44,6 @@ from typing import ( Union, overload, ) -from textwrap import TextWrapper import re @@ -57,7 +56,7 @@ from ..message import Message from ..user import User from ..member import Member from ..permissions import Permissions -from ..utils import resolve_annotation, MISSING, is_inside_class, maybe_coroutine, async_all +from ..utils import resolve_annotation, MISSING, is_inside_class, maybe_coroutine, async_all, _shorten, _to_kebab_case if TYPE_CHECKING: from typing_extensions import ParamSpec, Concatenate @@ -143,8 +142,6 @@ THAI_COMBINING = r'\u0e31-\u0e3a\u0e47-\u0e4e' DEVANAGARI_COMBINING = r'\u0900-\u0903\u093a\u093b\u093c\u093e\u093f\u0940-\u094f\u0955\u0956\u0957\u0962\u0963' VALID_SLASH_COMMAND_NAME = re.compile(r'^[-_\w' + THAI_COMBINING + DEVANAGARI_COMBINING + r']{1,32}$') -CAMEL_CASE_REGEX = re.compile(r'(?\w+)' ARG_DESCRIPTION_SUBREGEX = r'(?P(?:.|\n)+?(?:\Z|\r?\n(?=[\S\r\n])))' @@ -167,19 +164,6 @@ NUMPY_DOCSTRING_ARG_REGEX = re.compile( ) -def _shorten( - input: str, - *, - _wrapper: TextWrapper = TextWrapper(width=100, max_lines=1, replace_whitespace=True, placeholder='…'), -) -> str: - try: - # split on the first double newline since arguments may appear after that - input, _ = re.split(r'\n\s*\n', input, maxsplit=1) - except ValueError: - pass - return _wrapper.fill(' '.join(input.strip().split())) - - def _parse_args_from_docstring(func: Callable[..., Any], params: Dict[str, CommandParameter]) -> Dict[str, str]: docstring = inspect.getdoc(func) @@ -201,10 +185,6 @@ def _parse_args_from_docstring(func: Callable[..., Any], params: Dict[str, Comma } -def _to_kebab_case(text: str) -> str: - return CAMEL_CASE_REGEX.sub('-', text).lower() - - def validate_name(name: str) -> str: match = VALID_SLASH_COMMAND_NAME.match(name) if match is None: @@ -227,7 +207,7 @@ def validate_context_menu_name(name: str) -> str: return name -def _validate_auto_complete_callback( +def validate_auto_complete_callback( callback: AutocompleteCallback[GroupT, ChoiceT] ) -> AutocompleteCallback[GroupT, ChoiceT]: # This function needs to ensure the following is true: @@ -366,7 +346,7 @@ def _populate_autocomplete(params: Dict[str, CommandParameter], autocomplete: Di 'Choice annotation unsupported for autocomplete parameters, consider using a regular annotation instead' ) - param.autocomplete = _validate_auto_complete_callback(callback) + param.autocomplete = validate_auto_complete_callback(callback) if autocomplete: first = next(iter(autocomplete)) @@ -1117,7 +1097,7 @@ class Command(Generic[GroupT, P, T]): 'Choice annotation unsupported for autocomplete parameters, consider using a regular annotation instead' ) - param.autocomplete = _validate_auto_complete_callback(coro) + param.autocomplete = validate_auto_complete_callback(coro) return coro return decorator diff --git a/discord/app_commands/transformers.py b/discord/app_commands/transformers.py index 5f2649dcb..0816c5b87 100644 --- a/discord/app_commands/transformers.py +++ b/discord/app_commands/transformers.py @@ -870,8 +870,8 @@ def annotation_to_parameter(annotation: Any, parameter: inspect.Parameter) -> Co # Check if the method is overridden if inner.autocomplete.__func__ is not Transformer.autocomplete: - from .commands import _validate_auto_complete_callback + from .commands import validate_auto_complete_callback - result.autocomplete = _validate_auto_complete_callback(inner.autocomplete) + result.autocomplete = validate_auto_complete_callback(inner.autocomplete) return result diff --git a/discord/app_commands/tree.py b/discord/app_commands/tree.py index 61867633c..16dcf3244 100644 --- a/discord/app_commands/tree.py +++ b/discord/app_commands/tree.py @@ -48,7 +48,7 @@ from collections import Counter from .namespace import Namespace, ResolveKey from .models import AppCommand -from .commands import Command, ContextMenu, Group, _shorten +from .commands import Command, ContextMenu, Group from .errors import ( AppCommandError, CommandAlreadyRegistered, @@ -61,7 +61,7 @@ from .errors import ( from .translator import Translator, locale_str from ..errors import ClientException, HTTPException from ..enums import AppCommandType, InteractionType -from ..utils import MISSING, _get_as_snowflake, _is_submodule +from ..utils import MISSING, _get_as_snowflake, _is_submodule, _shorten from .._types import ClientT diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py index 23cafa6d5..d02b4e84f 100644 --- a/discord/ext/commands/cog.py +++ b/discord/ext/commands/cog.py @@ -26,7 +26,7 @@ from __future__ import annotations import inspect import discord from discord import app_commands -from discord.utils import maybe_coroutine +from discord.utils import maybe_coroutine, _to_kebab_case from typing import ( Any, @@ -182,7 +182,7 @@ class CogMeta(type): try: group_name = kwargs.pop('group_name') except KeyError: - group_name = app_commands.commands._to_kebab_case(name) + group_name = _to_kebab_case(name) else: group_name = kwargs.pop('group_name', cog_name) diff --git a/discord/utils.py b/discord/utils.py index 779ee9737..6b4e14347 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -25,6 +25,7 @@ from __future__ import annotations import array import asyncio +from textwrap import TextWrapper from typing import ( Any, AsyncIterable, @@ -1353,3 +1354,23 @@ def setup_logging( handler.setFormatter(formatter) logger.setLevel(level) logger.addHandler(handler) + + +def _shorten( + input: str, + *, + _wrapper: TextWrapper = TextWrapper(width=100, max_lines=1, replace_whitespace=True, placeholder='…'), +) -> str: + try: + # split on the first double newline since arguments may appear after that + input, _ = re.split(r'\n\s*\n', input, maxsplit=1) + except ValueError: + pass + return _wrapper.fill(' '.join(input.strip().split())) + + +CAMEL_CASE_REGEX = re.compile(r'(? str: + return CAMEL_CASE_REGEX.sub('-', text).lower()