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;
... };""")
True
>>> 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;
... }""")
True
>>> 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
True
>>> 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]
True
>>> extract += xrange(100)
>>> len(extract)
100
>>> val.__assign__(std.move(extract))    # move forced
<cppyy.gbl.boost.any object at 0xf6a8a0>
>>> len(extract)                         # now empty
0
>>> 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.

Contents:

Comments and bugs

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