If you make an object pickleable, you get deepcopy for free, because the deepcopy function will use a pickle-unpickle cycle as a fall back if it cannot find any other way to copy. This has the disadvantage that you must come up with a sensible pickled representation, and you pay for a round trip through a string. This is especially annoying since all c++ objects are already deepcopyable by default: just use a call copy-ctor.
There is another way to tell python how to deepcopy an object: give it a __deepcopy__ function (and a __copy__ function). This is some code I got from Hans Meine a while back: #define PYTHON_ERROR(TYPE, REASON) \ { \ PyErr_SetString(TYPE, REASON); \ throw bp::error_already_set(); \ } template<class T> inline PyObject * managingPyObject(T *p) { return typename bp::manage_new_object::apply<T *>::type()(p); } template<class Copyable> bp::object generic__copy__(bp::object copyable) { Copyable *newCopyable(new Copyable(bp::extract<const Copyable &>(copyable))); bp::object result(bp::detail::new_reference(managingPyObject(newCopyable))); bp::extract<bp::dict>(result.attr("__dict__"))().update( copyable.attr("__dict__")); return result; } template<class Copyable> bp::object generic__deepcopy__(bp::object copyable, bp::dict memo) { bp::object copyMod = bp::import("copy"); bp::object deepcopy = copyMod.attr("deepcopy"); Copyable *newCopyable(new Copyable(bp::extract<const Copyable &>(copyable))); bp::object result(bp::detail::new_reference(managingPyObject(newCopyable))); // HACK: copyableId shall be the same as the result of id(copyable) in Python - // please tell me that there is a better way! (and which ;-p) int copyableId = (int)(copyable.ptr()); memo[copyableId] = result; bp::extract<bp::dict>(result.attr("__dict__"))().update( deepcopy(bp::extract<bp::dict>(copyable.attr("__dict__"))(), memo)); return result; } To use it: class_<foo>(foo) .def("__copy__", &generic__copy__< foo >) .def("__deepcopy__", &generic__deepcopy__< foo >) .def(init< const foo & >()) This has the advantage that you can use it on any existing class that has a sensible cctor. -----Original Message----- From: cplusplus-sig-bounces+matthew.scouten=tradingtechnologies....@python.org [mailto:cplusplus-sig-bounces+matthew.scouten=tradingtechnologies....@py thon.org] On Behalf Of Gennadiy Rozental Sent: Monday, May 11, 2009 12:47 AM To: cplusplus-sig@python.org Subject: Re: [C++-sig] how to deep copy boost python object Ralf W. Grosse-Kunstleve <rwgk <at> yahoo.com> writes: > > > A comprehensive approach is to make the object picklable. > As a side-effect, copy.deepcopy() will also work. 1. Are you saying that copy.deepcopy does not work without object being picklable? What will happend if I try to use it for non picklable object? 2. What if object IS picklable. How will invoke deepcopy operation on bp::object? Gennadiy _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig