Python types#

Available wrappers#

All major Python types are available as thin C++ wrapper classes. These can also be used as function parameters – see Python objects as arguments.

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

Warning

Be sure to review the Gotchas before using this heavily in your C++ API.

Instantiating compound Python types from C++#

Dictionaries can be initialized in the dict constructor:

usingnamespacepybind11::literals;// to bring in the `_a` literal
py::dictd("spam"_a=py::none(),"eggs"_a=42);

A tuple of python objects can be instantiated using py::make_tuple():

py::tupletup=py::make_tuple(42,py::none(),"spam");

Each element is converted to a supported Python type.

A simple namespace can be instantiated using

usingnamespacepybind11::literals;// to bring in the `_a` literal
py::objectSimpleNamespace=py::module_::import("types").attr("SimpleNamespace");
py::objectns=SimpleNamespace("spam"_a=py::none(),"eggs"_a=42);

Attributes on a namespace can be modified with the py::delattr(), py::getattr(), and py::setattr() functions. Simple namespaces can be useful as lightweight stand-ins for class instances.

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 py::cast():

MyClass*cls=...;
py::objectobj=py::cast(cls);

The reverse direction uses the following syntax:

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

When conversion fails, both directions throw the exception 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::objectDecimal=py::module_::import("decimal").attr("Decimal");
// Try to import scipy
py::objectscipy=py::module_::import("scipy");
returnscipy.attr("__version__");

Calling Python functions#

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

// Construct a Python object of class Decimal
py::objectpi=Decimal("3.14159");
// Use Python to make our directories
py::objectos=py::module_::import("os");
py::objectmakedirs=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::functionf=<...>;
py::objectresult_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::objectexp_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::objectdecimal_exp=Decimal.attr("exp");
// Compute the e^n for n=0..4
for(intn=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:

deff(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:

usingnamespacepybind11::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::tupleargs=py::make_tuple(1234,"hello",some_instance);
f(*args);
// ** unpacking
py::dictkwargs=py::dict("number"_a=1234,"say"_a="hello","to"_a=some_instance);
f(**kwargs);
// mixed keywords, * and ** unpacking
py::tupleargs=py::make_tuple(1234);
py::dictkwargs=py::dict("to"_a=some_instance);
f(*args,"say"_a="hello",**kwargs);

Generalized unpacking according to PEP448 is also supported:

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

See also

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

Implicit casting#

When using the C++ interface for Python types, or calling Python functions, objects of type object are returned. It is possible to invoke implicit conversions to subclasses like dict. The same holds for the proxy objects returned by operator[] or obj.attr(). Casting to subtypes improves code readability and allows values to be passed to C++ functions that require a specific subtype rather than a generic object.

#include<pybind11/numpy.h>
usingnamespacepybind11::literals;
py::module_os=py::module_::import("os");
py::module_path=py::module_::import("os.path");// like 'import os.path as path'
py::module_np=py::module_::import("numpy");// like 'import numpy as np'
py::strcurdir_abs=path.attr("abspath")(path.attr("curdir"));
py::print(py::str("Current directory: ")+curdir_abs);
py::dictenviron=os.attr("environ");
py::print(environ["HOME"]);
py::array_t<float>arr=np.attr("ones")(3,"dtype"_a="float32");
py::print(py::repr(arr+py::int_(1)));

These implicit conversions are available for subclasses of object; there is no need to call obj.cast() explicitly as for custom classes, see Casting back and forth.

Note

If a trivial conversion via move constructor is not possible, both implicit and explicit casting (calling obj.cast()) will attempt a "rich" conversion. For instance, py::list env = os.attr("environ"); will succeed and is equivalent to the Python code env = list(os.environ) that produces a list of the dict keys.

Handling exceptions#

Python exceptions from wrapper classes will be thrown as a py::error_already_set. See Handling exceptions from Python in C++ 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).