cppyy: Automatic Python-C++ bindings

cppyy is an automatic Python-C++ bindings generator designed for large scale programs in high performance computing that use modern C++. Design and performance are described in this PyHPC paper.

cppyy is based on Cling, the C++ interpreter, to match Python’s dynamism and interactivity. Consider this session, showing dynamic, interactive, mixing of C++ and Python features:

>>> import cppyy
>>> cppyy.cppdef("""
... class MyClass {
... public:
...     MyClass(int i) : m_data(i) {}
...     int m_data;
... };""")
>>> from cppyy.gbl import MyClass
>>> m = MyClass(42)
>>> cppyy.cppdef("""
... void say_hello(MyClass* m) {
...     std::cout << "Hello, the number is: " << m->m_data << std::endl;
... }""")
>>> MyClass.say_hello = cppyy.gbl.say_hello
>>> m.say_hello()
Hello, the number is: 42
>>> m.m_data = 13
>>> m.say_hello()
Hello, the number is: 13

With a modern C++ compiler having its back, cppyy is future-proof. Consider the following session using boost::any, a capsule-type that allows for heterogeneous containers in C++. The Boost library is well known for its no holds barred use of modern C++ and heavy use of templates:

>>> import cppyy
>>> cppyy.include('boost/any.hpp')
>>> from cppyy.gbl import std, boost
>>> val = boost.any()                    # the capsule
>>> val.__assign__(std.vector[int]())    # assign it a std::vector<int>
<cppyy.gbl.boost.any object at 0xf6a8a0>
>>> val.type() == cppyy.typeid(std.vector[int])    # verify type
>>> extract = boost.any_cast[int](std.move(val))   # wrong cast
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: int boost::any_cast(boost::any&& operand) =>
    boost::bad_any_cast: failed conversion using boost::any_cast (C++ exception)
>>> extract = boost.any_cast[std.vector[int]](std.move(val))   # correct
>>> type(extract) is std.vector[int]
>>> extract += xrange(100)
>>> len(extract)
>>> val.__assign__(std.move(extract))    # move forced
<cppyy.gbl.boost.any object at 0xf6a8a0>
>>> len(extract)                         # now empty
>>> extract = boost.any_cast[std.vector[int]](std.move(val))
>>> list(extract)
[0, 1, 2, 3, 4, 5, 6, ..., 97, 98, 99]

And yes, there is no reason to use Boost from Python, but the example shows that cppyy seamlessly supports many advanced C++ features.

cppyy is available for both CPython (v2 and v3) and PyPy, reaching C++-like performance with the latter. It makes judicious use of precompiled headers, dynamic loading, and lazy instantiation, to support C++ programs consisting of millions of lines of code and many thousands of classes. cppyy minimizes dependencies to allow its use in distributed, heterogeneous, development environments.


Comments and bugs

Please report bugs or requests for improvement on the issue tracker.