Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 16 additions & 24 deletions validators/_extremes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,18 @@
class AbsMax:
"""An object that is greater than any other object (except itself).

Inspired by https://pypi.python.org/pypi/Extremes

Examples::

>>> import sys
Inspired by https://pypi.python.org/pypi/Extremes.

Examples:
>>> from sys import maxint
>>> AbsMax > AbsMin
True

>>> AbsMax > sys.maxint
True

# Output: True
>>> AbsMax > maxint
# Output: True
>>> AbsMax > 99999999999999999
True
# Output: True

.. versionadded:: 0.2
> *New in version 0.2.0*.
"""

def __ge__(self, other: Any):
Expand All @@ -37,22 +33,18 @@ def __ge__(self, other: Any):
class AbsMin:
"""An object that is less than any other object (except itself).

Inspired by https://pypi.python.org/pypi/Extremes

Examples::

>>> import sys

>>> AbsMin < -sys.maxint
True
Inspired by https://pypi.python.org/pypi/Extremes.

Examples:
>>> from sys import maxint
>>> AbsMin < -maxint
# Output: True
>>> AbsMin < None
True

# Output: True
>>> AbsMin < ''
True
# Output: True

.. versionadded:: 0.2
> *New in version 0.2.0*.
"""

def __le__(self, other: Any):
Expand Down
54 changes: 25 additions & 29 deletions validators/between.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,68 +9,64 @@
from ._extremes import AbsMax, AbsMin
from .utils import validator

T = TypeVar("T", int, float, str, datetime)
PossibleValueTypes = TypeVar("PossibleValueTypes", int, float, str, datetime)


@validator
def between(
value: T,
value: PossibleValueTypes,
/,
*,
min_val: Union[T, AbsMin, None] = None,
max_val: Union[T, AbsMax, None] = None,
min_val: Union[PossibleValueTypes, AbsMin, None] = None,
max_val: Union[PossibleValueTypes, AbsMax, None] = None,
):
"""Validate that a number is between minimum and/or maximum value.

This will work with any comparable type, such as floats, decimals and dates
not just integers. This validator is originally based on `WTForms-NumberRange-Validator`_
not just integers. This validator is originally based on [WTForms-NumberRange-Validator][1].

.. _WTForms-NumberRange-Validator:
https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L166-L220

Examples::
[1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L166-L220

Examples:
>>> from datetime import datetime

>>> between(5, min_val=2)
# Output: True

>>> between(13.2, min_val=13, max_val=14)
# Output: True

>>> between(500, max_val=400)
# Output: ValidationFailure(func=between, args=...)

>>> between(
... datetime(2000, 11, 11),
... min_val=datetime(1999, 11, 11)
... )
# True
# Output: True

Args:
`value`:
[Required] Value which is to be compared.
`min_val`:
[Optional] The minimum required value of the number.
value:
Value which is to be compared.
min_val:
The minimum required value of the number.
If not provided, minimum value will not be checked.
`max_val`:
[Optional] The maximum value of the number.
max_val:
The maximum value of the number.
If not provided, maximum value will not be checked.
Either one of `min_val` or `max_val` must be provided.

Returns:
A `boolean` if `value` is greater than `min_val` and
less than `max_val`.
(Literal[True]):
If `value` is in between the given conditions.
(ValidationFailure):
If `value` is not in between the given conditions.

Raises:
`AssertionError`:
- If both `min_val` and `max_val` are `None`.
- If `min_val` is greater than `max_val`.
AssertionError: If both `min_val` and `max_val` are `None`,
or if `min_val` is greater than `max_val`.
TypeError: If there's a type mismatch before comparison.

`TypeError`:
- If there's a type mismatch before comparison
Note:
- `PossibleValueTypes` = `TypeVar("PossibleValueTypes", int, float, str, datetime)`
- Either one of `min_val` or `max_val` must be provided.

.. versionadded:: 0.2
> *New in version 0.2.0*.
"""
if min_val is None and max_val is None:
raise AssertionError("At least one of either `min_val` or `max_val` must be specified")
Expand Down
16 changes: 8 additions & 8 deletions validators/btc_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,23 @@ def btc_address(value: str, /):
For segwit addresses a regexp is used to provide a reasonable
estimate on whether the address is valid.

