Oracle and Python on OS X Mountain Lion

I had been running OS X Snow Leopard, released on August 28th, 2009, relatively happily for many years and never saw the need to upgrade to newer incarnations of Apple's operating system. With Snow Leopard Apple focussed on under the hood changes and not so much on end user features. A laudable effort as many small and not so small things just did not work correctly; better make what's already there work than introduce more broken features.

That all changed with OS X Lion, released on July 20th, 2011. Lion was not particularly well received. It was buggy and presented Apple's first forays into dumbing OS X down to iOS levels. OS X Mountain Lion continued that effort but supposedly did solve many of Lion's issues.

The other day I was handed a relatively new MacBook Pro to be my main development machine at work. It ran Lion and might have run Snow Leopard, but I opted for installing Mountain Lion. One can only postpone the inevitable for so long.

Although some people strongly prefer HomeBrew, I am generally happy with MacPorts. It works just fine. Though it does require you to have installed Apple's Xcode Developer Tools and Apple's Command Line Developer Tools.

With MacPorts installing Python, and some basic tools, is a simple matter of:

$ sudo port install python26 py26-distribute py26-pip py26-virtualenv

Yes I know, I'm stuck at version 2.6 for deployment reasons out of my control.

For a particular project I needed to connect to an Oracle database. In order to install the Python interface to Oracle, cx_Oracle, in my virtualenv I needed to install the Oracle Instant Client first. Running on a 64 bit processor (Intel Core i7) and a 64 bit operating system with a 64 bit version of Python installed as demonstrated by:

$ python -c 'import struct;print( 8 * struct.calcsize("P"))'

I, logically, choose the 64 bit version of the Oracle Instant Client. Big mistake!

Even though cx_Oracle installed just fine. Executing code that tries to connect to the Oracle database consistently resulted in a segmentation fault 11 error message.

Under Snow Leopard, that I had running in 64 bit mode as well, this worked without any issues. Though in Mountain Lion and supposedly in Lion the Oracle Instant Client cannot be run in 64 bit mode. Fortunately I don't have strict requirements to run this particular application in 64 bit. So the solution is simple; use the 32 bit Oracle Instant Client and run Python in 32 bit mode.

The latter turned out to not so obvious. How do I tell MacPorts to build me a 32 bit version of Python? And how do I tell pip to build me 32 bit library?

Building 32 bit ports using MacPorts

Contrary to the Apple provided binary of the Python interpreter, the binaries as built by MacPorts do not contain both a 32 bit and a 64 bit version. MacPorts builds a 64 bits version if it is in a 64 bit environment. To tell it we want it to built a 32 bit version we need to edit macports.conf

$ sudo mvim /opt/local/etc/macports/macports.conf

And uncomment the line:

#build_arch        i386

From this moment on MacPorts will build 32 bit binaries exclusively.

Building 32 bit libraries using pip

Without any extra information, pip too, builds 64 bit libraries for those libraries that need C extensions to be built. To tell it we want a 32 bit library instead we run pip as follows:

$ ARCHFLAGS="-arch i386" pip install cx-Oracle

To make this the default we can add the variable ARCHFLAGS="-arch i386" to our shell environment by adding it to our shell startup scripts.

Now we can connect to Oracle without any issues.

Comments !