pybind / pybind/pybind11

copy/move rvp does not work as expected for already registered python objects

Open
#2,250 1 comment 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.