|
1 | 1 | # Validation
|
2 | 2 |
|
3 |
| -_cattrs_ has a detailed validation mode since version 22.1.0, and this mode is enabled by default. |
4 |
| -When running under detailed validation, the structuring hooks are slightly slower but produce richer and more precise error messages. |
5 |
| -Unstructuring hooks are not affected. |
| 3 | +_cattrs_ supports _structuring_ since its initial release, and _validation_ since release 24.1. |
| 4 | + |
| 5 | +**Structuring** is the process of ensuring data matches a set of Python types; |
| 6 | +it can be thought of as validating data against structural constraints. |
| 7 | +Structuring ensures the shape of your data. |
| 8 | +Structuring ensures data typed as `list[int]` really contains a list of integers. |
| 9 | + |
| 10 | +**Validation** is the process of ensuring data matches a set of user-provided constraints; |
| 11 | +it can be thought of as validating the value of data. |
| 12 | +Validation happens after the shape of the data has been ensured. |
| 13 | +Validation can ensure a `list[int]` contains at least one integer, and that all integers are positive. |
| 14 | + |
| 15 | +## (Value) Validation |
| 16 | + |
| 17 | +```{versionadded} 24.1.0 |
| 18 | +
|
| 19 | +``` |
| 20 | +```{note} _This API is still provisional; as such it is subject to breaking changes._ |
| 21 | +
|
| 22 | +``` |
| 23 | + |
| 24 | +_cattrs_ can be configured to validate the values of your data (ensuring a list of integers has at least one member, and that all elements are positive). |
| 25 | + |
| 26 | +The basic unit of value validation is a function that takes a value and, if the value is unacceptable, either raises an exception or returns exactly `False`. |
| 27 | +These functions are called _validators_. |
| 28 | + |
| 29 | +The attributes of _attrs_ classes can be validated with the use of a helper function, {func}`cattrs.v.customize`, and a helper class, {class}`cattrs.v.V`. |
| 30 | +_V_ is the validation attribute, mapping to _attrs_ or _dataclass_ attributes. |
| 31 | + |
| 32 | +```python |
| 33 | +from attrs import define |
| 34 | +from cattrs import Converter |
| 35 | +from cattrs.v import customize, V |
| 36 | + |
| 37 | +@define |
| 38 | +class C: |
| 39 | + a: int |
| 40 | + |
| 41 | +converter = Converter() |
| 42 | + |
| 43 | +customize(converter, C, V("a").ensure(lambda a: a > 0)) |
| 44 | +``` |
| 45 | + |
| 46 | +Now, every structuring of class `C` will run the provided validator(s). |
| 47 | + |
| 48 | +```python |
| 49 | +converter.structure({"a": -1}, C) |
| 50 | +``` |
| 51 | + |
| 52 | +This process also works with dataclasses: |
| 53 | + |
| 54 | +```python |
| 55 | +from dataclasses import dataclass |
| 56 | + |
| 57 | +@dataclass |
| 58 | +class D: |
| 59 | + a: int |
| 60 | + |
| 61 | +customize(converter, D, V("a").ensure(lambda a: a == 5)) |
| 62 | +``` |
6 | 63 |
|
7 | 64 | ## Detailed Validation
|
8 | 65 |
|
9 | 66 | ```{versionadded} 22.1.0
|
10 | 67 |
|
11 | 68 | ```
|
| 69 | +Detailed validation is enabled by default and can be disabled for a speed boost by creating a converter with `detailed_validation=False`. |
| 70 | +When running under detailed validation, the structuring hooks are slightly slower but produce richer and more precise error messages. |
| 71 | +Unstructuring hooks are not affected. |
| 72 | + |
12 | 73 | In detailed validation mode, any structuring errors will be grouped and raised together as a {class}`cattrs.BaseValidationError`, which is a [PEP 654 ExceptionGroup](https://www.python.org/dev/peps/pep-0654/).
|
13 | 74 | ExceptionGroups are special exceptions which contain lists of other exceptions, which may themselves be other ExceptionGroups.
|
14 | 75 | In essence, ExceptionGroups are trees of exceptions.
|
|
0 commit comments