Skip to content

Commit 1bcd8e8

Browse files
committed
Adjust to behavior change due to pybind/pybind11#4586 (smart_holder branch).
The behavior change made it possible to exercise the `reference_internal` vs `copy` behavior more thoroughly, which then led to a surprise discovery. See SURPRISE comment in tests/test_class_sh_property_stl.py
1 parent f80b55b commit 1bcd8e8

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

tests/test_class_sh_property_stl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "pybind11_tests.h"
55

6+
#include <cstddef>
67
#include <vector>
78

89
namespace test_class_sh_property_stl {
@@ -20,6 +21,11 @@ struct FieldHolder {
2021
struct VectorFieldHolder {
2122
std::vector<FieldHolder> vec_fld_hld;
2223
VectorFieldHolder() { vec_fld_hld.push_back(FieldHolder{Field{300}}); }
24+
void reset_at(std::size_t index, int wrapped_int) {
25+
if (index < vec_fld_hld.size()) {
26+
vec_fld_hld[index].fld.wrapped_int = wrapped_int;
27+
}
28+
}
2329
};
2430

2531
} // namespace test_class_sh_property_stl
@@ -37,6 +43,7 @@ TEST_SUBMODULE(class_sh_property_stl, m) {
3743

3844
py::classh<VectorFieldHolder>(m, "VectorFieldHolder")
3945
.def(py::init<>())
46+
.def("reset_at", &VectorFieldHolder::reset_at)
4047
.def_readwrite("vec_fld_hld_ref", &VectorFieldHolder::vec_fld_hld)
4148
.def_readwrite("vec_fld_hld_cpy",
4249
&VectorFieldHolder::vec_fld_hld,

tests/test_class_sh_property_stl.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
1-
import pytest
2-
31
from pybind11_tests import class_sh_property_stl as m
42

53

6-
def test_vec_fld_hld_ref():
7-
vfh = m.VectorFieldHolder()
8-
vfh0 = vfh.vec_fld_hld_ref[0]
9-
with pytest.raises(RuntimeError) as exc_info:
10-
vfh0.fld
11-
assert str(exc_info.value) == "Non-owning holder (loaded_as_shared_ptr)."
4+
def test_cpy_after_ref():
5+
h = m.VectorFieldHolder()
6+
c1 = h.vec_fld_hld_cpy
7+
c2 = h.vec_fld_hld_cpy
8+
assert repr(c2) != repr(c1)
9+
r1 = h.vec_fld_hld_ref
10+
assert repr(r1) != repr(c2)
11+
assert repr(r1) != repr(c1)
12+
r2 = h.vec_fld_hld_ref
13+
assert repr(r2) == repr(r1)
14+
c3 = h.vec_fld_hld_cpy
15+
assert repr(c3) == repr(r1) # SURPRISE!
16+
17+
18+
def test_persistent_holder():
19+
h = m.VectorFieldHolder()
20+
c0 = h.vec_fld_hld_cpy[0] # Must be first. See test_cpy_after_ref().
21+
r0 = h.vec_fld_hld_ref[0] # Must be second.
22+
assert c0.fld.wrapped_int == 300
23+
assert r0.fld.wrapped_int == 300
24+
h.reset_at(0, 400)
25+
assert c0.fld.wrapped_int == 300
26+
assert r0.fld.wrapped_int == 400
1227

1328

14-
def test_vec_fld_hld_cpy():
15-
vfh = m.VectorFieldHolder()
16-
vfh0 = vfh.vec_fld_hld_cpy[0]
17-
assert vfh0.fld.wrapped_int == 300
29+
def test_temporary_holder_keep_alive():
30+
r0 = m.VectorFieldHolder().vec_fld_hld_ref[0]
31+
assert r0.fld.wrapped_int == 300

0 commit comments

Comments
 (0)