diff --git a/include/pybind11/detail/smart_holder_type_casters.h b/include/pybind11/detail/smart_holder_type_casters.h index 19580c94d..913951ad7 100644 --- a/include/pybind11/detail/smart_holder_type_casters.h +++ b/include/pybind11/detail/smart_holder_type_casters.h @@ -305,6 +305,8 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag } auto uninitialized_location = std::addressof(v_h.holder()); auto value_ptr_w_t = v_h.value_ptr(); + bool pointee_depends_on_holder_owner + = dynamic_raw_ptr_cast_if_possible(value_ptr_w_t) != nullptr; if (holder_void_ptr) { // Note: inst->owned ignored. auto holder_ptr = static_cast(holder_void_ptr); @@ -314,7 +316,8 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag uninitialized_location, value_ptr_w_t, value_ptr_w_t)) { if (inst->owned) { new (uninitialized_location) - holder_type(holder_type::from_raw_ptr_take_ownership(value_ptr_w_t, true)); + holder_type(holder_type::from_raw_ptr_take_ownership( + value_ptr_w_t, pointee_depends_on_holder_owner)); } else { new (uninitialized_location) holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t)); @@ -322,13 +325,14 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag } } v_h.holder().pointee_depends_on_holder_owner - = dynamic_raw_ptr_cast_if_possible(value_ptr_w_t) != nullptr; + = pointee_depends_on_holder_owner; v_h.set_holder_constructed(); } template static smart_holder smart_holder_from_unique_ptr(std::unique_ptr &&unq_ptr) { - return pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr), true); + return pybindit::memory::smart_holder::from_unique_ptr( + std::move(unq_ptr), /*TODO pointee_depends_on_holder_owner*/ true); } template @@ -801,7 +805,8 @@ struct smart_holder_type_caster> : smart_holder_type_caste void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr(); valueptr = src_raw_void_ptr; - auto smhldr = pybindit::memory::smart_holder::from_unique_ptr(std::move(src), true); + auto smhldr = pybindit::memory::smart_holder::from_unique_ptr( + std::move(src), /*TODO pointee_depends_on_holder_owner*/ true); tinfo->init_instance(inst_raw_ptr, static_cast(&smhldr)); if (policy == return_value_policy::reference_internal) diff --git a/tests/test_class_sh_trampoline_shared_from_this.py b/tests/test_class_sh_trampoline_shared_from_this.py index 7a72a7677..665123d75 100644 --- a/tests/test_class_sh_trampoline_shared_from_this.py +++ b/tests/test_class_sh_trampoline_shared_from_this.py @@ -130,27 +130,14 @@ def test_pass_released_shared_ptr_as_unique_ptr(): ) -def test_pure_cpp_sft_raw_ptr(): - obj = m.make_pure_cpp_sft_raw_ptr("PureCppSft") - with pytest.raises(RuntimeError) as exc_info: - assert m.pass_shared_ptr(obj) == 3 # TODO: FIX. - assert str(exc_info.value) == "bad_weak_ptr" - obj = m.make_pure_cpp_sft_raw_ptr("PureCppSft") - stash1 = m.SftSharedPtrStash(1) - with pytest.raises(RuntimeError) as exc_info: - stash1.AddSharedFromThis(obj) # TODO: FIX. - assert str(exc_info.value) == "bad_weak_ptr" - stash1.Add(obj) - with pytest.raises(RuntimeError) as exc_info: - stash1.AddSharedFromThis(obj) # TODO: FIX. - assert str(exc_info.value) == "bad_weak_ptr" - - -def test_pure_cpp_sft_shd_ptr(): - obj = m.make_pure_cpp_sft_shd_ptr("PureCppSft") +@pytest.mark.parametrize( + "make_f", [m.make_pure_cpp_sft_raw_ptr, m.make_pure_cpp_sft_shd_ptr] +) +def test_pure_cpp_sft_raw_ptr(make_f): + obj = make_f("PureCppSft") assert m.pass_shared_ptr(obj) == 3 assert obj.history == "PureCppSft_PassSharedPtr" - obj = m.make_pure_cpp_sft_shd_ptr("PureCppSft") + obj = make_f("PureCppSft") stash1 = m.SftSharedPtrStash(1) stash1.AddSharedFromThis(obj) assert obj.history == "PureCppSft_Stash1AddSharedFromThis"