Fix multiple optional argument sorting
This commit is contained in:
parent
e9b95eaff7
commit
575a92cd3a
@ -148,6 +148,19 @@ def _unwrap_slash_groups(data: ApplicationCommandInteractionData) -> Tuple[str,
|
|||||||
|
|
||||||
return command_name, command_options
|
return command_name, command_options
|
||||||
|
|
||||||
|
def _quote_string_safe(string: str) -> str:
|
||||||
|
# we need to quote this string otherwise we may spill into
|
||||||
|
# other parameters and cause all kinds of trouble, as many
|
||||||
|
# quotes are supported and some may be in the option, we
|
||||||
|
# loop through all supported quotes and if neither open or
|
||||||
|
# close are in the string, we add them
|
||||||
|
for open, close in supported_quotes.items():
|
||||||
|
if open not in string and close not in string:
|
||||||
|
return f"{open}{string}{close}"
|
||||||
|
|
||||||
|
# all supported quotes are in the message and we cannot add any
|
||||||
|
# safely, very unlikely but still got to be covered
|
||||||
|
raise errors.UnexpectedQuoteError(string)
|
||||||
|
|
||||||
class _DefaultRepr:
|
class _DefaultRepr:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -1177,12 +1190,15 @@ class BotBase(GroupMixin):
|
|||||||
prefix = prefix[0]
|
prefix = prefix[0]
|
||||||
|
|
||||||
# Add arguments to fake message content, in the right order
|
# Add arguments to fake message content, in the right order
|
||||||
|
ignore_params: List[inspect.Parameter] = []
|
||||||
message.content = f'{prefix}{command_name} '
|
message.content = f'{prefix}{command_name} '
|
||||||
for name, param in command.clean_params.items():
|
for name, param in command.clean_params.items():
|
||||||
option = next((o for o in command_options if o['name'] == name), None) # type: ignore
|
option = next((o for o in command_options if o['name'] == name), None) # type: ignore
|
||||||
if option is None:
|
if option is None:
|
||||||
if param.default is param.empty and not command._is_typing_optional(param.annotation):
|
if param.default is param.empty and not command._is_typing_optional(param.annotation):
|
||||||
raise errors.MissingRequiredArgument(param)
|
raise errors.MissingRequiredArgument(param)
|
||||||
|
else:
|
||||||
|
ignore_params.append(param)
|
||||||
elif (
|
elif (
|
||||||
option["type"] == 3
|
option["type"] == 3
|
||||||
and param.kind != param.KEYWORD_ONLY
|
and param.kind != param.KEYWORD_ONLY
|
||||||
@ -1190,28 +1206,13 @@ class BotBase(GroupMixin):
|
|||||||
):
|
):
|
||||||
# String with space in without "consume rest"
|
# String with space in without "consume rest"
|
||||||
option = cast(_ApplicationCommandInteractionDataOptionString, option)
|
option = cast(_ApplicationCommandInteractionDataOptionString, option)
|
||||||
|
quoted_string = _quote_string_safe(option['value'])
|
||||||
# we need to quote this string otherwise we may spill into
|
message.content += f'{quoted_string} '
|
||||||
# other parameters and cause all kinds of trouble, as many
|
|
||||||
# quotes are supported and some may be in the option, we
|
|
||||||
# loop through all supported quotes and if neither open or
|
|
||||||
# close are in the string, we add them
|
|
||||||
quoted = False
|
|
||||||
string = option['value']
|
|
||||||
for open, close in supported_quotes.items():
|
|
||||||
if open not in string and close not in string:
|
|
||||||
message.content += f"{open}{string}{close} "
|
|
||||||
quoted = True
|
|
||||||
break
|
|
||||||
|
|
||||||
# all supported quotes are in the message and we cannot add any
|
|
||||||
# safely, very unlikely but still got to be covered
|
|
||||||
if not quoted:
|
|
||||||
raise errors.UnexpectedQuoteError(string)
|
|
||||||
else:
|
else:
|
||||||
message.content += f'{option.get("value", "")} '
|
message.content += f'{option.get("value", "")} '
|
||||||
|
|
||||||
ctx = await self.get_context(message)
|
ctx = await self.get_context(message)
|
||||||
|
ctx._ignored_params = ignore_params
|
||||||
ctx.interaction = interaction
|
ctx.interaction = interaction
|
||||||
await self.invoke(ctx)
|
await self.invoke(ctx)
|
||||||
|
|
||||||
|
@ -154,6 +154,7 @@ class Context(discord.abc.Messageable, Generic[BotT]):
|
|||||||
self.subcommand_passed: Optional[str] = subcommand_passed
|
self.subcommand_passed: Optional[str] = subcommand_passed
|
||||||
self.command_failed: bool = command_failed
|
self.command_failed: bool = command_failed
|
||||||
self.current_parameter: Optional[inspect.Parameter] = current_parameter
|
self.current_parameter: Optional[inspect.Parameter] = current_parameter
|
||||||
|
self._ignored_params: List[inspect.Parameter] = []
|
||||||
self._state: ConnectionState = self.message._state
|
self._state: ConnectionState = self.message._state
|
||||||
|
|
||||||
async def invoke(self, command: Command[CogT, P, T], /, *args: P.args, **kwargs: P.kwargs) -> T:
|
async def invoke(self, command: Command[CogT, P, T], /, *args: P.args, **kwargs: P.kwargs) -> T:
|
||||||
|
@ -577,6 +577,10 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
ctx.bot.dispatch('command_error', ctx, error)
|
ctx.bot.dispatch('command_error', ctx, error)
|
||||||
|
|
||||||
async def transform(self, ctx: Context, param: inspect.Parameter) -> Any:
|
async def transform(self, ctx: Context, param: inspect.Parameter) -> Any:
|
||||||
|
if param in ctx._ignored_params:
|
||||||
|
# in a slash command, we need a way to mark a param as default so ctx._ignored_params is used
|
||||||
|
return param.default if param.default is not param.empty else None
|
||||||
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user