Don't allow keep_alive or call_guard on properties#5533
Conversation
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?
|
(random timing, I'm cleaning up my email backlog) Looks good, thanks! — 'll get back here a few days after #5542 is merged, but before the v3.0.0 release. |
|
Looks like this got missed |
|
Oh, sorry. Could you please update this branch and tag me if you see that the CI passed? |
|
I think the android runner is broken. This is also an issue in #5896 |
|
Ignoring, after two unsuccessful reruns: CIBW / Android wheel ubuntu-latest (pull_request) (pull_request)Failing after 10m |
|
@gentlegiantJGC Thank you so much for the guard rails! Just to check the update path for this: should we use a syntax with |
The only cases this change should break are cases where |
error: static assertion failed: def_property family does not currently support call_guard. Use a py::cpp_function instead. See pybind/pybind11#5533


Description
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?
This does not fix - #4236 or #5046 but makes it clear that they don't work.
Workaround
If your property returns a reference, pybind11 will automatically link the lifespan of self to the return value.
See
return_value_policy::reference_internaldoc for more info..def_property("foo", &Obj::getFoo, &Obj::setFoo).def_readwrite("foo", &Obj::foo)If you need a custom
keep_aliveorcall_guardthese can be passed intopy::cpp_function.def_property( "foo", py::cpp_function(&Obj::getFoo, py::call_guard<py::gil_scoped_release>()), py::cpp_function(&Obj::setFoo, py::call_guard<py::gil_scoped_release>()))Suggested changelog entry: