[commands] Add support for Range[str, ...]

This commit is contained in:
Rapptz
2022-07-01 19:21:56 -04:00
parent bac66a9dab
commit b5392ea0f1
2 changed files with 30 additions and 11 deletions

View File

@ -1041,8 +1041,8 @@ if TYPE_CHECKING:
else:
class Range:
"""A special converter that can be applied to a parameter to require a numeric type
to fit within the range provided.
"""A special converter that can be applied to a parameter to require a numeric
or string type to fit within the range provided.
During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand
the intent of the code.
@ -1055,6 +1055,9 @@ else:
Inside a :class:`HybridCommand` this functions equivalently to :class:`discord.app_commands.Range`.
If the converter fails then :class:`~.ext.commands.RangeError` is raised to
the appropriate error handlers.
.. versionadded:: 2.0
Examples
@ -1079,8 +1082,11 @@ else:
self.max: Optional[Union[int, float]] = max
async def convert(self, ctx: Context[BotT], value: str) -> Union[int, float]:
converted = self.annotation(value)
if (self.min is not None and converted < self.min) or (self.max is not None and converted > self.max):
count = converted = self.annotation(value)
if self.annotation is str:
count = len(value)
if (self.min is not None and count < self.min) or (self.max is not None and count > self.max):
raise RangeError(converted, minimum=self.min, maximum=self.max)
return converted
@ -1108,13 +1114,18 @@ else:
if type(min) != type(max):
raise TypeError('Both min and max in Range must be the same type')
if annotation not in (int, float):
raise TypeError(f'expected int or float as range type, received {annotation!r} instead')
if annotation not in (int, float, str):
raise TypeError(f'expected int, float, or str as range type, received {annotation!r} instead')
if annotation in (str, int):
cast = int
else:
cast = float
return cls(
annotation=annotation,
min=annotation(min) if min is not None else None,
max=annotation(max) if max is not None else None,
min=cast(min) if min is not None else None,
max=cast(max) if max is not None else None,
)