Skip to content

Latest commit

 

History

History
243 lines (164 loc) · 7.33 KB

File metadata and controls

243 lines (164 loc) · 7.33 KB

Python types

Available wrappers

All major Python types are available as thin C++ wrapper classes. These can also be used as function parameters -- see :ref:`python_objects_as_args`.

Available types include :class:`handle`, :class:`object`, :class:`bool_`, :class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`, :class:`list`, :class:`dict`, :class:`slice`, :class:`none`, :class:`capsule`, :class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`, :class:`array`, and :class:`array_t`.

Warning

Be sure to review the :ref:`pytypes_gotchas` before using this heavily in your C++ API.

Casting back and forth

In this kind of mixed code, it is often necessary to convert arbitrary C++ types to Python, which can be done using :func:`py::cast`:

MyClass *cls = ..;
py::object obj = py::cast(cls);

The reverse direction uses the following syntax:

py::object obj = ...;
MyClass *cls = obj.cast<MyClass *>();

When conversion fails, both directions throw the exception :class:`cast_error`.

Accessing Python libraries from C++

It is also possible to import objects defined in the Python standard library or available in the current Python environment (sys.path) and work with these in C++.

This example obtains a reference to the Python Decimal class.

// Equivalent to "from decimal import Decimal"
py::object Decimal = py::module::import("decimal").attr("Decimal");
// Try to import scipy
py::object scipy = py::module::import("scipy");
return scipy.attr("__version__");

Implicit (automatic) casting

Instead of using a generic :class:`object` as return type, it is possible to specialize to a subtype, e.g., to use the lookup syntax of :class:`dict`.

Note

Casting to the wrong type will currently lead to downstream errors, e.g., when casting a Python dict to :class:`list` and using the append method. In the future, such a bad cast will likely result in a :class:`cast_error`, see PR #2349.

This constructor syntax is available for subclasses of :class:`object`; there is no need to call obj.cast() explicitly as for custom classes, see :ref:`_casting_back_and_forth`.

Calling Python functions

It is also possible to call Python classes, functions and methods via operator().

// Construct a Python object of class Decimal
py::object pi = Decimal("3.14159");
// Use Python to make our directories
py::object os = py::module::import("os");
py::object makedirs = os.attr("makedirs");
makedirs("/tmp/path/to/somewhere");

One can convert the result obtained from Python to a pure C++ version if a py::class_ or type conversion is defined.

py::function f = <...>;
py::object result_py = f(1234, "hello", some_instance);
MyClass &result = result_py.cast<MyClass>();

Calling Python methods

To call an object's method, one can again use .attr to obtain access to the Python method.

// Calculate e^π in decimal
py::object exp_pi = pi.attr("exp")();
py::print(py::str(exp_pi));

In the example above pi.attr("exp") is a bound method: it will always call the method for that same instance of the class. Alternately one can create an unbound method via the Python class (instead of instance) and pass the self object explicitly, followed by other arguments.

py::object decimal_exp = Decimal.attr("exp");

// Compute the e^n for n=0..4
for (int n = 0; n < 5; n++) {
    py::print(decimal_exp(Decimal(n));
}

Keyword arguments

Keyword arguments are also supported. In Python, there is the usual call syntax:

def f(number, say, to):
    ...  # function code

f(1234, say="hello", to=some_instance)  # keyword call in Python

In C++, the same call can be made using:

using namespace pybind11::literals; // to bring in the `_a` literal
f(1234, "say"_a="hello", "to"_a=some_instance); // keyword call in C++

Unpacking arguments

Unpacking of *args and **kwargs is also possible and can be mixed with other arguments:

// * unpacking
py::tuple args = py::make_tuple(1234, "hello", some_instance);
f(*args);

// ** unpacking
py::dict kwargs = py::dict("number"_a=1234, "say"_a="hello", "to"_a=some_instance);
f(**kwargs);

// mixed keywords, * and ** unpacking
py::tuple args = py::make_tuple(1234);
py::dict kwargs = py::dict("to"_a=some_instance);
f(*args, "say"_a="hello", **kwargs);

Generalized unpacking according to PEP448 is also supported:

py::dict kwargs1 = py::dict("number"_a=1234);
py::dict kwargs2 = py::dict("to"_a=some_instance);
f(**kwargs1, "say"_a="hello", **kwargs2);
.. seealso::

    The file :file:`tests/test_pytypes.cpp` contains a complete
    example that demonstrates passing native Python types in more detail. The
    file :file:`tests/test_callbacks.cpp` presents a few examples of calling
    Python functions from C++, including keywords arguments and unpacking.

Handling exceptions

Python exceptions from wrapper classes will be thrown as a py::error_already_set. See :ref:`Handling exceptions from Python in C++ <handling_python_exceptions_cpp>` for more information on handling exceptions raised when calling C++ wrapper classes.

Gotchas

Default-Constructed Wrappers

When a wrapper type is default-constructed, it is not a valid Python object (i.e. it is not py::none()). It is simply the same as PyObject* null pointer. To check for this, use static_cast<bool>(my_wrapper).

Assigning py::none() to wrappers

You may be tempted to use types like py::str and py::dict in C++ signatures (either pure C++, or in bound signatures), and assign them default values of py::none(). However, in a best case scenario, it will fail fast because None is not convertible to that type (e.g. py::dict), or in a worse case scenario, it will silently work but corrupt the types you want to work with (e.g. py::str(py::none()) will yield "None" in Python).