diff --git a/tests/test_class_sp_trampoline_weak_ptr.cpp b/tests/test_class_sp_trampoline_weak_ptr.cpp index 4821fd711..06250b303 100644 --- a/tests/test_class_sp_trampoline_weak_ptr.cpp +++ b/tests/test_class_sp_trampoline_weak_ptr.cpp @@ -34,6 +34,20 @@ private: std::weak_ptr wp; }; +struct SpOwner { + void set_sp(const std::shared_ptr &sp) { this->sp = sp; } + + int get_code() { + if (!sp) { + return -888; + } + return sp->get_code(); + } + +private: + std::shared_ptr sp; +}; + } // namespace class_sp_trampoline_weak_ptr } // namespace pybind11_tests @@ -48,4 +62,9 @@ TEST_SUBMODULE(class_sp_trampoline_weak_ptr, m) { .def(py::init<>()) .def("set_wp", &WpOwner::set_wp) .def("get_code", &WpOwner::get_code); + + py::class_(m, "SpOwner") + .def(py::init<>()) + .def("set_sp", &SpOwner::set_sp) + .def("get_code", &SpOwner::get_code); } diff --git a/tests/test_class_sp_trampoline_weak_ptr.py b/tests/test_class_sp_trampoline_weak_ptr.py index 3782cd8aa..5c427f980 100644 --- a/tests/test_class_sp_trampoline_weak_ptr.py +++ b/tests/test_class_sp_trampoline_weak_ptr.py @@ -12,7 +12,7 @@ class PyDrvd(m.VirtBase): @pytest.mark.parametrize(("vtype", "expected_code"), [(m.VirtBase, 100), (PyDrvd, 200)]) -def test_weak_ptr_owner(vtype, expected_code): +def test_with_wp_owner(vtype, expected_code): wpo = m.WpOwner() assert wpo.get_code() == -999 @@ -26,3 +26,44 @@ def test_weak_ptr_owner(vtype, expected_code): if env.PYPY or env.GRAALPY: pytest.skip("Cannot reliably trigger GC") assert wpo.get_code() == -999 + + +@pytest.mark.parametrize(("vtype", "expected_code"), [(m.VirtBase, 100), (PyDrvd, 200)]) +def test_with_sp_owner(vtype, expected_code): + spo = m.SpOwner() + assert spo.get_code() == -888 + + obj = vtype() + assert obj.get_code() == expected_code + + spo.set_sp(obj) + assert spo.get_code() == expected_code + + del obj + if env.PYPY or env.GRAALPY: + pytest.skip("Cannot reliably trigger GC") + assert spo.get_code() == 100 # Inheritance slicing (issue #1333) + + +@pytest.mark.parametrize(("vtype", "expected_code"), [(m.VirtBase, 100), (PyDrvd, 200)]) +def test_with_sp_and_wp_owners(vtype, expected_code): + spo = m.SpOwner() + wpo = m.WpOwner() + + obj = vtype() + spo.set_sp(obj) + wpo.set_wp(obj) + + assert spo.get_code() == expected_code + assert wpo.get_code() == expected_code + + del obj + if env.PYPY or env.GRAALPY: + pytest.skip("Cannot reliably trigger GC") + + # Inheritance slicing (issue #1333) + assert spo.get_code() == 100 + assert wpo.get_code() == 100 + + del spo + assert wpo.get_code() == -999