@@ -13,6 +13,11 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
13
13
:class: `iterable `, :class: `iterator `, :class: `function `, :class: `buffer `,
14
14
:class: `array `, and :class: `array_t `.
15
15
16
+ .. warning ::
17
+
18
+ You should be aware of how these classes interact with :func: `py::none `.
19
+ See :ref: `pytypes_interaction_with_none ` for more details.
20
+
16
21
Casting back and forth
17
22
======================
18
23
@@ -168,3 +173,62 @@ Generalized unpacking according to PEP448_ is also supported:
168
173
Python functions from C++, including keywords arguments and unpacking.
169
174
170
175
.. _PEP448 : https://www.python.org/dev/peps/pep-0448/
176
+
177
+ .. _pytypes_interaction_with_none :
178
+
179
+ Interaction with None
180
+ =====================
181
+
182
+ You may be tempted to use types like ``py::str `` and ``py::dict `` in C++
183
+ signatures (either pure C++, or in bound signatures). However, there are some
184
+ "gotchas" for ``py::none() `` and how it interacts with these types. In best
185
+ case scenarios, it will fail fast (e.g. with default arguments); in worst
186
+ cases, it will silently work but corrupt the types you want to work with.
187
+
188
+ At a first glance, you may think after executing the following code, the
189
+ expression ``my_value.is(py::none()) `` will be true:
190
+
191
+ .. code-block :: cpp
192
+
193
+ py::str my_value = py::none();
194
+
195
+ However, this is not the case. Instead, the value of ``my_value `` will be equal
196
+ to the Python value of ``str(None) ``, due to how :macro: `PYBIND11_OBJECT_CVT `
197
+ is used in :file: `pybind11/pytypes.h `.
198
+
199
+ Additionally, calling the following binding with the default argument used will
200
+ raise a ``TypeError `` about invalid arguments:
201
+
202
+ .. code-block :: cpp
203
+
204
+ m.def(
205
+ "my_function",
206
+ [](py::str my_value) { ... },
207
+ py::arg("my_value") = py::none());
208
+
209
+ In both of these cases where you may want to pass ``None `` through any
210
+ signatures where you want to constrain the type, you should either use
211
+ :class: `py::object ` in conjunction with :func: `py::isinstance `, or use the
212
+ corresponding C++ type with `std::optional ` (if it is available on your
213
+ system).
214
+
215
+ For the above conversion:
216
+
217
+ .. code-block :: cpp
218
+
219
+ py::object my_value = /* py::none() or some string */;
220
+ ...
221
+ if (!my_value.is(py::none()) && !py::isinstance<py::str>(my_value)) {
222
+ /* error behavior */
223
+ }
224
+
225
+ For the above default argument:
226
+
227
+ .. code-block :: cpp
228
+
229
+ m.def(
230
+ "my_function",
231
+ [](std::optional<std::string> my_value) { ... },
232
+ py::arg("my_value") = std::nullopt);
233
+
234
+ For more details, see the tests for ``pytypes `` mentioned above.
0 commit comments