python c++ apis on - europython · c++ apis on python austin bingham ... c-api boost.python. python...

43
C++ APIs on Python Austin Bingham Roxar Software Solutions [email protected]

Upload: duongnhu

Post on 30-Aug-2018

258 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C++ APIs on PythonAustin BinghamRoxar Software [email protected]

Page 2: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object
Page 3: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object
Page 4: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Concept

Page 5: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Python extension module

C/C++ library

Page 6: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C-APISWIGctypes

boost.python

Page 7: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C/C++ application

Python interpreter

Page 8: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C-API boost.python

Page 9: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Python module

C/C++ application

C/C++ wrapperlibrary

Page 10: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Natural, idiomatic C++ APIs built on Python implementations.

Goal

Page 11: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

import loggingimport sys

logging.basicConfig()log = logging.getLogger()

log.addHandler( logging.StreamHandler())

log.addHandler( logging.StreamHandler( sys.stdout))

Page 12: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

#include <logging.hpp>

void initLogging() { basicConfig(); Logger log = getLogger();

// This handler will log to stderr log.addHandler(handlers::StreamHandler());

// This will log to stdout log.addHandler( handlers::StreamHandler( boost::python::import("sys") .attr("stdout")));}

Page 13: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Motivation

Page 14: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Expressiveness and productivity

print('Hello, world.')

vs.

#include <iostream>

int main(int, char**) { std::cout << "Hello, world." << std::endl; return 0;}

Page 15: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Edit, Compile, Run, Debug

Page 16: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Access Python modules

● logging● uuid● re● difflib● shutil● template engines

...and so on

C++

Page 17: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Existing C/C++ code

Probably the encompassing reason that you would want to use the techniques in this presentation.

Page 18: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Progression

Page 19: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C/C++ application

C/C++ library

Page 20: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

C/C++ application

C/C++ wrapper library

Python module

Page 21: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Python application

Python module

Extension

main()C/C++ library

Page 22: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Python application

Python module Python module

Page 23: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Techniques

Page 24: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Code structure

lib_mypackage.so

mypackage

namespace mypackage { . . . }

Page 25: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Module initializationnamespace mypackage { void initialize() { bp::object mod = bp::import("mypackage");

// register type-conversion

// anything else: create // loggers, etc. }}

Page 26: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Type conversion

How do we get objects across the Python-C++ boundary?

The key is often to remember that PyObjects are wholly legitimate C-level entities. There is no magic.

Page 27: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Type conversion: A simple model

C++ class

bp::object obj_;

PyObject

Page 28: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Type conversion: to C++

inspectionPython to C++

if (PyObject_IsInstance(obj, class_obj)) return new T( object( handle<>( borrowed( obj))));

Page 29: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Type conversion: to Python

templatesC++ to Python

template <typename T>struct to_python_object_{ static PyObject* convert(const T& t) { return boost::python::incref( t.obj().ptr()); }};

Page 30: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Type conversion: registration// Register from-python converterboost::python::converter::registry::push_back( &convertible, &construct, boost::python::type_id<MyType>());

// Register to-python converterboost::python::to_python_converter< MyType, to_python_object_<MyType> >();

// Covert from Python to C++MyType x = boost::python::extract<MyType>(obj);

// Convert from C++ to Python (implicit in bp::object constructor)python_class.attr("doit")(x);

Page 31: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Exceptions: with C-API

PythonAPI_Foo();if (PyErr_Occurred()) respondToPythonException();PythonAPI_Bar();if (PyErr_Occurred()) respondToPythonException();

Page 32: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Exceptions: error_already_set

Pythonexception

bp::error_already_set

try { some_class.attr("method")(3);}catch (const bp::error_already_set&) { // Some exception has been thrown in Python throw SomeException();}

Page 33: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Exception translation

PyObject *t, *v, *tb;PyErr_Fetch(&t, &v, &tb);

// Check if it's a ValueErrorif (PyErr_GivenExceptionMatches( value_error_class_obj, t)){ throw ValueError();}

Page 34: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Exception translation

// The easy way!try { some_python_function();}catch (const bp::error_already_set&) { ackward::core::translatePythonException();}

Page 35: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Iteration

There's a very natural mapping between C++ and Python iterators

● C++ iterator holds a Python iterator reference● Incrementing iterator calls next(iter)and

stores values● StopIteration is caught in increment● The "end" iterator simply has a None Python

iterator

Page 36: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Duck Typing vs. Static Typing

mypackage::DatabaseC++

Python

mypackage.DB

mypackage.DBProxy

pkg2.FancyDB

Page 37: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Other stuff

● Enumerations● Const-ness● Properties● Tuples● Kwargs● Subclassing● Lifetime management

Page 38: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Interesting Bits

Page 39: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Debugging the full stack

C++ application

C++ wrapper library

Python module

C/C++ library

debug?!

● pdb.set_trace()● gdb with python

extensions● VisualStudio python

support (?)● SIGINT to break

debugger● Common logging● Debugging individual

layers

Page 40: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Debugging: Pythonizing the App

main() extension

C++ wrapper library

Python module

C/C++ library

Python application pdb

gdb

attach

Page 41: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Performance

● Python function call overhead can cause problems.

● Be aware of unnecessary data copies.● Learn the buffer and memoryview APIs

In general, the 80/20 principle works in your favor. Performance is not an issue for most code, and when it is you can bring many tools to bear.

Page 42: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

References

● Boost.Python http://www.boost.org/doc/libs/1_49_0/libs/python/doc/index.html

● Ackward code.google.com/p/ackward/

● Type conversion misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/

● Exception translation misspent.wordpress.com/2009/10/11/boost-python-and-handling-python-exceptions/

Page 43: Python C++ APIs on - EuroPython · C++ APIs on Python Austin Bingham ... C-API boost.python. Python module ... // Convert from C++ to Python (implicit in bp::object

Contact

twitter: @austin_binghamemail: [email protected]