Examples::

Examples:
>>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69')
# Output: True
>>> btc_address('1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2')
# Output: ValidationFailure(func=btc_address, args=...)

Args:
`value`:
[Required] Bitcoin address string to validate.
value:
Bitcoin address string to validate.

Returns:
`True`:
If the value is valid bitcoin address.
`ValidationFailure`:
If the value is an invalid bitcoin address.
(Literal[True]):
If `value` is a valid bitcoin address.
(ValidationFailure):
If `value` is an invalid bitcoin address.

> *New in version 0.18.0*.
"""
if value and type(value) is str:
return (
Expand Down
26 changes: 12 additions & 14 deletions validators/length.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,30 @@
def length(value: str, /, *, min_val: int = 0, max_val: int = 0):
"""Return whether or not the length of given string is within a specified range.

Examples::

Examples:
>>> length('something', min_val=2)
# Output: True

>>> length('something', min_val=9, max_val=9)
# Output: True

>>> length('something', max_val=5)
# Output: ValidationFailure(func=length, ...)

Args:
`value`:
[Required] The string to validate.
`min_val`:
[Optional] The minimum required length of the string. If not provided,
value:
The string to validate.
min_val:
The minimum required length of the string. If not provided,
minimum length will not be checked.
`max_val`:
[Optional] The maximum length of the string. If not provided,
max_val:
The maximum length of the string. If not provided,
maximum length will not be checked.
Either one of `min_val` or `max_val` must be provided.

Returns:
A `boolean` if `value` is greater than `min_val` and
less than `max_val`.
(Literal[True]):
If `len(value)` is in between the given conditions.
(ValidationFailure):
If `len(value)` is not in between the given conditions.

.. versionadded:: 0.2
> *New in version 0.2.0*.
"""
return between(len(value), min_val=min_val, max_val=max_val)
29 changes: 10 additions & 19 deletions validators/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def __bool__(self):

def _func_args_as_dict(func: Callable[..., Any], *args: Any, **kwargs: Any):
"""Return function's positional and key value arguments as an ordered dictionary."""
# TODO: find more efficient way to do it
return dict(
list(zip(dict.fromkeys(chain(getfullargspec(func)[0], kwargs.keys())), args))
+ list(kwargs.items())
Expand All @@ -43,26 +42,28 @@ def _func_args_as_dict(func: Callable[..., Any], *args: Any, **kwargs: Any):
def validator(func: Callable[..., Any]):
"""A decorator that makes given function validator.

Whenever the given function is called and returns ``False`` value
this decorator returns :class:`ValidationFailure` object.

Example::
Whenever the given `func` returns `False` this
decorator returns `ValidationFailure` object.

Examples:
>>> @validator
... def even(value):
... return not (value % 2)

>>> even(4)
# Output: True

>>> even(5)
# Output: ValidationFailure(func=even, args={'value': 5})

Args:
`func`: function which is to be decorated.
func:
Function which is to be decorated.

Returns:
Wrapper function as a decorator.
(Callable[..., ValidationFailure | Literal[True])):
A decorator which returns either `ValidationFailure`
or `Literal[True]`.

> *New in version 2013.10.21*.
"""

def wrapper(*args: Any, **kwargs: Any):
Expand All @@ -71,15 +72,5 @@ def wrapper(*args: Any, **kwargs: Any):
if func(*args, **kwargs)
else ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs))
)
# try:
# return (
# True
# if func(*args, **kwargs)
# else ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs))
# )
# except (AssertionError, TypeError) as err:
# print(err)
# finally:
# return ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs))

return wrapper