From 787e7d320416d9c93e66c9f92c8b2bde54e07268 Mon Sep 17 00:00:00 2001 From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:28:59 +0300 Subject: [PATCH 1/2] Fix wrong parameter name in namedtuple_dict_structure_factory The call to make_dict_structure_fn_from_attrs passes _cattrs_use_detailed_validation but the function expects _cattrs_detailed_validation. Because **kwargs catches the misnamed parameter as an attribute override, detailed_validation is silently ignored and always falls back to the converter default. --- src/cattrs/cols.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, ) From adaa39939db35eb60b372d05903c745c56dc57a1 Mon Sep 17 00:00:00 2001 From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:51:44 +0300 Subject: [PATCH 2/2] Add regression test and changelog for namedtuple detailed_validation fix Add a test that verifies the detailed_validation parameter passed to namedtuple_dict_structure_factory is actually used and not silently ignored. Also add a HISTORY.md entry for the fix. --- HISTORY.md | 5 +++++ tests/test_tuples.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) 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/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)