-
-
Notifications
You must be signed in to change notification settings - Fork 125
Open
Labels
Description
python version: 3.13.7
attrs version: 25.4.0
cattrs version 25.3.0
When I try to structure a dict into a class, I only see a validation error from one field, when I would expect to see multiple.
Example:
import attrs
import cattrs
@attrs.define()
class Foo:
a: str = attrs.field(validator=[attrs.validators.min_len(3)])
b: str = attrs.field(validator=[attrs.validators.min_len(3)])
cattrs.structure(
{"a": "a", "b": "b"},
Foo,
)I am expecting to see validation errors from fields a and b, but only see a:
Traceback (most recent call last):
File "<cattrs generated structure __main__.Foo>", line 16, in structure_Foo
return __cl(
**res,
)
File "<attrs generated methods __main__.Foo>", line 28, in __init__
__attr_validator_a(self, __attr_a, self.a)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.13/site-packages/attr/_make.py", line 3279, in __call__
v(inst, attr, value)
~^^^^^^^^^^^^^^^^^^^
File ".venv/lib/python3.13/site-packages/attr/validators.py", line 575, in __call__
raise ValueError(msg)
ValueError: Length of 'a' must be >= 3: 1
During handling of the above exception, another exception occurred:
+ Exception Group Traceback (most recent call last):
| File "/home/lincoln/.config/JetBrains/PyCharm2025.2/scratches/scratch_2.py", line 12, in <module>
| cattrs.structure(
| ~~~~~~~~~~~~~~~~^
| {"a": "a", "b": "b"},
| ^^^^^^^^^^^^^^^^^^^^^
| Foo,
| ^^^^
| )
| ^
| File ".venv/lib/python3.13/site-packages/cattrs/converters.py", line 589, in structure
| return self._structure_func.dispatch(cl)(obj, cl)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
| File "<cattrs generated structure __main__.Foo>", line 19, in structure_Foo
| except Exception as exc: raise __c_cve('While structuring ' + 'Foo', [exc], __cl)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| cattrs.errors.ClassValidationError: While structuring Foo (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "<cattrs generated structure __main__.Foo>", line 16, in structure_Foo
| return __cl(
| **res,
| )
| File "<attrs generated methods __main__.Foo>", line 28, in __init__
| __attr_validator_a(self, __attr_a, self.a)
| ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
| File ".venv/lib/python3.13/site-packages/attr/_make.py", line 3279, in __call__
| v(inst, attr, value)
| ~^^^^^^^^^^^^^^^^^^^
| File ".venv/lib/python3.13/site-packages/attr/validators.py", line 575, in __call__
| raise ValueError(msg)
| ValueError: Length of 'a' must be >= 3: 1
+------------------------------------
Plus when I pass that exception to cattrs.transform_exception the output list is
['invalid value @ $']which seems lacking on detail of where the validation error happened.
I am expecting to see multiple because the docs say
When structuring a class, cattrs will gather any exceptions on a field-by-field basis and raise them as a cattrs.ClassValidationError, which is a subclass of BaseValidationError.
I am doing something wrong, or this not a feature of cattrs?