Skip to content

Commit 0b30a4a

Browse files
committed
This change fixes the 6 unit tests in
https://github.com/deepmind/open_spiel/tree/bbfb0259b5d26c1e3f05000f1f4a05b7ad60393e/open_spiel/python/mfg/algorithms best_response_value_test distribution_test fictitious_play_test greedy_policy_test nash_conv_test policy_value_test CAVEAT: The fix is NOT covered by pybind11 unit tests.
1 parent 6ff8361 commit 0b30a4a

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

include/pybind11/detail/smart_holder_poc.h

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ High-level aspects:
6060
namespace pybindit {
6161
namespace memory {
6262

63+
static constexpr bool type_has_shared_from_this(...) { return false; }
64+
65+
template <typename T>
66+
static constexpr bool type_has_shared_from_this(const std::enable_shared_from_this<T> *) {
67+
return true;
68+
}
69+
6370
struct guarded_delete {
6471
std::weak_ptr<void> released_ptr; // Trick to keep the smart_holder memory footprint small.
6572
void (*del_ptr)(void *);

include/pybind11/detail/smart_holder_type_casters.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ struct smart_holder_type_caster_load {
393393
throw_if_uninitialized_or_disowned_holder();
394394
holder_type &hld = holder();
395395
hld.ensure_is_not_disowned("loaded_as_shared_ptr");
396+
if (hld.vptr_is_using_noop_deleter) {
397+
throw std::runtime_error("Non-owning holder (loaded_as_shared_ptr).");
398+
}
396399
auto void_raw_ptr = hld.template as_raw_ptr_unowned<void>();
397400
auto type_raw_ptr = convert_type(void_raw_ptr);
398401
if (hld.pointee_depends_on_holder_owner) {
@@ -407,12 +410,26 @@ struct smart_holder_type_caster_load {
407410
vptr_gd_ptr->released_ptr = to_be_released;
408411
return to_be_released;
409412
}
413+
if (std::get_deleter<shared_ptr_dec_ref_deleter>(hld.vptr) != nullptr) {
414+
// SMART_HOLDER_WIP: unit test coverage.
415+
std::shared_ptr<void> void_shd_ptr = hld.template as_shared_ptr<void>();
416+
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
417+
}
418+
if (!pybindit::memory::type_has_shared_from_this(type_raw_ptr)) {
419+
// SMART_HOLDER_WIP: unit test coverage.
420+
// SMART_HOLDER_WIP: keep weak_ref?
421+
auto self = reinterpret_cast<PyObject *>(load_impl.loaded_v_h.inst);
422+
Py_INCREF(self);
423+
return std::shared_ptr<T>(type_raw_ptr, shared_ptr_dec_ref_deleter{self});
424+
}
425+
if (hld.vptr_is_external_shared_ptr) {
426+
// SMART_HOLDER_WIP: unit test coverage.
427+
pybind11_fail("smart_holder_type_casters loaded_as_shared_ptr failure: external "
428+
"shared_ptr for type with shared_from_this.");
429+
}
410430
pybind11_fail("smart_holder_type_casters: loaded_as_shared_ptr failure: internal "
411431
"inconsistency.");
412432
}
413-
if (hld.vptr_is_using_noop_deleter) {
414-
throw std::runtime_error("Non-owning holder (loaded_as_shared_ptr).");
415-
}
416433
std::shared_ptr<void> void_shd_ptr = hld.template as_shared_ptr<void>();
417434
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
418435
}

0 commit comments

Comments
 (0)