mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +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) {
|
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
|
// This code is reachable only if there are multiple registered_instances for the
|
||||||
// same pointee.
|
// 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>();
|
std::shared_ptr<void> void_shd_ptr = hld.template as_shared_ptr<void>();
|
||||||
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
|
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
|
||||||
}
|
}
|
||||||
if (!pybindit::memory::type_has_shared_from_this(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);
|
auto self = reinterpret_cast<PyObject *>(load_impl.loaded_v_h.inst);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return std::shared_ptr<T>(type_raw_ptr, shared_ptr_dec_ref_deleter{self});
|
return std::shared_ptr<T>(type_raw_ptr, shared_ptr_dec_ref_deleter{self});
|
||||||
}
|
}
|
||||||
if (hld.vptr_is_external_shared_ptr) {
|
if (hld.vptr_is_external_shared_ptr) {
|
||||||
// SMART_HOLDER_WIP: unit test coverage.
|
pybind11_fail("smart_holder_type_casters loaded_as_shared_ptr failure: not "
|
||||||
pybind11_fail("smart_holder_type_casters loaded_as_shared_ptr failure: external "
|
"implemented: trampoline-self-life-support for external shared_ptr "
|
||||||
"shared_ptr for type with shared_from_this.");
|
"to type inheriting from std::enable_shared_from_this.");
|
||||||
}
|
}
|
||||||
pybind11_fail("smart_holder_type_casters: loaded_as_shared_ptr failure: internal "
|
pybind11_fail("smart_holder_type_casters: loaded_as_shared_ptr failure: internal "
|
||||||
"inconsistency.");
|
"inconsistency.");
|
||||||
|
@ -103,7 +103,10 @@ PYBIND11_SMART_HOLDER_TYPE_CASTERS(SftSharedPtrStash)
|
|||||||
|
|
||||||
TEST_SUBMODULE(class_sh_trampoline_shared_from_this, m) {
|
TEST_SUBMODULE(class_sh_trampoline_shared_from_this, m) {
|
||||||
py::classh<Sft, SftTrampoline>(m, "Sft")
|
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)
|
.def_readonly("history", &Sft::history)
|
||||||
// This leads to multiple entries in registered_instances:
|
// This leads to multiple entries in registered_instances:
|
||||||
.def(py::init([](const std::shared_ptr<Sft> &existing) { return existing; }));
|
.def(py::init([](const std::shared_ptr<Sft> &existing) { return existing; }));
|
||||||
|
@ -171,3 +171,20 @@ def test_multiple_registered_instances_for_same_pointee():
|
|||||||
else:
|
else:
|
||||||
assert not hasattr(obj_pt, "attachment_in_dict")
|
assert not hasattr(obj_pt, "attachment_in_dict")
|
||||||
break # Comment out for manual leak checking (use `top` command).
|
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;
|
virtual ~SpBase() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<SpBase> pass_through_shd_ptr(const std::shared_ptr<SpBase> &obj) { return obj; }
|
||||||
|
|
||||||
struct PySpBase : SpBase {
|
struct PySpBase : SpBase {
|
||||||
|
using SpBase::SpBase;
|
||||||
bool is_base_used() override { PYBIND11_OVERRIDE(bool, SpBase, is_base_used); }
|
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")
|
py::classh<SpBase, PySpBase>(m, "SpBase")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
|
.def(py::init([](int) { return std::make_shared<PySpBase>(); }))
|
||||||
.def("is_base_used", &SpBase::is_base_used)
|
.def("is_base_used", &SpBase::is_base_used)
|
||||||
.def("has_python_instance", &SpBase::has_python_instance);
|
.def("has_python_instance", &SpBase::has_python_instance);
|
||||||
|
|
||||||
|
m.def("pass_through_shd_ptr", pass_through_shd_ptr);
|
||||||
|
|
||||||
py::classh<SpBaseTester>(m, "SpBaseTester")
|
py::classh<SpBaseTester>(m, "SpBaseTester")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def("get_object", &SpBaseTester::get_object)
|
.def("get_object", &SpBaseTester::get_object)
|
||||||
|
@ -131,3 +131,12 @@ def test_infinite():
|
|||||||
while True:
|
while True:
|
||||||
tester.set_object(m.SpBase())
|
tester.set_object(m.SpBase())
|
||||||
return # Comment out for manual leak checking (use `top` command).
|
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