mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-22 16:51:59 +00:00
[commands] Add support for Range[str, ...]
This commit is contained in:
parent
bac66a9dab
commit
b5392ea0f1
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
@ -594,17 +594,17 @@ class RangeError(BadArgument):
|
||||
The minimum value expected or ``None`` if there wasn't one
|
||||
maximum: Optional[Union[:class:`int`, :class:`float`]]
|
||||
The maximum value expected or ``None`` if there wasn't one
|
||||
value: Union[:class:`int`, :class:`float`]
|
||||
value: Union[:class:`int`, :class:`float`, :class:`str`]
|
||||
The value that was out of range.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Union[int, float],
|
||||
value: Union[int, float, str],
|
||||
minimum: Optional[Union[int, float]],
|
||||
maximum: Optional[Union[int, float]],
|
||||
) -> None:
|
||||
self.value: Union[int, float] = value
|
||||
self.value: Union[int, float, str] = value
|
||||
self.minimum: Optional[Union[int, float]] = minimum
|
||||
self.maximum: Optional[Union[int, float]] = maximum
|
||||
|
||||
@ -616,6 +616,14 @@ class RangeError(BadArgument):
|
||||
elif maximum is not None and minimum is not None:
|
||||
label = f'between {minimum} and {maximum}'
|
||||
|
||||
if label and isinstance(value, str):
|
||||
label += ' characters'
|
||||
count = len(value)
|
||||
if count == 1:
|
||||
value = '1 character'
|
||||
else:
|
||||
value = f'{count} characters'
|
||||
|
||||
super().__init__(f'value must be {label} but received {value}')
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user