Adding `test_pass_released_shared_ptr_as_unique_ptr`, exercising new guard in smart_holder_type_casters.h.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-06-21 16:16:37 -07:00 committed by Ralf W. Grosse-Kunstleve
parent e04196e82b
commit 4b872febcc
3 changed files with 24 additions and 1 deletions

View File

@ -438,6 +438,7 @@ to_cout("LOOOK loaded_as_shared_ptr return hld vptr " + std::to_string(__LINE__)
if (!have_holder())
return nullptr;
throw_if_uninitialized_or_disowned_holder();
throw_if_instance_is_currently_owned_by_shared_ptr();
holder().ensure_is_not_disowned(context);
holder().template ensure_compatible_rtti_uqp_del<T, D>(context);
holder().ensure_use_count_1(context);
@ -501,6 +502,13 @@ private:
}
}
// have_holder() must be true or this function will fail.
void throw_if_instance_is_currently_owned_by_shared_ptr() const {
if (holder().vptr_is_released) {
throw value_error("Python instance is currently owned by a std::shared_ptr.");
}
}
T *convert_type(void *void_ptr) const {
if (void_ptr != nullptr && load_impl.loaded_v_h_cpptype != nullptr
&& !load_impl.reinterpret_cast_deemed_ok && load_impl.implicit_cast != nullptr) {

View File

@ -70,7 +70,7 @@ struct SftSharedPtrStash {
}
};
struct SftTrampoline : Sft {
struct SftTrampoline : Sft, py::trampoline_self_life_support {
using Sft::Sft;
};
@ -78,6 +78,8 @@ void pass_shared_ptr(const std::shared_ptr<Sft> &obj) {
obj->shared_from_this()->history += "_PassSharedPtr";
}
void pass_unique_ptr(const std::unique_ptr<Sft> &) {}
} // namespace
PYBIND11_SMART_HOLDER_TYPE_CASTERS(Sft)
@ -97,4 +99,5 @@ TEST_SUBMODULE(class_sh_trampoline_shared_from_this, m) {
.def("use_count", &SftSharedPtrStash::use_count);
m.def("pass_shared_ptr", pass_shared_ptr);
m.def("pass_unique_ptr", pass_unique_ptr);
}

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import pytest
import env # noqa: F401
@ -80,3 +81,14 @@ def test_pass_shared_ptr_while_stashed_with_shared_from_this():
gc.collect()
if not env.PYPY:
assert obj_wr() is None
def test_pass_released_shared_ptr_as_unique_ptr():
obj = PySft("PySft")
stash1 = m.SftSharedPtrStash(1)
stash1.Add(obj) # Releases shared_ptr to C++.
with pytest.raises(ValueError) as exc_info:
m.pass_unique_ptr(obj)
assert str(exc_info.value) == (
"Python instance is currently owned by a std::shared_ptr."
)