pybind / pybind/pybind11

Is clone pattern supported with classes overloaded in python?

Open
#1,049 24 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

docs
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

In C++ clone pattern is used in many APIs:

class A {
public:
   A();
   A(const A& other)
   virtual void func()=0;
   virtual A* clone() const { return new A(*this);  }
}

class A_trampoline: public A {
 // Usual things for pure virtual func()
}

// function dependent on clone functionality
void work_on_many_instances(const shared_ptr<A>& inst){
    std::vector<shared_ptr<A>> tasks;
    for(int i=0; i<100; ++i) tasks.push_back( shared_ptr<A>(inst->clone()) );
    // Do something with clonned instances
}

Suppose one extends class A in python using standard trampoline facilities and exposes it as usual:

py::class_<A,A_trampoline,std::shared_ptr<A>>(m, "A") 
....
;

// Accepts PyObject with class derived in python from A
m.def("work_on_many_instances", [](const py::object& o){
        auto p = o.cast<shared_ptr<A>>();
        work_on_many_instances(p); // UPS! clone will try to create A, not the derived class...
   });

When clone() is called inside work_on_many_instances() it creates an instance of A, which is an abstract class and, of course, fails. Unless I'm missing something obvious I can't figure out how to clone an object of derived class correctly. As far as I understand the trampoline should make a deep copy of existing python derived class instance on C++ side somehow but I have absolutely no idea how. Is it possible at all?

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

No source files or tests are named. Start by reading pybind11's class_ and trampoline facilities, then trace how a Python-derived A is represented when clone() is called through the C++ interface. Done means the supported behavior and any required approach are established clearly, with coverage if the project accepts a change.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.