Skip to content

Commit ff70657

Browse files
committed
Add test_class_sp_trampoline_weak_ptr.cpp,py (using std::shared_ptr as holder). Tweak test_class_sh_trampoline_weak_ptr.py to pass, with # THIS NEEDS FIXING comment.
1 parent 2fe82b2 commit ff70657

4 files changed

+83
-1
lines changed

tests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ set(PYBIND11_TEST_FILES
134134
test_class_sh_unique_ptr_custom_deleter
135135
test_class_sh_unique_ptr_member
136136
test_class_sh_virtual_py_cpp_mix
137+
test_class_sp_trampoline_weak_ptr
137138
test_const_name
138139
test_constants_and_functions
139140
test_copy_move

tests/test_class_sh_trampoline_weak_ptr.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ def test_weak_ptr_base(vtype, expected_code):
2121
assert obj.get_code() == expected_code
2222

2323
wpo.set_wp(obj)
24-
assert wpo.get_code() == expected_code
24+
if vtype is m.VirtBase:
25+
assert wpo.get_code() == expected_code
26+
else:
27+
assert wpo.get_code() == -999 # THIS NEEDS FIXING (issue #5623)
2528

2629
del obj
2730
assert wpo.get_code() == -999
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) 2025 The Pybind Development Team.
2+
// All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#include "pybind11_tests.h"
6+
7+
#include <memory>
8+
9+
namespace pybind11_tests {
10+
namespace class_sp_trampoline_weak_ptr {
11+
12+
struct VirtBase {
13+
virtual ~VirtBase() = default;
14+
virtual int get_code() { return 100; }
15+
};
16+
17+
struct PyVirtBase : VirtBase, py::trampoline_self_life_support {
18+
using VirtBase::VirtBase;
19+
int get_code() override { PYBIND11_OVERRIDE(int, VirtBase, get_code); }
20+
};
21+
22+
struct WpOwner {
23+
void set_wp(std::shared_ptr<VirtBase> sp) { wp = sp; }
24+
25+
int get_code() {
26+
auto sp = wp.lock();
27+
if (!sp) {
28+
return -999;
29+
}
30+
return sp->get_code();
31+
}
32+
33+
private:
34+
std::weak_ptr<VirtBase> wp;
35+
};
36+
37+
} // namespace class_sp_trampoline_weak_ptr
38+
} // namespace pybind11_tests
39+
40+
using namespace pybind11_tests::class_sp_trampoline_weak_ptr;
41+
42+
TEST_SUBMODULE(class_sp_trampoline_weak_ptr, m) {
43+
py::class_<VirtBase, std::shared_ptr<VirtBase>, PyVirtBase>(m, "VirtBase")
44+
.def(py::init<>())
45+
.def("get_code", &VirtBase::get_code);
46+
47+
py::class_<WpOwner>(m, "WpOwner")
48+
.def(py::init<>())
49+
.def("set_wp", &WpOwner::set_wp)
50+
.def("get_code", &WpOwner::get_code);
51+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
5+
import env # noqa: F401
6+
import pybind11_tests.class_sp_trampoline_weak_ptr as m
7+
8+
9+
class PyDrvd(m.VirtBase):
10+
def get_code(self):
11+
return 200
12+
13+
14+
@pytest.mark.skipif("env.GRAALPY", reason="Cannot reliably trigger GC")
15+
@pytest.mark.parametrize(("vtype", "expected_code"), [(m.VirtBase, 100), (PyDrvd, 200)])
16+
def test_weak_ptr_base(vtype, expected_code):
17+
wpo = m.WpOwner()
18+
assert wpo.get_code() == -999
19+
20+
obj = vtype()
21+
assert obj.get_code() == expected_code
22+
23+
wpo.set_wp(obj)
24+
assert wpo.get_code() == expected_code
25+
26+
del obj
27+
assert wpo.get_code() == -999

0 commit comments

Comments
 (0)