copy/move rvp does not work as expected for already registered python objects
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
The copy/move return value policy does not apply correctly to a C++ reference returned from the function in case the reference being returned is already associated with a previously registered pybind11 instance. The underlying problem is that the cast function in type_caster_generic class returns an existing instance, if any, before even considering the intended rvp. To fix this issue, the search for existing instances needs to be predicated on the rvp not being a copy/move. The following code reproduces the problem.
// C++ binding
#include "pybind11/pybind11.h"
namespace py = pybind11;
struct A {
int x;
A(int x) : x(x) {}
A(const A& a): x(a.x * 100) {}
void m() { printf("A.m() = %p, %d\n", this, x); }
};
A& foo(A& a) {
return a;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
py::class_<A>(m, "A")
.def(py::init<int>())
.def(py::init<const A&>())
.def("m", &A::m);
m.def("foo", foo, py::return_value_policy::copy);
}
Python code
from example import A, foo, bar
a = A(1)
a.m()
foo(a).m()
Possible output
A.m() = 0x7052ab, 1
A.m() = 0x7052ab, 1
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 at the type_caster_generic cast function and reproduce the behavior with the C++ binding and Python example in the issue. Trace how existing registered instances are selected for the return value policy, then add regression coverage showing that copy/move policies produce the intended result and run the relevant test suite.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100