2007-05-31

python bindings generator

For the ns-3 project, I've been trying for some time to create some Python bindings. I've been using Py++, which uses gccxml to parse C++ header files and automatically generates Boost.Python code that tries to wrap it.

Py++ is really nice. Unfortunately Boost.Python isn't nearly at the same level. Boost.Python is heavily built on C++ templates. Mastering C++ templates is Hard™. Everything Boost does is practically black magic to me. While using Py++, Boost.Python has been fighting with me every step of the way, and winning too!

I decided to move away from Boost once and for all. Some of the non-boost alternatives I could find were:
  1. Python-SIP: the code generator itself is written in C++; that doesn't make any sense! I want something I can easily hack;
  2. SWIG: also made in C/C++, and in addition generates very ugly code, almost unreadable with so much macro abuse;
  3. The PyGtk code generator. I know this one very well :) Unfortunately it has some problems, the biggest of which is that it doesn't support C++ classes, while the ns-3 code I want to wrap is pure C++.
So, in the end, there really isn't any good python bindings generator tool out there. I decided to create my own. I've set myself the following goals for my forthcoming tool:
  • Must be written in pure Python, and in good pylint-checked style;
  • Must have unit tests;
  • It should have a simple python API to generate the code, other frontends (such as header file scanning) optional and layered on top of the python API;
  • Must be easily extensible to handle new types, with strong focus on correct memory management of type convertion code;
The project is called PyBindGen (yes, I'm from a school of thought that believes project names should be descriptive of their function). First pre-alpha release is ready, supporting generation of modules with only functions, and only the basic python types. However it already supports something not supported by pygtk-codegen: out/inout parameters and, consequently, multiple return values.


bzr (0.15) branch: http://telecom.inescporto.pt/~gjc/pybindgen/bzr
Releases: http://telecom.inescporto.pt/~gjc/pybindgen/releases
Launchpad (bug reporting, etc.): https://launchpad.net/pybindgen/

The project uses WAF to build; Running "./waf" should be enough to build the example. "./waf check" should be able to run the unit tests.