Skip to content

fix(smart_holder): keep void-cast semantics in from_unique_ptr - #6163

Open
henryiii wants to merge 1 commit into
pybind:masterfrom
henryiii:fix/smart-holder-unique-ptr-shared-from-this
Open

fix(smart_holder): keep void-cast semantics in from_unique_ptr#6163
henryiii wants to merge 1 commit into
pybind:masterfrom
henryiii:fix/smart-holder-unique-ptr-shared-from-this

Conversation

@henryiii

@henryiii henryiii commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI text below 🤖

smart_holder::from_unique_ptr() always built the owning shared_ptr from a T *. This connects the std::enable_shared_from_this<T> machinery to the holder control block. For trampoline (alias) types this must not happen: shared_from_this() must fail with bad_weak_ptr, because the resulting shared_ptr does not keep the Python object alive.

The void_cast_raw_ptr flag in detail/init.h was made ineffective by #5836, which changed the second parameter of from_unique_ptr() into a multiple-inheritance subobject pointer. As a result, a factory that returns a unique_ptr to a trampoline lost the guard, and the Python override could disappear silently.

from_unique_ptr() now has an explicit void_cast_raw_ptr parameter. If it is true, the owner is constructed as a shared_ptr<void>, which keeps the control block invisible to shared_from_this(). The multiple-inheritance behavior does not change.

Fixes item 4 of #6159.

Suggested changelog entry:

  • Fixed py::init() factories that return a std::unique_ptr to a trampoline: shared_from_this() correctly fails with bad_weak_ptr again, instead of returning a shared_ptr that does not keep the Python object alive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant