Pass a reference to C++ container to the Python callback
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Hi!
I faced this issue while implementing a Python's os.walk-like function for my tree structure. I hoped to mimic the ability of callback to edit passed list of directories in-place and guide further search.
Suppose we have the following in C++:
#include <pybind11/stl_bind.h>
PYBIND11_MAKE_OPAQUE(std::vector<double>);
namespace py = pybind11;
...
py::bind_vector<std::vector<double>>(m, "d_list", py::module_local(false));
// this will work as expected because I can explicitly point that return value is a reference
m.def("test_static_d", []() -> std::vector<double>& {
static std::vector<double> v{0, 0};
return v;
}, py::return_value_policy::reference);
// callback will fail to edit passed vector, because a copy is involved somewhere?
m.def("test_callback", [](std::function<void(std::vector<double>&)> f) {
std::vector<double> v{0, 0};
f(v);
for(const auto& l : v) {
std::cout << l << ' ';
}
std::cout << std::endl;
});
And now the Python code:
In [2]: a = example.test_static_d()
In [3]: a.append(1)
In [4]: a
Out[4]: d_list[0, 0, 1]
In [5]: b = example.test_static_d()
In [6]: b
Out[6]: d_list[0, 0, 1]
# so far so good
In [7]: b is a
Out[7]: True
# callback seems to modify a copy of vector
def f(v) :
v.append(1.)
print(v)
# C++ function don't get updated vector after callback invoke
In [1]: example.test_callback(f)
d_list[0, 0, 1]
0 0
Is there a way to specify that callback should take an opaque container by reference (in order to modify it in-place on Python side)?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the contrast between test_static_d and test_callback using the opaque std::vector binding from pybind11/stl_bind.h. Trace how the std::function callback argument is converted, then verify that mutations made by the Python callback are visible in the C++ vector after the callback returns.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100