Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additonal validators #845

Merged
merged 7 commits into from
Sep 24, 2021
Merged
Changes from 1 commit
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
Prev Previous commit
Add doctests and rename maxlen to max_len
sscherfke committed Sep 23, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 36701e5cf64687ead22e6aaa5973deb8f229a7b1
71 changes: 70 additions & 1 deletion docs/api.rst
Original file line number Diff line number Diff line change
@@ -347,14 +347,83 @@ Validators

.. autofunction:: attr.validators.lt

For example:

.. doctest::

>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.lt(42))
>>> C(41)
C(x=41)
>>> C(42)
Traceback (most recent call last):
...
ValueError: ("'x' must be < 42: 42")

.. autofunction:: attr.validators.le

For example:

.. doctest::

>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.le(42))
>>> C(42)
C(x=42)
>>> C(43)
Traceback (most recent call last):
...
ValueError: ("'x' must be <= 42: 43")

.. autofunction:: attr.validators.ge

For example:

.. doctest::

>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.ge(42))
>>> C(42)
C(x=42)
>>> C(41)
Traceback (most recent call last):
...
ValueError: ("'x' must be => 42: 41")

.. autofunction:: attr.validators.gt

.. autofunction:: attr.validators.maxlen
For example:

.. doctest::

>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.gt(42))
>>> C(43)
C(x=43)
>>> C(42)
Traceback (most recent call last):
...
ValueError: ("'x' must be > 42: 42")

.. autofunction:: attr.validators.max_len

For example:

.. doctest::

>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.max_len(4))
>>> C("spam")
C(x='spam')
>>> C("bacon")
Traceback (most recent call last):
...
ValueError: ("Length of 'x' must be <= 4: 5")

.. autofunction:: attr.validators.instance_of

6 changes: 3 additions & 3 deletions src/attr/validators.py
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
"le",
"lt",
"matches_re",
"maxlen",
"max_len",
"optional",
"provides",
]
@@ -475,10 +475,10 @@ def __call__(self, inst, attr, value):
)

def __repr__(self):
return "<maxlen validator for {max}>".format(max=self.max_length)
return "<max_len validator for {max}>".format(max=self.max_length)


def maxlen(length):
def max_len(length):
"""
A validator that raises `ValueError` if the initializer is called
with a string or iterable that is longer than *length*.
2 changes: 1 addition & 1 deletion src/attr/validators.pyi
Original file line number Diff line number Diff line change
@@ -69,4 +69,4 @@ def lt(val: _T) -> _ValidatorType[_T]: ...
def le(val: _T) -> _ValidatorType[_T]: ...
def ge(val: _T) -> _ValidatorType[_T]: ...
def gt(val: _T) -> _ValidatorType[_T]: ...
def maxlen(length: int) -> _ValidatorType[_T]: ...
def max_len(length: int) -> _ValidatorType[_T]: ...
24 changes: 12 additions & 12 deletions tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@
le,
lt,
matches_re,
maxlen,
max_len,
optional,
provides,
)
@@ -718,7 +718,7 @@ def test_hashability():

class TestLtLeGeGt:
"""
Tests for `maxlen`.
Tests for `max_len`.
"""

BOUND = 4
@@ -794,9 +794,9 @@ def test_repr(self, v):
)


class TestMaxlen:
class TestMaxLen:
"""
Tests for `maxlen`.
Tests for `max_len`.
"""

MAX_LENGTH = 4
@@ -805,16 +805,16 @@ def test_in_all(self):
"""
validator is in ``__all__``.
"""
assert maxlen.__name__ in validator_module.__all__
assert max_len.__name__ in validator_module.__all__

def test_retrieve_maxlen(self):
def test_retrieve_max_len(self):
"""
The configured max. length can be extracted from the Attribute
"""

@attr.s
class Tester(object):
value = attr.ib(validator=maxlen(self.MAX_LENGTH))
value = attr.ib(validator=max_len(self.MAX_LENGTH))

assert fields(Tester).value.validator.max_length == self.MAX_LENGTH

@@ -831,13 +831,13 @@ class Tester(object):
)
def test_check_valid(self, value):
"""
Silent if len(value) <= maxlen.
Silent if len(value) <= max_len.
Values can be strings and other iterables.
"""

@attr.s
class Tester(object):
value = attr.ib(validator=maxlen(self.MAX_LENGTH))
value = attr.ib(validator=max_len(self.MAX_LENGTH))

Tester(value) # shouldn't raise exceptions

@@ -850,12 +850,12 @@ class Tester(object):
)
def test_check_invalid(self, value):
"""
Raise ValueError if len(value) > maxlen.
Raise ValueError if len(value) > max_len.
"""

@attr.s
class Tester(object):
value = attr.ib(validator=maxlen(self.MAX_LENGTH))
value = attr.ib(validator=max_len(self.MAX_LENGTH))

with pytest.raises(ValueError):
Tester(value)
@@ -864,4 +864,4 @@ def test_repr(self):
"""
__repr__ is meaningful.
"""
assert repr(maxlen(23)) == "<maxlen validator for 23>"
assert repr(max_len(23)) == "<max_len validator for 23>"