[commands] Default construct flags if they're not passed as parameters

This only applies if and only if the flag can be default constructible.
Ergo, all the flags are optional or not required.
This commit is contained in:
Rapptz 2021-04-20 08:00:47 -04:00
parent ac7588f735
commit 15bfdf66b2
2 changed files with 18 additions and 0 deletions

View File

@ -559,6 +559,8 @@ class Command(_BaseCommand):
if required:
if self._is_typing_optional(param.annotation):
return None
if hasattr(converter, '__commands_is_flag__') and converter._can_be_constructible():
return await converter._construct_default(ctx)
raise MissingRequiredArgument(param)
return param.default

View File

@ -408,6 +408,22 @@ class FlagConverter(metaclass=FlagsMeta):
"""Dict[:class:`str`, :class:`Flag`]: A mapping of flag name to flag object this converter has."""
return cls.__commands_flags__.copy()
@classmethod
def _can_be_constructible(cls) -> bool:
return all(not flag.required for flag in cls.__commands_flags__.values())
@classmethod
async def _construct_default(cls: Type[F], ctx: Context) -> F:
self: F = cls.__new__(cls)
flags = cls.__commands_flags__
for flag in flags.values():
if callable(flag.default):
default = await maybe_coroutine(flag.default, ctx)
setattr(self, flag.attribute, default)
else:
setattr(self, flag.attribute, flag.default)
return self
def __repr__(self) -> str:
pairs = ' '.join([f'{flag.attribute}={getattr(self, flag.attribute)!r}' for flag in self.get_flags().values()])
return f'<{self.__class__.__name__} {pairs}>'