test_pickling.cpp
Go to the documentation of this file.
1 /*
2  tests/test_pickling.cpp -- pickle support
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #include "pybind11_tests.h"
11 
12 TEST_SUBMODULE(pickling, m) {
13  // test_roundtrip
14  class Pickleable {
15  public:
16  Pickleable(const std::string &value) : m_value(value) { }
17  const std::string &value() const { return m_value; }
18 
19  void setExtra1(int extra1) { m_extra1 = extra1; }
20  void setExtra2(int extra2) { m_extra2 = extra2; }
21  int extra1() const { return m_extra1; }
22  int extra2() const { return m_extra2; }
23  private:
24  std::string m_value;
25  int m_extra1 = 0;
26  int m_extra2 = 0;
27  };
28 
29  class PickleableNew : public Pickleable {
30  public:
31  using Pickleable::Pickleable;
32  };
33 
34  py::class_<Pickleable>(m, "Pickleable")
35  .def(py::init<std::string>())
36  .def("value", &Pickleable::value)
37  .def("extra1", &Pickleable::extra1)
38  .def("extra2", &Pickleable::extra2)
39  .def("setExtra1", &Pickleable::setExtra1)
40  .def("setExtra2", &Pickleable::setExtra2)
41  // For details on the methods below, refer to
42  // http://docs.python.org/3/library/pickle.html#pickling-class-instances
43  .def("__getstate__", [](const Pickleable &p) {
44  /* Return a tuple that fully encodes the state of the object */
45  return py::make_tuple(p.value(), p.extra1(), p.extra2());
46  })
47  .def("__setstate__", [](Pickleable &p, py::tuple t) {
48  if (t.size() != 3)
49  throw std::runtime_error("Invalid state!");
50  /* Invoke the constructor (need to use in-place version) */
51  new (&p) Pickleable(t[0].cast<std::string>());
52 
53  /* Assign any additional state */
54  p.setExtra1(t[1].cast<int>());
55  p.setExtra2(t[2].cast<int>());
56  });
57 
58  py::class_<PickleableNew, Pickleable>(m, "PickleableNew")
59  .def(py::init<std::string>())
60  .def(py::pickle(
61  [](const PickleableNew &p) {
62  return py::make_tuple(p.value(), p.extra1(), p.extra2());
63  },
64  [](py::tuple t) {
65  if (t.size() != 3)
66  throw std::runtime_error("Invalid state!");
67  auto p = PickleableNew(t[0].cast<std::string>());
68 
69  p.setExtra1(t[1].cast<int>());
70  p.setExtra2(t[2].cast<int>());
71  return p;
72  }
73  ));
74 
75 #if !defined(PYPY_VERSION)
76  // test_roundtrip_with_dict
77  class PickleableWithDict {
78  public:
79  PickleableWithDict(const std::string &value) : value(value) { }
80 
81  std::string value;
82  int extra;
83  };
84 
85  class PickleableWithDictNew : public PickleableWithDict {
86  public:
87  using PickleableWithDict::PickleableWithDict;
88  };
89 
90  py::class_<PickleableWithDict>(m, "PickleableWithDict", py::dynamic_attr())
91  .def(py::init<std::string>())
92  .def_readwrite("value", &PickleableWithDict::value)
93  .def_readwrite("extra", &PickleableWithDict::extra)
94  .def("__getstate__", [](py::object self) {
95  /* Also include __dict__ in state */
96  return py::make_tuple(self.attr("value"), self.attr("extra"), self.attr("__dict__"));
97  })
98  .def("__setstate__", [](py::object self, py::tuple t) {
99  if (t.size() != 3)
100  throw std::runtime_error("Invalid state!");
101  /* Cast and construct */
102  auto& p = self.cast<PickleableWithDict&>();
103  new (&p) PickleableWithDict(t[0].cast<std::string>());
104 
105  /* Assign C++ state */
106  p.extra = t[1].cast<int>();
107 
108  /* Assign Python state */
109  self.attr("__dict__") = t[2];
110  });
111 
112  py::class_<PickleableWithDictNew, PickleableWithDict>(m, "PickleableWithDictNew")
113  .def(py::init<std::string>())
114  .def(py::pickle(
115  [](py::object self) {
116  return py::make_tuple(self.attr("value"), self.attr("extra"), self.attr("__dict__"));
117  },
118  [](const py::tuple &t) {
119  if (t.size() != 3)
120  throw std::runtime_error("Invalid state!");
121 
122  auto cpp_state = PickleableWithDictNew(t[0].cast<std::string>());
123  cpp_state.extra = t[1].cast<int>();
124 
125  auto py_state = t[2].cast<py::dict>();
126  return std::make_pair(cpp_state, py_state);
127  }
128  ));
129 #endif
130 }
Matrix3f m
TEST_SUBMODULE(pickling, m)
Tuple< Args... > make_tuple(Args...args)
Creates a tuple object, deducing the target type from the types of arguments.
detail::initimpl::pickle_factory< GetState, SetState > pickle(GetState &&g, SetState &&s)
Definition: pybind11.h:1479
float * p
Point2 t(10, 10)


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:04