#74: Building just readline.so for Python on OS X

I want to build the readline.so module for my Python install, and link it to an installation of GNU readline. As much as I dislike the entire "what's Free" argument about this nonsense, readline simply works better with packages such as IPython than the crummy libedit alternative.

And I don't want to compile the entire Python package for one measly shared object file.

The easy way

sudo easy_install readline

The hard way

Grab a copy of the Python source code corresponding to the version you want. The stock 10.6 operating system ships with Python 2.6.1, so you'll want to grab the tarball from the reference site below.

Unpack it and go into the Modules/ subdirectory within the unpacked source directory. There you'll find readline.c.

Compile readline.c into a shared object via:
gcc -O2 -arch x86_64 -arch i386 -shared -o readline.so readline.c -I/usr/local/include -I/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6 -L/usr/local/lib -lreadline -ltermcap -framework Python

where the -arch flags are set appropriately for your environment, the -I points to the header files for readline, and the version numbers are set for your Python version. This should yield readline.so.

To override the stock readline.so that uses libedit, DO NOT overwrite it. As a rule, never overwrite system-provided files on OS X unless you absolutely know what you're doing. The reason is: on a system update, it'll either be clobbered by the update installer, or worse, it'll interfere with the update.

You should create a subdirectory in /Library/Python/2.6/site-packages (I called it lib-dynload, corresponding with the structure in /System/Library). Then, prepend the new directory to the sys.path.

One way to do this is to add a line in /Library/Python/2.6/site-packages/easy_install.pth, pointing to /Library/Python/2.6/site-packages/lib-dynload. This forces your custom-compiled readline.so to be loaded before the system readline.so.

And now, enjoy a non-buggy readline implementation in IPython.

Think you've got a better solution? Help 92049143cabb7ba896d7c06e19906303_small yliu out by posting your solution