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
See also [PR #5533](pybind/pybind11#5533). PiperOrigin-RevId: 886714838 Change-Id: I8c98461098ccf4958fb18bdcb5acc293c988c258
pybind11 prohibits keep_alive inside def_property_readonly. The correct equivalent for 'return reference + keep parent alive' is py::return_value_policy::reference_internal. Fixes google#5140 See: pybind/pybind11#5533
* set install directories depending on target type * set rpath for tests * set rpath for python bindings * set install dirs of the C lib * set install dirs of the fortran lib * update python and library paths in the CI * set c mpi lib install path * fix python binary module install paths and rpaths * update PYTHONPATH for the windows CI * Revert "update PYTHONPATH for the windows CI" This reverts commit 4e452ba. * debug print * remove direct compiler flags specifying the cpp standard * update pybind11 to version 3.0.4 * ignore clangd configuration * pybind11::module => pybind11::module_ * wrap python bindings of iterator ranges into pybind11::cpp_functions (see pybind/pybind11#5533) * explicit template argument for pybind11 holder type * debug * indicate which version of python is used for running tests on rocky * / => \ on windows * install on rocky before running tests * point PYTHONPATH to the install dir on windows * the rocky docker image relies on /etc/bashrc?? * special treatment for pybind modules on windows * kratos' rocky image needs /etc/local/bin, try sourcing /etc/profile instead of /etc/bashrc * sh => bash * give up on sourcing the fucking profile and extend PATH manually * maybe the rocky image got silently updated?w * yes, the rocky image did get silently updated, and python3.8 was replaced with python3.10, instead of installing the dev package for the system's default python3. wow. I'm never going to touch this piece of shit image again. If Altair updates their docker image, it's their job to fix this crap. * drop intel mpi from the CI * trigger CI
pyrealsense2 fails to build with pybind11 v3.0.2 Build error log: https://cache.nixos.org/log/kcry0khph8g0crka6zzkznn8izfvsrq1-librealsense-2.56.3.drv Cause: pybind/pybind11#5533 I based this fix on NGSolve/netgen@ceacae3 I'm not very familiar with pybind11, please double check whether this fix is correct.
pyrealsense2 fails to build with pybind11 v3.0.2 Build error log: https://cache.nixos.org/log/kcry0khph8g0crka6zzkznn8izfvsrq1-librealsense-2.56.3.drv Cause: pybind/pybind11#5533 I based this fix on NGSolve/netgen@ceacae3 I'm not very familiar with pybind11, please double check whether this fix is correct.
…erationConfig (openvinotoolkit#3915) ## Description The `py::keep_alive<1, 2>()` policy is no longer supported with pybind11's `def_readwrite()` method ([link](pybind/pybind11#5533)), causing a static assertion failure during compilation. This policy is unnecessary as pybind11 automatically handles lifetime management for `def_readwrite` attributes. This is similar to the error fixed by this PR in OpenVINO: openvinotoolkit/openvino#34468 I've tested that this fixes compatibility with pybind11 when building Python bindings for OpenVINO GenAI 2026.1.0.0. To reproduce the error (building environment: Ubuntu 24.04), build OpenVINO GenAI as an extra module: ``` git clone --branch 2026.1.0 --recursive https://github.com/openvinotoolkit/openvino.git git clone --branch 2026.1.0.0 --recursive https://github.com/openvinotoolkit/openvino.genai.git cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/install -DENABLE_PYTHON=ON -DPython3_EXECUTABLE=/usr/bin/python3.12 -DOPENVINO_EXTRA_MODULES=$(pwd)/openvino.genai -DCPACK_ARCHIVE_COMPONENT_INSTALL=OFF -S ./openvino -B ./build cmake --build ./build -j . . In file included from /home/ubuntu/openvino-genai-python/openvino.genai/src/python/py_generation_config.cpp:5: /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_static(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::is_method, pybind11::return_value_policy, pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’: /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2438:35: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::return_value_policy, pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’ /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2347:21: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = ov::genai::GenerationConfig; D = std::vector<std::shared_ptr<ov::genai::Parser> >; Extra = {pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’ /home/ubuntu/openvino-genai-python/openvino.genai/src/python/py_generation_config.cpp:450:23: required from here /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2462:25: error: static assertion failed: def_property family does not currently support keep_alive. Use a py::cpp_function instead. 2462 | static_assert(0 == detail::constexpr_sum(detail::is_keep_alive<Extra>::value...), | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2462:25: note: the comparison reduces to ‘(0 == 1)’ gmake[2]: *** [build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/build.make:104: build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/py_generation_config.cpp.o] Error 1 gmake[1]: *** [CMakeFiles/Makefile2:9712: build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/all] Error 2 gmake: *** [Makefile:156: all] Error 2 ``` ## Checklist: - [x] This PR follows [GenAI Contributing guidelines](https://github.com/openvinotoolkit/openvino.genai?tab=contributing-ov-file#contributing). <!-- Always follow them. If there are deviations, explain what and why. --> - [ ] Tests have been updated or added to cover the new code. <!-- Specify exactly which tests were added or updated. If the change isn't maintenance related, update the tests at https://github.com/openvinotoolkit/openvino.genai/tree/master/tests or explain in the description why the tests don't need an update. --> - [ ] This PR fully addresses the ticket. <!--- If not, explain clearly what is covered and what is not. If follow-up pull requests are needed, specify in the description. --> - [ ] I have made corresponding changes to the documentation. <!-- Run github.com/\<username>/openvino.genai/actions/workflows/deploy_gh_pages.yml on your fork with your branch as a parameter to deploy a test version with the updated content. Replace this comment with the link to the built docs. If the documentation is updated in a separate PR, clearly specify it. --> Co-authored-by: Pavel Esir <pavel.esir@gmail.com> Co-authored-by: Alexander Suvorov <alexander.suvorov@intel.com>
…erationConfig (openvinotoolkit#3915) ## Description The `py::keep_alive<1, 2>()` policy is no longer supported with pybind11's `def_readwrite()` method ([link](pybind/pybind11#5533)), causing a static assertion failure during compilation. This policy is unnecessary as pybind11 automatically handles lifetime management for `def_readwrite` attributes. This is similar to the error fixed by this PR in OpenVINO: openvinotoolkit/openvino#34468 I've tested that this fixes compatibility with pybind11 when building Python bindings for OpenVINO GenAI 2026.1.0.0. To reproduce the error (building environment: Ubuntu 24.04), build OpenVINO GenAI as an extra module: ``` git clone --branch 2026.1.0 --recursive https://github.com/openvinotoolkit/openvino.git git clone --branch 2026.1.0.0 --recursive https://github.com/openvinotoolkit/openvino.genai.git cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/install -DENABLE_PYTHON=ON -DPython3_EXECUTABLE=/usr/bin/python3.12 -DOPENVINO_EXTRA_MODULES=$(pwd)/openvino.genai -DCPACK_ARCHIVE_COMPONENT_INSTALL=OFF -S ./openvino -B ./build cmake --build ./build -j . . In file included from /home/ubuntu/openvino-genai-python/openvino.genai/src/python/py_generation_config.cpp:5: /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_static(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::is_method, pybind11::return_value_policy, pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’: /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2438:35: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...) [with Extra = {pybind11::return_value_policy, pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’ /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2347:21: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_readwrite(const char*, D C::*, const Extra& ...) [with C = ov::genai::GenerationConfig; D = std::vector<std::shared_ptr<ov::genai::Parser> >; Extra = {pybind11::keep_alive<1, 2>}; type_ = ov::genai::GenerationConfig; options = {}]’ /home/ubuntu/openvino-genai-python/openvino.genai/src/python/py_generation_config.cpp:450:23: required from here /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2462:25: error: static assertion failed: def_property family does not currently support keep_alive. Use a py::cpp_function instead. 2462 | static_assert(0 == detail::constexpr_sum(detail::is_keep_alive<Extra>::value...), | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/ubuntu/openvino-genai-python/openvino/src/bindings/python/thirdparty/pybind11/include/pybind11/pybind11.h:2462:25: note: the comparison reduces to ‘(0 == 1)’ gmake[2]: *** [build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/build.make:104: build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/py_generation_config.cpp.o] Error 1 gmake[1]: *** [CMakeFiles/Makefile2:9712: build-modules/openvino.genai/src/python/CMakeFiles/py_openvino_genai.dir/all] Error 2 gmake: *** [Makefile:156: all] Error 2 ``` ## Checklist: - [x] This PR follows [GenAI Contributing guidelines](https://github.com/openvinotoolkit/openvino.genai?tab=contributing-ov-file#contributing). <!-- Always follow them. If there are deviations, explain what and why. --> - [ ] Tests have been updated or added to cover the new code. <!-- Specify exactly which tests were added or updated. If the change isn't maintenance related, update the tests at https://github.com/openvinotoolkit/openvino.genai/tree/master/tests or explain in the description why the tests don't need an update. --> - [ ] This PR fully addresses the ticket. <!--- If not, explain clearly what is covered and what is not. If follow-up pull requests are needed, specify in the description. --> - [ ] I have made corresponding changes to the documentation. <!-- Run github.com/\<username>/openvino.genai/actions/workflows/deploy_gh_pages.yml on your fork with your branch as a parameter to deploy a test version with the updated content. Replace this comment with the link to the built docs. If the documentation is updated in a separate PR, clearly specify it. --> Co-authored-by: Pavel Esir <pavel.esir@gmail.com> Co-authored-by: Alexander Suvorov <alexander.suvorov@intel.com>


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: