From fb02aa8aa17ce2c18b1ef4e8fc119dcce9b8630b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 8 Sep 2025 15:04:38 +0000 Subject: [PATCH 1/4] pytypes.h: constrain accessor::operator= templates so that they do not match calls that should use the special member functions. Found by an experimental, new clang-tidy check. While we may not know the exact design decisions now, it seems unlikely that the special members were deliberately meant to not be selected (for otherwise they could have been defined differently to make this clear). Rather, it seems like an oversight that the operator templates win in overload resolution, and we should restore the intended resolution. --- include/pybind11/pytypes.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 9c60c94c04..8d95ef2047 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1039,11 +1039,13 @@ class accessor : public object_api> { void operator=(const accessor &a) & { operator=(handle(a)); } template - void operator=(T &&value) && { + std::enable_if_t>> + operator=(T &&value) && { Policy::set(obj, key, object_or_cast(std::forward(value))); } template - void operator=(T &&value) & { + std::enable_if_t>> + operator=(T &&value) & { get_cache() = ensure_object(object_or_cast(std::forward(value))); } From c3d9be4e0db4a5efe3720ce3043cdfa4de0bdd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 8 Sep 2025 16:24:21 +0000 Subject: [PATCH 2/4] Use C++11-compatible facilities --- include/pybind11/pytypes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 8d95ef2047..af7763a149 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1039,12 +1039,12 @@ class accessor : public object_api> { void operator=(const accessor &a) & { operator=(handle(a)); } template - std::enable_if_t>> + std::enable_if_t>::value> operator=(T &&value) && { Policy::set(obj, key, object_or_cast(std::forward(value))); } template - std::enable_if_t>> + std::enable_if_t>::value> operator=(T &&value) & { get_cache() = ensure_object(object_or_cast(std::forward(value))); } From 363c945b0eb2f8c0ee902421871581aacb4220af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Mon, 8 Sep 2025 15:04:38 +0000 Subject: [PATCH 3/4] Use C++11-compatible facilities --- include/pybind11/pytypes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index af7763a149..62830e13cf 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1039,12 +1039,12 @@ class accessor : public object_api> { void operator=(const accessor &a) & { operator=(handle(a)); } template - std::enable_if_t>::value> + enable_if_t>::value> operator=(T &&value) && { Policy::set(obj, key, object_or_cast(std::forward(value))); } template - std::enable_if_t>::value> + enable_if_t>::value> operator=(T &&value) & { get_cache() = ensure_object(object_or_cast(std::forward(value))); } From 4e9434a833cc3f7f3c89c5ecb0d7f6552ac7ac17 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:43:30 +0000 Subject: [PATCH 4/4] style: pre-commit fixes --- include/pybind11/pytypes.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 62830e13cf..cee4ab5623 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1039,13 +1039,11 @@ class accessor : public object_api> { void operator=(const accessor &a) & { operator=(handle(a)); } template - enable_if_t>::value> - operator=(T &&value) && { + enable_if_t>::value> operator=(T &&value) && { Policy::set(obj, key, object_or_cast(std::forward(value))); } template - enable_if_t>::value> - operator=(T &&value) & { + enable_if_t>::value> operator=(T &&value) & { get_cache() = ensure_object(object_or_cast(std::forward(value))); }