From af796d0a99f0cbd9aebb10591257c41a56811cf6 Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Sat, 15 Nov 2025 16:53:15 +0000 Subject: [PATCH] Don't allow keep_alive or call_guard on properties (#5533) * Don't allow keep_alive or call_guard on properties The def_property family blindly ignore the keep_alive and call_guard arguments passed to them making them confusing to use. This adds a static_assert if either is passed to make it clear it doesn't work. I would prefer this to be a compiler warning but I can't find a way to do that. Is that even possible? * style: pre-commit fixes * Re-run tests --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/pybind11/attr.h | 6 ++++++ include/pybind11/pybind11.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 9b631fa48..f902c7c60 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -702,6 +702,12 @@ struct process_attributes { } }; +template +struct is_keep_alive : std::false_type {}; + +template +struct is_keep_alive> : std::true_type {}; + template using is_call_guard = is_instantiation; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 5cc9e9e1c..60db0a087 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2430,6 +2430,12 @@ public: const Extra &...extra) { static_assert(0 == detail::constexpr_sum(std::is_base_of::value...), "Argument annotations are not allowed for properties"); + static_assert(0 == detail::constexpr_sum(detail::is_call_guard::value...), + "def_property family does not currently support call_guard. Use a " + "py::cpp_function instead."); + static_assert(0 == detail::constexpr_sum(detail::is_keep_alive::value...), + "def_property family does not currently support keep_alive. Use a " + "py::cpp_function instead."); auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset); auto *rec_active = rec_fget; if (rec_fget) {