PageRenderTime 68ms CodeModel.GetById 40ms RepoModel.GetById 0ms app.codeStats 0ms

/peer/pickle_support.hpp

https://github.com/gfrd/egfrd
C++ Header | 85 lines | 67 code | 18 blank | 0 comment | 6 complexity | bf73bbe5313174e49b16e7223ce47f73 MD5 | raw file
Possible License(s): GPL-2.0
  1. #ifndef OBJECTMATRIX_PEER_PICKLE_SUPPORT
  2. #define OBJECTMATRIX_PEER_PICKLE_SUPPORT
  3. #include <Python.h>
  4. #include <pyerrors.h>
  5. #include <import.h>
  6. #include <boost/python.hpp>
  7. namespace peer { namespace pickle {
  8. static const char reconstruct_func_name[] = "__reconstruct__";
  9. static PyObject* reconstruct(PyObject* self, PyObject* args)
  10. {
  11. PyTypeObject* klass;
  12. PyObject* base;
  13. PyObject* state;
  14. if (!PyArg_ParseTuple(args, "OOO", &klass, &base, &state))
  15. return NULL;
  16. if (!PyType_Check(klass)) {
  17. PyErr_SetString(PyExc_TypeError, "argument 1 must be a type object");
  18. return NULL;
  19. }
  20. if (!PyType_Check(base)) {
  21. PyErr_SetString(PyExc_TypeError, "argument 2 must be a type object");
  22. return NULL;
  23. }
  24. if (!PyTuple_Check(state)) {
  25. PyErr_SetString(PyExc_TypeError, "argument 3 must be a tuple");
  26. return NULL;
  27. }
  28. return klass->tp_new(klass, state, NULL);
  29. }
  30. static PyObject* reduce(PyObject* self) try
  31. {
  32. using namespace boost::python;
  33. BOOST_ASSERT(self->ob_type);
  34. BOOST_ASSERT(self->ob_type->tp_base);
  35. BOOST_ASSERT(self != Py_None);
  36. object state(getattr(object(borrowed(self)), "__getstate__")());
  37. object module(borrowed(PyImport_Import(
  38. getattr(object(borrowed(
  39. reinterpret_cast<PyObject*>(self->ob_type))),
  40. "__module__").ptr())));
  41. return incref(make_tuple(
  42. getattr(module, reconstruct_func_name),
  43. make_tuple(
  44. borrowed(incref(reinterpret_cast<PyObject*>(self->ob_type))),
  45. borrowed(incref(reinterpret_cast<PyObject*>(self->ob_type->tp_base))),
  46. state)).ptr());
  47. }
  48. catch (boost::python::error_already_set const&)
  49. {
  50. return NULL;
  51. }
  52. static inline void register_reconstructor()
  53. {
  54. using namespace boost::python;
  55. static bool registered = false;
  56. if (!registered) {
  57. static PyMethodDef def = {
  58. const_cast<char*>(reconstruct_func_name),
  59. &reconstruct,
  60. METH_VARARGS, const_cast<char*>("")
  61. };
  62. scope().attr(reconstruct_func_name) = borrowed(PyCFunction_NewEx(
  63. &def, NULL, getattr(scope(), "__name__").ptr()));
  64. }
  65. }
  66. } } // namespace peer::pickle
  67. #endif /* OBJECTMATRIX_PEER_PICKLE_SUPPORT */