-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
@apojomovsky ran into a situation where a set of ovlerloads look like something to the effect of:
py::class_<Container>(m, "Container")
.def(py::init<unique_ptr<A>, FirstT>())
.def(py::init<unique_ptr<A>, SecondT>());
When Python calls something like:
c = Container(A(), SecondT())
this will most likely failure with the following error:
RuntimeError: C++ object must be owned by pybind11 when attempting to release to C++
This most likely happens since pybind11::detail::argument_loader
does not have a "transaction" mechanism of sort; the cast of unique_ptr<A>
succeeds when it tries to match the first overload, but when it is unable to load the second argument, it will just exit out, and not try to reverse the ownership transfer:
https://github.com/RobotLocomotion/pybind11/blob/060f8eb/include/pybind11/cast.h#L2138
The solution is to introduce some sort of "transaction" mechanism.
From what it looks like, I detect ownership transfer from the move_only_holder_caster
; if the caster is destructed without having transferred the object, then it can reverse the ownership transfer (simply calling cast
to release ownership back to Python).