Bring in shared_ptr_with_responsible_parent() from smart_holder branch:

smart_holder branch:

```
    static std::shared_ptr<type> shared_ptr_from_python(handle responsible_parent)
```

Renamed in this commit:

```
    static std::shared_ptr<type> shared_ptr_with_responsible_parent(handle responsible_parent)
```

Use in `property_cpp_function<>` specializations.

Fixes all 8 test failures introduced with the previous commit (1bcf572780):

```
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_value_ro-expected0-True] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_value_rw-expected1-True] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_value_rw-expected1-False] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_raw_ptr_ro-expected4-True] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_raw_ptr_ro-expected4-False] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_raw_ptr_rw-expected5-True] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_value_ro-expected0-False] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
FAILED test_class_sh_property_non_owning.py::test_core_fld_common[core_fld_raw_ptr_rw-expected5-False] - RuntimeError: Non-owning holder (loaded_as_shared_ptr).
```
This commit is contained in:
Ralf W. Grosse-Kunstleve 2024-07-12 01:27:02 -07:00
parent 1bcf572780
commit 048e36df40
2 changed files with 20 additions and 4 deletions

View File

@ -896,6 +896,18 @@ public:
return type_caster_base<type>::cast_holder(ptr, &src); return type_caster_base<type>::cast_holder(ptr, &src);
} }
// This function will succeed even if the `responsible_parent` does not own the
// wrapped C++ object directly.
// It is the responsibility of the caller to ensure that the `responsible_parent`
// has a `keep_alive` relationship with the owner of the wrapped C++ object, or
// that the wrapped C++ object lives for the duration of the process.
static std::shared_ptr<type> shared_ptr_with_responsible_parent(handle responsible_parent) {
copyable_holder_caster loader;
loader.load(responsible_parent, /*convert=*/false);
assert(loader.typeinfo->default_holder);
return loader.sh_load_helper.loaded_as_shared_ptr(loader.value, responsible_parent);
}
protected: protected:
friend class type_caster_generic; friend class type_caster_generic;
void check_holder_compat() {} void check_holder_compat() {}

View File

@ -1647,7 +1647,8 @@ struct property_cpp_function<
if (tinfo->default_holder) { if (tinfo->default_holder) {
return cpp_function( return cpp_function(
[pm](handle c_hdl) -> std::shared_ptr<drp> { [pm](handle c_hdl) -> std::shared_ptr<drp> {
auto c_sp = cast<std::shared_ptr<T>>(c_hdl); std::shared_ptr<T> c_sp = detail::type_caster<
std::shared_ptr<T>>::shared_ptr_with_responsible_parent(c_hdl);
D ptr = (*c_sp).*pm; D ptr = (*c_sp).*pm;
return std::shared_ptr<drp>(c_sp, ptr); return std::shared_ptr<drp>(c_sp, ptr);
}, },
@ -1694,7 +1695,8 @@ struct property_cpp_function<
if (tinfo->default_holder) { if (tinfo->default_holder) {
return cpp_function( return cpp_function(
[pm](handle c_hdl) -> std::shared_ptr<typename std::add_const<D>::type> { [pm](handle c_hdl) -> std::shared_ptr<typename std::add_const<D>::type> {
auto c_sp = cast<std::shared_ptr<T>>(c_hdl); std::shared_ptr<T> c_sp = detail::type_caster<
std::shared_ptr<T>>::shared_ptr_with_responsible_parent(c_hdl);
return std::shared_ptr<typename std::add_const<D>::type>(c_sp, return std::shared_ptr<typename std::add_const<D>::type>(c_sp,
&(c_sp.get()->*pm)); &(c_sp.get()->*pm));
}, },
@ -1709,7 +1711,8 @@ struct property_cpp_function<
if (tinfo->default_holder) { if (tinfo->default_holder) {
return cpp_function( return cpp_function(
[pm](handle c_hdl) -> std::shared_ptr<D> { [pm](handle c_hdl) -> std::shared_ptr<D> {
auto c_sp = cast<std::shared_ptr<T>>(c_hdl); std::shared_ptr<T> c_sp = detail::type_caster<
std::shared_ptr<T>>::shared_ptr_with_responsible_parent(c_hdl);
return std::shared_ptr<D>(c_sp, &(c_sp.get()->*pm)); return std::shared_ptr<D>(c_sp, &(c_sp.get()->*pm));
}, },
is_method(hdl)); is_method(hdl));
@ -1757,7 +1760,8 @@ struct property_cpp_function<
if (tinfo->default_holder) { if (tinfo->default_holder) {
return cpp_function( return cpp_function(
[pm](handle c_hdl) -> D { [pm](handle c_hdl) -> D {
auto c_sp = cast<std::shared_ptr<T>>(c_hdl); std::shared_ptr<T> c_sp = detail::type_caster<
std::shared_ptr<T>>::shared_ptr_with_responsible_parent(c_hdl);
return D{std::move(c_sp.get()->*pm)}; return D{std::move(c_sp.get()->*pm)};
}, },
is_method(hdl)); is_method(hdl));