[BUG]: `py::cast()` from `std::shared_ptr` throws with custom holder
triage
### Required prerequisites
- [x] Make sure you've read the [documentation](https://pybind11.readthedocs.io). Your issue may be addressed there.
- [x] Search the [issue tracker](https://github.com/pybind/pybind11/issues) and [Discussions](https:/pybind/pybind11/discussions) to verify that this hasn't already been reported. +1 or comment there if it has.
- [ ] Consider asking first in the [Gitter chat room](https://gitter.im/pybind/Lobby) or in a [Discussion](https:/pybind/pybind11/discussions/new).
### What version (or hash if on master) of pybind11 are you using?
3.0.4
### Problem description
The *libcamera* project provides python bindings via pybind11. One particular type has a private destructor and is managed via `std::shared_ptr`. It has a custom holder to work around the need for a public destructor.
This has worked so far, but now it does work not with pybind11 3.0.4. Specifically, calling `py::cast()` on an `std::shared_ptr` of that type in question throws:
```
>>> import libcamera
>>> cm = libcamera.CameraManager.singleton()
>>> cm.cameras
RuntimeError: Unable to convert std::shared_ptr<T> to Python when the bound type does not use std::shared_ptr or py::smart_holder as its holder type
```
As far as I can see this has been added by #6008. So I'm wondering, is this exception diagnosing a real issue, or the above PR missed some cases?
It seems to work with `py::smart_holder`, but this code predates that, so it wasn't used.
<details>
<summary>holder type</summary>
```cpp
template<typename T>
class PyCameraSmartPtr
{
public:
using element_type = T;
PyCameraSmartPtr()
{
}
explicit PyCameraSmartPtr(T *)
{
throw std::runtime_error("invalid SmartPtr constructor call");
}
explicit PyCameraSmartPtr(std::shared_ptr<T> p)
: ptr_(std::move(p))
{
}
T *get() const { return ptr_.get(); }
operator std::shared_ptr<T>() const { return ptr_; }
private:
std::shared_ptr<T> ptr_;
};
PYBIND11_DECLARE_HOLDER_TYPE(T, PyCameraSmartPtr<T>)
// ...
auto pyCamera = py::class_<Camera, PyCameraSmartPtr<Camera>>(m, "Camera");
```
</details>
### Reproducible example code
```text
```
### Is this a regression? Put the last known working version here if it is.
3.0.2 (?)
2 条评论