Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 45 additions & 0 deletions tests/test_property_stl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <pybind11/stl.h>

#include "pybind11_tests.h"

#include <cstddef>
#include <vector>

namespace test_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<FieldHolder> 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_property_stl

TEST_SUBMODULE(property_stl, m) {
using namespace test_property_stl;

py::class_<Field>(m, "Field").def_readwrite("wrapped_int", &Field::wrapped_int);

py::class_<FieldHolder>(m, "FieldHolder").def_readwrite("fld", &FieldHolder::fld);

py::class_<VectorFieldHolder>(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::copy);
}
31 changes: 31 additions & 0 deletions tests/test_property_stl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pybind11_tests import 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