mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-07-01 07:40:07 +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:
|
else:
|
||||||
|
|
||||||
class Range:
|
class Range:
|
||||||
"""A special converter that can be applied to a parameter to require a numeric type
|
"""A special converter that can be applied to a parameter to require a numeric
|
||||||
to fit within the range provided.
|
or string type to fit within the range provided.
|
||||||
|
|
||||||
During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand
|
During type checking time this is equivalent to :obj:`typing.Annotated` so type checkers understand
|
||||||
the intent of the code.
|
the intent of the code.
|
||||||
@ -1055,6 +1055,9 @@ else:
|
|||||||
|
|
||||||
Inside a :class:`HybridCommand` this functions equivalently to :class:`discord.app_commands.Range`.
|
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
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
@ -1079,8 +1082,11 @@ else:
|
|||||||
self.max: Optional[Union[int, float]] = max
|
self.max: Optional[Union[int, float]] = max
|
||||||
|
|
||||||
async def convert(self, ctx: Context[BotT], value: str) -> Union[int, float]:
|
async def convert(self, ctx: Context[BotT], value: str) -> Union[int, float]:
|
||||||
converted = self.annotation(value)
|
count = converted = self.annotation(value)
|
||||||
if (self.min is not None and converted < self.min) or (self.max is not None and converted > self.max):
|
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)
|
raise RangeError(converted, minimum=self.min, maximum=self.max)
|
||||||
|
|
||||||
return converted
|
return converted
|
||||||
@ -1108,13 +1114,18 @@ else:
|
|||||||
if type(min) != type(max):
|
if type(min) != type(max):
|
||||||
raise TypeError('Both min and max in Range must be the same type')
|
raise TypeError('Both min and max in Range must be the same type')
|
||||||
|
|
||||||
if annotation not in (int, float):
|
if annotation not in (int, float, str):
|
||||||
raise TypeError(f'expected int or float as range type, received {annotation!r} instead')
|
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(
|
return cls(
|
||||||
annotation=annotation,
|
annotation=annotation,
|
||||||
min=annotation(min) if min is not None else None,
|
min=cast(min) if min is not None else None,
|
||||||
max=annotation(max) if max 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
|
The minimum value expected or ``None`` if there wasn't one
|
||||||
maximum: Optional[Union[:class:`int`, :class:`float`]]
|
maximum: Optional[Union[:class:`int`, :class:`float`]]
|
||||||
The maximum value expected or ``None`` if there wasn't one
|
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.
|
The value that was out of range.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
value: Union[int, float],
|
value: Union[int, float, str],
|
||||||
minimum: Optional[Union[int, float]],
|
minimum: Optional[Union[int, float]],
|
||||||
maximum: Optional[Union[int, float]],
|
maximum: Optional[Union[int, float]],
|
||||||
) -> None:
|
) -> None:
|
||||||
self.value: Union[int, float] = value
|
self.value: Union[int, float, str] = value
|
||||||
self.minimum: Optional[Union[int, float]] = minimum
|
self.minimum: Optional[Union[int, float]] = minimum
|
||||||
self.maximum: Optional[Union[int, float]] = maximum
|
self.maximum: Optional[Union[int, float]] = maximum
|
||||||
|
|
||||||
@ -616,6 +616,14 @@ class RangeError(BadArgument):
|
|||||||
elif maximum is not None and minimum is not None:
|
elif maximum is not None and minimum is not None:
|
||||||
label = f'between {minimum} and {maximum}'
|
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}')
|
super().__init__(f'value must be {label} but received {value}')
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user