Skip to content

Is clone pattern supported with classes overloaded in python? #1049

@yesint

Description

@yesint

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocs or GitHub info

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions