Skip to content

Commit fbc7563

Browse files
authored
Add py::object casting example to embedding docs (#2466)
* Add py::object casting example to embedding docs * Move implicit cast example to object.rst * Move to bottom and improve implicit casting text * Fix xref * Improve wording as per @bstaletic's suggestion
1 parent 37f845a commit fbc7563

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

docs/advanced/pycpp/object.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
2020
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
2121
your C++ API.
2222

23+
.. _casting_back_and_forth:
24+
2325
Casting back and forth
2426
======================
2527

@@ -62,6 +64,7 @@ This example obtains a reference to the Python ``Decimal`` class.
6264
py::object scipy = py::module::import("scipy");
6365
return scipy.attr("__version__");
6466
67+
6568
.. _calling_python_functions:
6669

6770
Calling Python functions
@@ -176,6 +179,47 @@ Generalized unpacking according to PEP448_ is also supported:
176179

177180
.. _PEP448: https://www.python.org/dev/peps/pep-0448/
178181

182+
.. _implicit_casting:
183+
184+
Implicit casting
185+
================
186+
187+
When using the C++ interface for Python types, or calling Python functions,
188+
objects of type :class:`object` are returned. It is possible to invoke implicit
189+
conversions to subclasses like :class:`dict`. The same holds for the proxy objects
190+
returned by ``operator[]`` or ``obj.attr()``.
191+
Casting to subtypes improves code readability and allows values to be passed to
192+
C++ functions that require a specific subtype rather than a generic :class:`object`.
193+
194+
.. code-block:: cpp
195+
196+
#include <pybind11/numpy.h>
197+
using namespace pybind11::literals;
198+
199+
py::module os = py::module::import("os");
200+
py::module path = py::module::import("os.path"); // like 'import os.path as path'
201+
py::module np = py::module::import("numpy"); // like 'import numpy as np'
202+
203+
py::str curdir_abs = path.attr("abspath")(path.attr("curdir"));
204+
py::print(py::str("Current directory: ") + curdir_abs);
205+
py::dict environ = os.attr("environ");
206+
py::print(environ["HOME"]);
207+
py::array_t<float> arr = np.attr("ones")(3, "dtype"_a="float32");
208+
py::print(py::repr(arr + py::int_(1)));
209+
210+
These implicit conversions are available for subclasses of :class:`object`; there
211+
is no need to call ``obj.cast()`` explicitly as for custom classes, see
212+
:ref:`casting_back_and_forth`.
213+
214+
.. note::
215+
If a trivial conversion via move constructor is not possible, both implicit and
216+
explicit casting (calling ``obj.cast()``) will attempt a "rich" conversion.
217+
For instance, ``py::list env = os.attr("environ");`` will succeed and is
218+
equivalent to the Python code ``env = list(os.environ)`` that produces a
219+
list of the dict keys.
220+
221+
.. TODO: Adapt text once PR #2349 has landed
222+
179223
Handling exceptions
180224
===================
181225

0 commit comments

Comments
 (0)