Skip to content

Ownership of python objects inheriting from C++ classes #1389

Closed
@florianwechsung

Description

@florianwechsung

Hi,

I have an issue with the ref counting of python objects that are passed to C++.
I have a C++ class Vector that the use can inherit from (hence I also have a PyVector trampoline class). The user-defined python class should then be passed back to C++ where some actions on this class are performed. Unfortunately, it seems that python takes complete ownership of the class, so that it gets deleted even if the C++ side still needs it.

MFE:

#include <pybind11/pybind11.h>
#include <iostream>
#include <memory>

namespace py = pybind11;

class Vector : public std::enable_shared_from_this<Vector> {
    public:
        Vector() {}
        virtual void print() {
            std::cout << "Vector" << std::endl;
        }
};

class PyVector : public Vector {
    public:
        virtual void print() override {
            PYBIND11_OVERLOAD(void, Vector, print,);
        }
};

class Foo {
    public:
        Foo(std::shared_ptr<Vector> vec) : _vec(vec){}
        std::shared_ptr<Vector> _vec;
        void print() {
            _vec -> print();
        }
};

PYBIND11_MODULE(cmake_example, m) {

    py::class_<Vector, std::shared_ptr<Vector>,
        PyVector>(m, "Vector")
            .def(py::init<>());

    py::class_<Foo, std::shared_ptr<Foo>>(m, "Foo")
        .def(py::init<std::shared_ptr<Vector>>())
        .def("print", &Foo::print);

}

Python code:

import cmake_example as m

class MyVector(m.Vector):

    def print(self):
        print("MyVector")

    def __del__(self):
        print("I was deleted")

def make_foo():
    x = MyVector()
    foo = m.Foo(x)
    foo.print()
    return foo

myfoo = make_foo()
myfoo.print()

Output:

MyVector
I was deleted
Vector

Expected output:

MyVector
MyVector
I was deleted

Metadata

Metadata

Assignees

No one assigned

    Labels

    holdersIssues and PRs regarding holders

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions