-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[BUG]: def_property
doesn't seems to keep parent alive when the return object is a py::array
#4236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi,
But it obviously is NOT true, at least not in all cases. See the most simplified example: struct B
{
B() { std::cout << "B" << std::endl; }
~B() { std::cout << "~B" << std::endl; }
B(B&& other) { std::cout << "B move" << std::endl; }
};
struct A
{
A() { std::cout << "A" << std::endl; }
~A() { std::cout << "~A" << std::endl; }
};
PYBIND11_MODULE(my_module, m)
{
py::class_<A>(m, "A")
.def(py::init())
.def_property_readonly("b_wrong", [](A& a) { return B(); })
.def_property_readonly("b_ok", py::cpp_function([](A& a) { return B(); }, py::keep_alive<0, 1>()));
py::class_<B>(m, "B")
.def(py::init()) ;
} Note that the See that property >>> from my_module import A, B
>>> a = A()
A
>>> b = a.b_wrong
B
B move
~B
>>> del a
~A While it works with >>> from my_module import A, B
>>> a = A()
A
>>> b = a.b_ok
B
B move
~B
>>> del a
>>> del b
~B
~A |
I've also checked test_call_policies.cpp which could have been used as good reference, but it unfortunately also doesn't contain any |
We recently ran into this problem when writing bindings for This happens because First things first, every templated But ok, I can just use The problem is that if I don't construct a I believe this fully covers this bug. As for how this should be resolved, I'm not sure. I'm not familiar enough with the internals of pybind11 to propose a solution that won't break something else. But I would love to see this fixed in the near future. Hope this information helps! |
I don't see how |
I don't know what the correct solution here is (beyond the |
Required prerequisites
Problem description
I posted this as a discussion before: #4200, but got no answer for a while, so repost it here.
I have a use case that have some internal C++ vectors and want to return to python side as numpy array. To avoid copy, we only return a view on a C++ vector. It works OK in most of times, but I'm now hitting below corner case:
Wrapper2
create a new instance ofstd::shared_ptr<Wrapper1>
which contains a C++ std::vectorvalues
. Thevalues
is then return to python as a numpy array view.From the docs: https://pybind11.readthedocs.io/en/stable/advanced/functions.html,
def_property_readonly
will usereturn_value_policy::reference_internal
and thus keep the parent object alive. So I expect thevalues
returned will keep its parent, i.e. the new instance ofstd::shared_ptr<Wrapper1>
alive and the underlying memory will be valid as long asvalues
is alive in Python.However, below test case shows it is not the case
I also try to manually to use
keep_alive<0, 1>
in thevalues
binding ofWrapper1
, but that doesn't seem to help.So is the
keep_alive
system not supposed to work with an existing python object, e.g.py::array
? If so, what should I do to make above test case work?Any thoughts would be appreciated. Thanks.
Reproducible example code
No response
The text was updated successfully, but these errors were encountered: