mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 07:02:11 +00:00
Adding unit tests: 2 x test_std_make_shared_factory
Completes unit test coverage for the changed code in smart_holder_type_casters.h.
This commit is contained in:
parent
1b752f56c1
commit
e2108546e1
@ -413,21 +413,20 @@ struct smart_holder_type_caster_load {
|
||||
if (std::get_deleter<shared_ptr_dec_ref_deleter>(hld.vptr) != nullptr) {
|
||||
// This code is reachable only if there are multiple registered_instances for the
|
||||
// same pointee.
|
||||
// SMART_HOLDER_WIP: keep weak_ref?
|
||||
// SMART_HOLDER_WIP: keep weak_ref
|
||||
std::shared_ptr<void> void_shd_ptr = hld.template as_shared_ptr<void>();
|
||||
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
|
||||
}
|
||||
if (!pybindit::memory::type_has_shared_from_this(type_raw_ptr)) {
|
||||
// SMART_HOLDER_WIP: unit test coverage.
|
||||
// SMART_HOLDER_WIP: keep weak_ref?
|
||||
// SMART_HOLDER_WIP: keep weak_ref
|
||||
auto self = reinterpret_cast<PyObject *>(load_impl.loaded_v_h.inst);
|
||||
Py_INCREF(self);
|
||||
return std::shared_ptr<T>(type_raw_ptr, shared_ptr_dec_ref_deleter{self});
|
||||
}
|
||||
if (hld.vptr_is_external_shared_ptr) {
|
||||
// SMART_HOLDER_WIP: unit test coverage.
|
||||
pybind11_fail("smart_holder_type_casters loaded_as_shared_ptr failure: external "
|
||||
"shared_ptr for type with shared_from_this.");
|
||||
pybind11_fail("smart_holder_type_casters loaded_as_shared_ptr failure: not "
|
||||
"implemented: trampoline-self-life-support for external shared_ptr "
|
||||
"to type inheriting from std::enable_shared_from_this.");
|
||||
}
|
||||
pybind11_fail("smart_holder_type_casters: loaded_as_shared_ptr failure: internal "
|
||||
"inconsistency.");
|
||||
|
@ -103,7 +103,10 @@ PYBIND11_SMART_HOLDER_TYPE_CASTERS(SftSharedPtrStash)
|
||||
|
||||
TEST_SUBMODULE(class_sh_trampoline_shared_from_this, m) {
|
||||
py::classh<Sft, SftTrampoline>(m, "Sft")
|
||||
.def(py::init<std::string>())
|
||||
.def(py::init<const std::string &>())
|
||||
.def(py::init([](const std::string &history, int) {
|
||||
return std::make_shared<SftTrampoline>(history);
|
||||
}))
|
||||
.def_readonly("history", &Sft::history)
|
||||
// This leads to multiple entries in registered_instances:
|
||||
.def(py::init([](const std::shared_ptr<Sft> &existing) { return existing; }));
|
||||
|
@ -171,3 +171,20 @@ def test_multiple_registered_instances_for_same_pointee():
|
||||
else:
|
||||
assert not hasattr(obj_pt, "attachment_in_dict")
|
||||
break # Comment out for manual leak checking (use `top` command).
|
||||
|
||||
|
||||
def test_std_make_shared_factory():
|
||||
class PySftMakeShared(m.Sft):
|
||||
def __init__(self, history):
|
||||
super(PySftMakeShared, self).__init__(history, 0)
|
||||
|
||||
obj = PySftMakeShared("PySftMakeShared")
|
||||
assert obj.history == "PySftMakeShared"
|
||||
with pytest.raises(RuntimeError) as exc_info:
|
||||
m.pass_through_shd_ptr(obj)
|
||||
assert (
|
||||
str(exc_info.value)
|
||||
== "smart_holder_type_casters loaded_as_shared_ptr failure: not implemented:"
|
||||
" trampoline-self-life-support for external shared_ptr to type inheriting"
|
||||
" from std::enable_shared_from_this."
|
||||
)
|
||||
|
@ -26,7 +26,10 @@ struct SpBase {
|
||||
virtual ~SpBase() = default;
|
||||
};
|
||||
|
||||
std::shared_ptr<SpBase> pass_through_shd_ptr(const std::shared_ptr<SpBase> &obj) { return obj; }
|
||||
|
||||
struct PySpBase : SpBase {
|
||||
using SpBase::SpBase;
|
||||
bool is_base_used() override { PYBIND11_OVERRIDE(bool, SpBase, is_base_used); }
|
||||
};
|
||||
|
||||
@ -61,9 +64,12 @@ TEST_SUBMODULE(class_sh_trampoline_shared_ptr_cpp_arg, m) {
|
||||
|
||||
py::classh<SpBase, PySpBase>(m, "SpBase")
|
||||
.def(py::init<>())
|
||||
.def(py::init([](int) { return std::make_shared<PySpBase>(); }))
|
||||
.def("is_base_used", &SpBase::is_base_used)
|
||||
.def("has_python_instance", &SpBase::has_python_instance);
|
||||
|
||||
m.def("pass_through_shd_ptr", pass_through_shd_ptr);
|
||||
|
||||
py::classh<SpBaseTester>(m, "SpBaseTester")
|
||||
.def(py::init<>())
|
||||
.def("get_object", &SpBaseTester::get_object)
|
||||
|
@ -131,3 +131,12 @@ def test_infinite():
|
||||
while True:
|
||||
tester.set_object(m.SpBase())
|
||||
return # Comment out for manual leak checking (use `top` command).
|
||||
|
||||
|
||||
def test_std_make_shared_factory():
|
||||
class PyChild(m.SpBase):
|
||||
def __init__(self):
|
||||
super(PyChild, self).__init__(0)
|
||||
|
||||
obj = PyChild()
|
||||
assert m.pass_through_shd_ptr(obj) is obj
|
||||
|
Loading…
Reference in New Issue
Block a user