Skip to content

Fix py::cast(std::shared_ptr<T>) for shared_ptr-compatible custom holders#6065

Draft
virtuald wants to merge 3 commits into
pybind:masterfrom
virtuald:custom-holder-shared-ptr
Draft

Fix py::cast(std::shared_ptr<T>) for shared_ptr-compatible custom holders#6065
virtuald wants to merge 3 commits into
pybind:masterfrom
virtuald:custom-holder-shared-ptr

Conversation

@virtuald
Copy link
Copy Markdown
Contributor

Description

Fixes #6064. I don't really like this approach, it seems like a lot of obscure code to support an edge case, and the thread_local is hard to follow.

Suggested changelog entry:

  • Placeholder.

virtuald and others added 3 commits May 17, 2026 03:51
This restores support for custom holders that are constructible from std::shared_ptr<T> without requiring user code changes or an internals ABI bump.

The fix keeps the safety check added in pybind#6008 for incompatible custom holders, but adds an internal path for compatible ones:
- py::cast(std::shared_ptr<T>) now recognizes bound types using custom holders
- it tunnels shared ownership through an internal thread-local payload
- non-smart-holder init_instance() consumes that payload and constructs the bound holder when Holder<T> is constructible from std::shared_ptr<T>

This preserves the regression fix for unsafe cases while allowing established patterns such as private-destructor types wrapped by shared_ptr-backed custom holders to keep working.
rwgk added a commit that referenced this pull request May 19, 2026
Lock down the current behavior discussed in issue #6064: py::cast() from std::shared_ptr<T> remains rejected for custom holder bindings that are not std::shared_ptr or py::smart_holder.

This extracts the incompatible-holder coverage from PR #6068 and adds a test shaped like issue #6064, while PR #6065 and PR #6066 explore alternative support paths.
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.

[BUG]: py::cast() from std::shared_ptr throws with custom holder

1 participant