diff --git a/HISTORY.md b/HISTORY.md index 156d50a6..a87b2888 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,6 +11,11 @@ The third number is for emergencies when we need to start branches for older rel Our backwards-compatibility policy can be found [here](https://github.com/python-attrs/cattrs/blob/main/.github/SECURITY.md). +## NEXT + +- Fix the `detailed_validation` parameter being passed under the wrong name in {func}`namedtuple_dict_structure_factory `, causing it to be silently ignored. + ([#723](https://github.com/python-attrs/cattrs/pull/723)) + ## 26.1.0 (2026-02-18) - Add the {mod}`tomllib ` preconf converter. diff --git a/src/cattrs/cols.py b/src/cattrs/cols.py index 64e4f2c7..d1d22ee8 100644 --- a/src/cattrs/cols.py +++ b/src/cattrs/cols.py @@ -277,7 +277,7 @@ def namedtuple_dict_structure_factory( cl, converter, _cattrs_forbid_extra_keys=forbid_extra_keys, - _cattrs_use_detailed_validation=detailed_validation, + _cattrs_detailed_validation=detailed_validation, _cattrs_use_linecache=use_linecache, **kwargs, ) diff --git a/tests/test_tuples.py b/tests/test_tuples.py index 4fcfd85e..0877ebfa 100644 --- a/tests/test_tuples.py +++ b/tests/test_tuples.py @@ -141,3 +141,31 @@ class Test(NamedTuple): assert isinstance(exc, ForbiddenExtraKeysError) assert exc.extra_fields == {"b"} + + +def test_dict_namedtuples_detailed_validation(): + """Passing detailed_validation to namedtuple_dict_structure_factory works. + + Regression test for the parameter being passed under the wrong name. + """ + + class Test(NamedTuple): + a: int + + # Create a converter that does NOT use detailed validation by default. + c = Converter(detailed_validation=False) + + # But explicitly enable it in the factory. + c.register_structure_hook_factory( + lambda t: t is Test, + lambda t, conv: namedtuple_dict_structure_factory( + t, conv, detailed_validation=True + ), + ) + + # With detailed validation, structuring errors should be wrapped + # in a ClassValidationError instead of being raised directly. + from cattrs.errors import ClassValidationError + + with raises(ClassValidationError): + c.structure({"a": "not_an_int"}, Test)