From 5657ab11de67d6a8eb6a25e2d869b0fd343eda0d Mon Sep 17 00:00:00 2001 From: gentlegiantJGC Date: Tue, 18 Feb 2025 12:27:03 +0000 Subject: [PATCH] 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? --- include/pybind11/attr.h | 6 ++++++ include/pybind11/pybind11.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 1044db94d..742a2fc40 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -670,6 +670,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 4387c2754..e2dddb9f0 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1849,6 +1849,10 @@ 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) {