From 39e09b7301b9678a194b2c7db1a302e0c9f54d09 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 24 Mar 2023 08:52:18 -0700 Subject: [PATCH 1/2] Files copied from pywrapcc test_class_sh_property_stl.cpp,py --- tests/test_property_stl.cpp | 51 +++++++++++++++++++++++++++++++++++++ tests/test_property_stl.py | 31 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 tests/test_property_stl.cpp create mode 100644 tests/test_property_stl.py diff --git a/tests/test_property_stl.cpp b/tests/test_property_stl.cpp new file mode 100644 index 0000000000..030a578df4 --- /dev/null +++ b/tests/test_property_stl.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "pybind11_tests.h" + +#include +#include + +namespace test_class_sh_property_stl { + +struct Field { + explicit Field(int wrapped_int) : wrapped_int{wrapped_int} {} + int wrapped_int = 100; +}; + +struct FieldHolder { + explicit FieldHolder(const Field &fld) : fld{fld} {} + Field fld = Field{200}; +}; + +struct VectorFieldHolder { + std::vector vec_fld_hld; + VectorFieldHolder() { vec_fld_hld.push_back(FieldHolder{Field{300}}); } + void reset_at(std::size_t index, int wrapped_int) { + if (index < vec_fld_hld.size()) { + vec_fld_hld[index].fld.wrapped_int = wrapped_int; + } + } +}; + +} // namespace test_class_sh_property_stl + +using namespace test_class_sh_property_stl; + +PYBIND11_SMART_HOLDER_TYPE_CASTERS(Field) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(FieldHolder) +PYBIND11_SMART_HOLDER_TYPE_CASTERS(VectorFieldHolder) + +TEST_SUBMODULE(class_sh_property_stl, m) { + py::classh(m, "Field").def_readwrite("wrapped_int", &Field::wrapped_int); + + py::classh(m, "FieldHolder").def_readwrite("fld", &FieldHolder::fld); + + py::classh(m, "VectorFieldHolder") + .def(py::init<>()) + .def("reset_at", &VectorFieldHolder::reset_at) + .def_readwrite("vec_fld_hld_ref", &VectorFieldHolder::vec_fld_hld) + .def_readwrite("vec_fld_hld_cpy", + &VectorFieldHolder::vec_fld_hld, + py::return_value_policy::_clif_automatic); +} diff --git a/tests/test_property_stl.py b/tests/test_property_stl.py new file mode 100644 index 0000000000..b26c2c9458 --- /dev/null +++ b/tests/test_property_stl.py @@ -0,0 +1,31 @@ +from pybind11_tests import class_sh_property_stl as m + + +def test_cpy_after_ref(): + h = m.VectorFieldHolder() + c1 = h.vec_fld_hld_cpy + c2 = h.vec_fld_hld_cpy + assert repr(c2) != repr(c1) + r1 = h.vec_fld_hld_ref + assert repr(r1) != repr(c2) + assert repr(r1) != repr(c1) + r2 = h.vec_fld_hld_ref + assert repr(r2) == repr(r1) + c3 = h.vec_fld_hld_cpy + assert repr(c3) == repr(r1) # SURPRISE! + + +def test_persistent_holder(): + h = m.VectorFieldHolder() + c0 = h.vec_fld_hld_cpy[0] # Must be first. See test_cpy_after_ref(). + r0 = h.vec_fld_hld_ref[0] # Must be second. + assert c0.fld.wrapped_int == 300 + assert r0.fld.wrapped_int == 300 + h.reset_at(0, 400) + assert c0.fld.wrapped_int == 300 + assert r0.fld.wrapped_int == 400 + + +def test_temporary_holder_keep_alive(): + r0 = m.VectorFieldHolder().vec_fld_hld_ref[0] + assert r0.fld.wrapped_int == 300 From 3a703f32c73eeec6a6b0fa7f3f7b901cc0f929ea Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 24 Mar 2023 09:27:43 -0700 Subject: [PATCH 2/2] Demo: `return_value_policy::copy` ignored after `return_value_policy::reference_internal` already created a Python object. Back-ported from pywrapcc test_class_sh_property_stl.cpp,py --- tests/CMakeLists.txt | 1 + tests/test_property_stl.cpp | 24 +++++++++--------------- tests/test_property_stl.py | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b1cb222b4a..7e5bbc971c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -147,6 +147,7 @@ set(PYBIND11_TEST_FILES test_opaque_types test_operator_overloading test_pickling + test_property_stl test_pytypes test_sequences_and_iterators test_smart_ptr diff --git a/tests/test_property_stl.cpp b/tests/test_property_stl.cpp index 030a578df4..ff81bbff25 100644 --- a/tests/test_property_stl.cpp +++ b/tests/test_property_stl.cpp @@ -1,4 +1,3 @@ -#include #include #include "pybind11_tests.h" @@ -6,7 +5,7 @@ #include #include -namespace test_class_sh_property_stl { +namespace test_property_stl { struct Field { explicit Field(int wrapped_int) : wrapped_int{wrapped_int} {} @@ -28,24 +27,19 @@ struct VectorFieldHolder { } }; -} // namespace test_class_sh_property_stl +} // namespace test_property_stl -using namespace test_class_sh_property_stl; +TEST_SUBMODULE(property_stl, m) { + using namespace test_property_stl; -PYBIND11_SMART_HOLDER_TYPE_CASTERS(Field) -PYBIND11_SMART_HOLDER_TYPE_CASTERS(FieldHolder) -PYBIND11_SMART_HOLDER_TYPE_CASTERS(VectorFieldHolder) + py::class_(m, "Field").def_readwrite("wrapped_int", &Field::wrapped_int); -TEST_SUBMODULE(class_sh_property_stl, m) { - py::classh(m, "Field").def_readwrite("wrapped_int", &Field::wrapped_int); + py::class_(m, "FieldHolder").def_readwrite("fld", &FieldHolder::fld); - py::classh(m, "FieldHolder").def_readwrite("fld", &FieldHolder::fld); - - py::classh(m, "VectorFieldHolder") + py::class_(m, "VectorFieldHolder") .def(py::init<>()) .def("reset_at", &VectorFieldHolder::reset_at) .def_readwrite("vec_fld_hld_ref", &VectorFieldHolder::vec_fld_hld) - .def_readwrite("vec_fld_hld_cpy", - &VectorFieldHolder::vec_fld_hld, - py::return_value_policy::_clif_automatic); + .def_readwrite( + "vec_fld_hld_cpy", &VectorFieldHolder::vec_fld_hld, py::return_value_policy::copy); } diff --git a/tests/test_property_stl.py b/tests/test_property_stl.py index b26c2c9458..501ab9c04f 100644 --- a/tests/test_property_stl.py +++ b/tests/test_property_stl.py @@ -1,4 +1,4 @@ -from pybind11_tests import class_sh_property_stl as m +from pybind11_tests import property_stl as m def test_cpy_after_ref():