@@ -37,6 +37,72 @@ The old macro emits a compile-time deprecation warning.
37
37
}
38
38
39
39
40
+ New API for defining custom constructors and pickling functions
41
+ ---------------------------------------------------------------
42
+
43
+ The old placement-new custom constructors have been deprecated. The new approach
44
+ uses ``py::init() `` and factory functions to greatly improve type safety.
45
+
46
+ Placement-new can be called accidentally with an incompatible type (without any
47
+ compiler errors or warnings), or it can initialize the same object multiple times
48
+ if not careful with the Python-side ``__init__ `` calls. The new-style custom
49
+ constructors prevent such mistakes. See :ref: `custom_constructors ` for details.
50
+
51
+ .. code-block :: cpp
52
+
53
+ // old -- deprecated (runtime warning shown only in debug mode)
54
+ py::class<Foo>(m, "Foo")
55
+ .def("__init__", [](Foo &self, ...) {
56
+ new (&self) Foo(...); // uses placement-new
57
+ });
58
+
59
+ // new
60
+ py::class<Foo>(m, "Foo")
61
+ .def(py::init([](...) { // Note: no `self` argument
62
+ return new Foo(...); // return by raw pointer
63
+ // or: return std::make_unique<Foo>(...); // return by holder
64
+ // or: return Foo(...); // return by value (move constructor)
65
+ }));
66
+
67
+ Mirroring the custom constructor changes, ``py::pickle() `` is now the preferred
68
+ way to get and set object state. See :ref: `pickling ` for details.
69
+
70
+ .. code-block :: cpp
71
+
72
+ // old -- deprecated (runtime warning shown only in debug mode)
73
+ py::class<Foo>(m, "Foo")
74
+ ...
75
+ .def("__getstate__", [](const Foo &self) {
76
+ return py::make_tuple(self.value1(), self.value2(), ...);
77
+ })
78
+ .def("__setstate__", [](Foo &self, py::tuple t) {
79
+ new (&self) Foo(t[0].cast<std::string>(), ...);
80
+ });
81
+
82
+ // new
83
+ py::class<Foo>(m, "Foo")
84
+ ...
85
+ .def(py::pickle(
86
+ [](const Foo &self) { // __getstate__
87
+ return py::make_tuple(f.value1(), f.value2(), ...); // unchanged
88
+ },
89
+ [](py::tuple t) { // __setstate__, note: no `self` argument
90
+ return new Foo(t[0].cast<std::string>(), ...);
91
+ // or: return std::make_unique<Foo>(...); // return by holder
92
+ // or: return Foo(...); // return by value (move constructor)
93
+ }
94
+ ));
95
+
96
+ For both the constructors and pickling, warnings are shown at module
97
+ initialization time (on import, not when the functions are called).
98
+ They're only visible when compiled in debug mode. Sample warning:
99
+
100
+ .. code-block :: none
101
+
102
+ pybind11-bound class 'mymodule.Foo' is using an old-style placement-new '__init__'
103
+ which has been deprecated. See the upgrade guide in pybind11's docs.
104
+
105
+
40
106
Stricter enforcement of hidden symbol visibility for pybind11 modules
41
107
---------------------------------------------------------------------
42
108
@@ -135,66 +201,6 @@ localize all common type bindings in order to avoid conflicts with
135
201
third-party modules.
136
202
137
203
138
- New syntax for custom constructors
139
- ----------------------------------
140
-
141
- The old placement-new custom constructors are still valid, but the new approach
142
- greatly improves type safety. Placement-new can be called accidentally with an
143
- incompatible type (without any compiler errors or warnings), or it can initialize
144
- the same object multiple times if not careful with the Python-side ``__init__ ``
145
- calls. The new-style ``py::init() `` custom constructors prevent such mistakes.
146
- See :ref: `custom_constructors ` for details.
147
-
148
- .. code-block :: cpp
149
-
150
- // old
151
- py::class<Foo>(m, "Foo")
152
- .def("__init__", [](Foo &self, ...) {
153
- new (&self) Foo(...); // uses placement-new
154
- });
155
-
156
- // new
157
- py::class<Foo>(m, "Foo")
158
- .def(py::init([](...) { // Note: no `self` argument
159
- return new Foo(...); // return by raw pointer
160
- // or: return std::make_unique<Foo>(...); // return by holder
161
- // or: return Foo(...); // return by value (move constructor)
162
- }));
163
-
164
-
165
- New syntax for pickling support
166
- -------------------------------
167
-
168
- Mirroring the custom constructor changes, ``py::pickle() `` is now the preferred
169
- way to get and set object state. See :ref: `pickling ` for details.
170
-
171
- .. code-block :: cpp
172
-
173
- // old -- deprecated
174
- py::class<Foo>(m, "Foo")
175
- ...
176
- .def("__getstate__", [](const Foo &self) {
177
- return py::make_tuple(self.value1(), self.value2(), ...);
178
- })
179
- .def("__setstate__", [](Foo &self, py::tuple t) {
180
- new (&self) Foo(t[0].cast<std::string>(), ...);
181
- });
182
-
183
- // new
184
- py::class<Foo>(m, "Foo")
185
- ...
186
- .def(py::pickle(
187
- [](const Foo &self) { // __getstate__
188
- return py::make_tuple(f.value1(), f.value2(), ...); // unchanged
189
- },
190
- [](py::tuple t) { // __setstate__, note: no `self` argument
191
- return new Foo(t[0].cast<std::string>(), ...);
192
- // or: return std::make_unique<Foo>(...); // return by holder
193
- // or: return Foo(...); // return by value (move constructor)
194
- }
195
- ));
196
-
197
-
198
204
Deprecation of some ``py::object `` APIs
199
205
---------------------------------------
200
206
0 commit comments