What is the inverse API of pybind11::keep_alive?

Viewed 159

One can ensure that an object appended to a List lives for at least as long as the List itself using pybind11::keep_alive construct.

Quoting the documentation for pybind11::keep_alive,

Consider the following example: here, the binding code for a list append operation ties the lifetime of the newly added element to the underlying container:

py::class_<List>(m, "List")
    .def("append", &List::append, py::keep_alive<1, 2>());

Similarly, how can one untie the lifetime of the appended object on remove API?

py::class_<List>(m, "List")
    .def("append", &List::append, py::keep_alive<1, 2>())
    .def("remove", &List::remove, ... /* What goes here? */);

To clarify, the remove API takes the element to remove as a parameter and removes the element from the List. Hence, it wouldn't make sense to keep the lifetime of the removed object tied to the List after the remove succeeds.

The following approach to decrease the ref count on the python object like so

.def("remove", [](List& list, py::object obj) {
        list.remove(obj.cast<CppObject*>());
        obj.dec_ref();
    });

does not work since pybind11 will try to decrement the reference count again when the List python object is garbage collected.

Is there a solution that does the inverse of pybind11::keep_alive?

Thanks in Advance!

Using C++17 with pybind11 v2.6.1.

1 Answers
Related