Skip to content

Commit 7c61275

Browse files
authored
Merge pull request #254 from joe733/workshop
feat: @validator now catches `Exception`
2 parents e04b4e1 + 5982057 commit 7c61275

File tree

10 files changed

+137
-185
lines changed

10 files changed

+137
-185
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ True
1616

1717
## Resources
1818

19-
- [Documentation](https://python-validators.github.io/)
19+
- [Documentation](https://python-validators.github.io/validators/)
2020
- [Issue Tracker](https://github.com/python-validators/validators/issues)
2121
- [Security](https://github.com/python-validators/validators/blob/master/SECURITY.md)
2222
- [Code](https://github.com/python-validators/validators/)

docs/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ True
1616

1717
## Resources
1818

19-
- [Documentation](https://python-validators.github.io/)
19+
- [Documentation](https://python-validators.github.io/validators/)
2020
- [Issue Tracker](https://github.com/python-validators/validators/issues)
2121
- [Security](https://github.com/python-validators/validators/blob/master/SECURITY.md)
2222
- [Code](https://github.com/python-validators/validators/)

mkdocs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
site_name: "validators"
22
site_description: "Automatic documentation from sources, for MkDocs."
3-
site_url: "https://python-validators.github.io/"
3+
site_url: "https://python-validators.github.io/validators/"
44
repo_url: "https://github.com/python-validators/validators"
55
edit_uri: "tree/master/docs/"
66
repo_name: "validators/validators"

poetry.lock

+99-128
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ classifiers = [
2222
"Programming Language :: Python :: Implementation :: CPython",
2323
"Topic :: Software Development :: Libraries :: Python Modules",
2424
]
25-
include = ["CHANGES.md", "docs/*"]
25+
include = ["CHANGES.md", "docs/*", "validators/py.typed"]
2626

2727
[tool.poetry.dependencies]
2828
python = "^3.8"
@@ -50,7 +50,7 @@ black = "^23.1.0"
5050
flake8 = "^5.0.4"
5151
flake8-docstrings = "^1.7.0"
5252
isort = "^5.12.0"
53-
pyright = "^1.1.299"
53+
pyright = "^1.1.300"
5454

5555
[build-system]
5656
requires = ["poetry-core"]

tests/test_between.py

+5-22
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,19 @@ def test_returns_true_on_valid_range(value: T, min_val: T, max_val: T):
2323
assert between(value, min_val=min_val, max_val=max_val)
2424

2525

26-
@pytest.mark.parametrize(
27-
("value", "min_val", "max_val"),
28-
[(12, 13, 12), (12, None, None)],
29-
)
30-
def test_raises_assertion_error_for_invalid_args(value: T, min_val: T, max_val: T):
31-
"""Test raises assertion error for invalid args."""
32-
with pytest.raises(AssertionError):
33-
assert between(value, min_val=min_val, max_val=max_val)
34-
35-
3626
@pytest.mark.parametrize(
3727
("value", "min_val", "max_val"),
3828
[
29+
(12, 13, 14),
30+
(12, None, 11),
31+
(12, None, None),
32+
(12, 13, None),
3933
(12, "13.5", datetime(1970, 1, 1)),
4034
("12", 20.5, "None"),
4135
(datetime(1970, 1, 1), 20, "string"),
4236
(30, 40, "string"),
4337
],
4438
)
45-
def test_raises_type_error_for_invalid_args(value: T, min_val: T, max_val: T):
46-
"""Test raises type error for invalid args."""
47-
with pytest.raises(TypeError):
48-
assert between(value, min_val=min_val, max_val=max_val)
49-
50-
51-
@pytest.mark.parametrize(
52-
("value", "min_val", "max_val"),
53-
[(12, 13, 14), (12, None, 11), (12, 13, None)],
54-
)
5539
def test_returns_failed_validation_on_invalid_range(value: T, min_val: T, max_val: T):
5640
"""Test returns failed validation on invalid range."""
57-
result = between(value, min_val=min_val, max_val=max_val)
58-
assert isinstance(result, ValidationFailure)
41+
assert isinstance(between(value, min_val=min_val, max_val=max_val), ValidationFailure)

tests/test_length.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,7 @@ def test_returns_true_on_valid_length(value: str, min_val: int, max_val: int):
1919

2020
@pytest.mark.parametrize(
2121
("value", "min_val", "max_val"),
22-
[("something", 14, 12), ("something", -10, -20), ("something", 0, -2)],
23-
)
24-
def test_raises_assertion_error_for_invalid_args(value: str, min_val: int, max_val: int):
25-
"""Test raises assertion error for invalid args."""
26-
with pytest.raises(AssertionError):
27-
assert length(value, min_val=min_val, max_val=max_val)
28-
29-
30-
@pytest.mark.parametrize(
31-
("value", "min_val", "max_val"),
32-
[("something", 13, 14), ("something", 0, 6), ("something", 14, 20)],
22+
[("something", 14, 12), ("something", -10, -20), ("something", 0, -2), ("something", 13, 14)],
3323
)
3424
def test_returns_failed_validation_on_invalid_range(value: str, min_val: int, max_val: int):
3525
"""Test returns failed validation on invalid range."""

validators/between.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def between(
5858
If `value` is not in between the given conditions.
5959
6060
Raises:
61-
AssertionError: If both `min_val` and `max_val` are `None`,
61+
ValueError: If both `min_val` and `max_val` are `None`,
6262
or if `min_val` is greater than `max_val`.
6363
TypeError: If there's a type mismatch before comparison.
6464
@@ -68,29 +68,32 @@ def between(
6868
6969
> *New in version 0.2.0*.
7070
"""
71+
if not value:
72+
return False
73+
7174
if min_val is None and max_val is None:
72-
raise AssertionError("At least one of either `min_val` or `max_val` must be specified")
75+
raise ValueError("At least one of either `min_val` or `max_val` must be specified")
7376

7477
if max_val is None:
7578
max_val = AbsMax()
7679
if min_val is None:
7780
min_val = AbsMin()
7881

7982
if isinstance(min_val, AbsMin):
80-
if type(value) is not type(max_val):
81-
raise TypeError("`value` and `max_val` must be of same type")
82-
return min_val <= value <= max_val
83+
if type(value) is type(max_val):
84+
return min_val <= value <= max_val
85+
raise TypeError("`value` and `max_val` must be of same type")
8386

8487
if isinstance(max_val, AbsMax):
85-
if type(value) is not type(min_val):
86-
raise TypeError("`value` and `min_val` must be of same type")
87-
return min_val <= value <= max_val
88+
if type(value) is type(min_val):
89+
return min_val <= value <= max_val
90+
raise TypeError("`value` and `min_val` must be of same type")
8891

8992
if type(min_val) is type(max_val):
9093
if min_val > max_val:
91-
raise AssertionError("`min_val` cannot be more than `max_val`")
92-
if type(value) is not type(min_val): # or type(max_val):
93-
raise TypeError("`value` and (`min_val` or `max_val`) must be of same type")
94-
return min_val <= value <= max_val
94+
raise ValueError("`min_val` cannot be more than `max_val`")
95+
if type(value) is type(min_val): # or is type(max_val)
96+
return min_val <= value <= max_val
97+
raise TypeError("`value` and (`min_val` or `max_val`) must be of same type")
9598

9699
raise TypeError("`value` and `min_val` and `max_val` must be of same type")

validators/py.typed

Whitespace-only changes.

validators/utils.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
class ValidationFailure(Exception):
1212
"""Exception class when validation failure occurs."""
1313

14-
def __init__(self, function: Callable[..., Any], arg_dict: Dict[str, Any]):
14+
def __init__(self, function: Callable[..., Any], arg_dict: Dict[str, Any], message: str = ""):
1515
"""Initialize Validation Failure."""
16+
if message:
17+
self.reason = message
1618
self.func = function
1719
self.__dict__.update(arg_dict)
1820

@@ -60,7 +62,7 @@ def validator(func: Callable[..., Any]):
6062
Function which is to be decorated.
6163
6264
Returns:
63-
(Callable[..., ValidationFailure | Literal[True])):
65+
(Callable[..., ValidationFailure | Literal[True]]):
6466
A decorator which returns either `ValidationFailure`
6567
or `Literal[True]`.
6668
@@ -69,10 +71,13 @@ def validator(func: Callable[..., Any]):
6971

7072
@wraps(func)
7173
def wrapper(*args: Any, **kwargs: Any):
72-
return (
73-
True
74-
if func(*args, **kwargs)
75-
else ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs))
76-
)
74+
try:
75+
return (
76+
True
77+
if func(*args, **kwargs)
78+
else ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs))
79+
)
80+
except Exception as exp:
81+
return ValidationFailure(func, _func_args_as_dict(func, *args, **kwargs), str(exp))
7782

7883
return wrapper

0 commit comments

Comments
 (0)