From 19b678f50831189c3206a612d16bdc7e4084e013 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/3] 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 fca1f9513a0079e36048b0c10a0439434f3551f3 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/3] 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 | 2 ++ tests/test_tuples.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index f8f7df14..452e7b7e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -15,6 +15,8 @@ Our backwards-compatibility policy can be found [here](https://github.com/python - Fix an `AttributeError` in `cattrs` internals that could be triggered by using the `include_subclasses` strategy in a `structure_hook_factory` ([#721](https://github.com/python-attrs/cattrs/issues/721), [#722](https://github.com/python-attrs/cattrs/pull/722)) +- 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) 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) From 5fd1c7f89f6c5f19b91cc5f2758a0fbf7740730b Mon Sep 17 00:00:00 2001 From: Tin Tvrtkovic Date: Wed, 4 Mar 2026 00:23:52 +0100 Subject: [PATCH 3/3] Fix namedtuple validation test --- tests/test_tuples.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/test_tuples.py b/tests/test_tuples.py index 0877ebfa..c1a9562c 100644 --- a/tests/test_tuples.py +++ b/tests/test_tuples.py @@ -11,7 +11,7 @@ namedtuple_dict_unstructure_factory, ) from cattrs.converters import Converter -from cattrs.errors import ForbiddenExtraKeysError +from cattrs.errors import ClassValidationError, ForbiddenExtraKeysError def test_simple_hetero_tuples(genconverter: Converter): @@ -158,14 +158,11 @@ class Test(NamedTuple): # 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 - ), + lambda t, conv: namedtuple_dict_structure_factory(t, conv, 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)