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
|
||||
|
||||
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:
|
||||
def __repr__(self):
|
||||
@ -1177,12 +1190,15 @@ class BotBase(GroupMixin):
|
||||
prefix = prefix[0]
|
||||
|
||||
# Add arguments to fake message content, in the right order
|
||||
ignore_params: List[inspect.Parameter] = []
|
||||
message.content = f'{prefix}{command_name} '
|
||||
for name, param in command.clean_params.items():
|
||||
option = next((o for o in command_options if o['name'] == name), None) # type: ignore
|
||||
if option is None:
|
||||
if param.default is param.empty and not command._is_typing_optional(param.annotation):
|
||||
raise errors.MissingRequiredArgument(param)
|
||||
else:
|
||||
ignore_params.append(param)
|
||||
elif (
|
||||
option["type"] == 3
|
||||
and param.kind != param.KEYWORD_ONLY
|
||||
@ -1190,28 +1206,13 @@ class BotBase(GroupMixin):
|
||||
):
|
||||
# String with space in without "consume rest"
|
||||
option = cast(_ApplicationCommandInteractionDataOptionString, option)
|
||||
|
||||
# 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
|
||||
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)
|
||||
quoted_string = _quote_string_safe(option['value'])
|
||||
message.content += f'{quoted_string} '
|
||||
else:
|
||||
message.content += f'{option.get("value", "")} '
|
||||
|
||||
ctx = await self.get_context(message)
|
||||
ctx._ignored_params = ignore_params
|
||||
ctx.interaction = interaction
|
||||
await self.invoke(ctx)
|
||||
|
||||
|
@ -154,6 +154,7 @@ class Context(discord.abc.Messageable, Generic[BotT]):
|
||||
self.subcommand_passed: Optional[str] = subcommand_passed
|
||||
self.command_failed: bool = command_failed
|
||||
self.current_parameter: Optional[inspect.Parameter] = current_parameter
|
||||
self._ignored_params: List[inspect.Parameter] = []
|
||||
self._state: ConnectionState = self.message._state
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
converter = get_converter(param)
|
||||
consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw
|
||||
|
Loading…
x
Reference in New Issue
Block a user