installing GNU gettext for use with Python on OS X

I’ve been working on my blog post about Python’s gettext module for the past couple of mornings, and ran into a snag. The documentation claims that the Python source distribution includes all the tools you’ll need, but when I got to the point where I wanted to write examples of internationalizing plural strings, pygettext.py wasn’t working.

It worked great for extracting individual string messages up to that point, but refused to extract messages wrapped in the ungettext() call, even when I used what seemed to be the appropriate command line options. I ended up installing the GNU gettext tools and using xgettext instead. Installation took me longer than I expected, so I’m documenting the process I went through here.

Fink or MacPorts: Not so much.

Since OS X doesn’t ship with a version of gettext by default, and there doesn’t seem to be one in the Xcode package (Apple has their own internationalization tools), I needed to find a copy elsewhere.

Ages ago I had installed fink as an “easy” way to grab copies of these sorts of utilities. However, it seems that somewhere along the line the version of fink I have stopped working (probably due to upgrading to 10.5, I haven’t tried using fink or FinkCommander directly in some time). After wiping and reinstalling, I was pleased to find a slightly old version (0.14.5) of gettext installed as part of the default set of packages. Unfortunately, xgettext wasn’t included in the package at all.

Next, I grabbed a copy of MacPorts, a competitor to fink. Although I’ve been warned off of MacPorts by a few people I trust, others have had no problems with it. Installation was fairly easy, and as with fink it installed everything to its own directory tree (under /opt/local). Once I had the port program installed, the next step was to run:

$ sudo port install gettext

It downloaded several dependencies, patched the source, compiled everything, and installed it. Voila! Well, not so much.

Even though the most current version of gettext (0.17) was installed, and the documentation clearly described the included Python language support, the binary refused to recognize any language other than C.

Scratch that.

Compiling from Source: Partial Success

Since MacPorts had to download the package and compile it anyway, I decided to go ahead and do that on my own. I was a little wary because I wasn’t exactly sure what port was doing in its “patching” step, but I thought I would give it a try anyway. I snagged the most recent tarball from the gettext site and ran the usual

$ ./configure
$ make

That gave me a binary for xgettext inside the source directory, and testing it against my Python source yielded the results I wanted. A simple .pot file was extracted with the original message strings and placeholders for singular and plural translations.

Next, I thought I’d get clever and install the results into the virtualenv I use for working on PyMOTW. Re-configuring with my --prefix set to $VIRTUAL_ENV, rebuilding, then running make install copied the binaries and a bunch of associated data files right where I expected them to be. And the binary only recognized the C language.

After a little more fighting, I did manage to get it working by installing with a prefix of $VIRTUAL_ENV/gettext and adding $VIRTUAL_ENV/gettext/bin to my PATH. I’m not sure if the problem was solved by clearing out an older, bad version of xgettext from elsewhere in my path or if using $VIRTUAL_ENV as the prefix somehow confused the install script.

Conclusion: I think I understand why internationalization is frequently the last feature dealt with in a project.