Abandoned Wig
Hi, I'm Martin.
I work on the Web Platform at Igalia.

Embedding Python in D

01 January 2009
It's some snakes.
It's some snakes.

A while back I began spending some time acquainting myself with D. For those who don't know, D is a relatively new system programming language with all kinds of interesting features like very flexible garbage collection, mixins and an easy-to-use yet powerful template system. D was created by Walter Bright, who also created the first native C++ compiler and Empire (of all things).

Anyhow, one of the things that I really like about D is that it is maintains link compatibility with C 1. This means that D code can make calls into libraries like those from GTK in the same way that C++ code can. This mitigates the need or the desire to rewrite useful tools. Many times simple binding layers can be written to expose C-style APIs in D-style ways.

In my case, I'm writing an application which uses the GTK bindings for D, GtkD, and embeds a Python interpreter. Creating the D header from Python.h turns out to be pretty easy with bcd, a tool which tries to automate most of the process 2.

The first step is to run bcd against the header you want to use. For me this looked like:
./bcdgen /usr/include/python2.5/Python.h Python -C -A
In this case "-C" means "C-mode" (as opposed to C++-mode) and "-A" tells bcdgen to continue working on all includes recursively (since Python.h is really a meta-header). Unfortunately this gives me:
In file included from /usr/include/stdio.h:906,
from /usr/include/python2.5/Python.h:32:
/usr/include/bits/stdio2.h: In function 'int sprintf(char*, const char*, ...)':
/usr/include/bits/stdio2.h:35: error: '__builtin_va_arg_pack' was not declared in this scope
/usr/include/bits/stdio2.h: In function 'int snprintf(char*, size_t, const char*, ...)':
This is a bug with Intrepid Ibex's version of gccxml. Luckily there are workarounds. Once bcdgen finishes it's work, it should create a bcd/Python/Python.d, which is where all the Python.h definitions landed. If you open it up and take a look, you can see bcdgen has converted them to D definitions. Way to go automated software development tools!

Generally some work is required before the D compiler accepts this file and the bcd page lists some general guidelines for this task. I'm familiar with Python's C interface, but definitely not intimate. This is a secret code that I'm using which means I spent a bit of time fixing weird D compiler errors. It wasn't bad though and I was was able to resolve most of the compile errors without much trouble. I'm my next post I'll write a little bit about that.

  1. D does not have link compatibility with C++. Many C++ projects have have external APIs which are C-compatible though. One example from recent memory is the KJS API from WebKit.

  2. There is a really great project called CeleriD, which has already done a lot of this work. CeleriD is really geared toward extending Python rather than embedding it though. I decided to strike out on my own as an educational gesture3 and to avoid depending on distutils for my build process.

  3. Gesture because it's hard to believe this is can be considered larnin'4, which is coincidentally the way I feel about most professional software training programs.

  4. The best thing about the <sup> tag is that it's a formatting markup and a greeting. 'Sup <sup>?