Sunday, January 9, 2011

Python for PyObjC

This is a short post to document that I was able to download the Python.org's Framework build of Python 2.7 and then install matplotlib in it, as well as modify a Cocoa-Python application to link against that Framework. The only thing that looks a little shaky is the PyObjC install, but it still seems like it's working. Not every detail is given, but I hope it's enough.

The installer comes from here for python-2.7.1-macosx10.6.dmg (Mac Installer disk image (2.7.1) for OS X 10.6 and later).

I did a stock install except I unchecked Shell profile updater under Custom.. Not sure why, except I didn't want to spend time figuring out what it does.

Python.org installs stuff in


/Library/Frameworks/Pythonframework
/Applications
/usr/local/bin


I added this to .bash_profile


> export PATH=/$PATH:/Library/Frameworks/Python.framework/Versions/2.7/bin


I anticipated that easy_install would be difficult, but I got (something like) it from distribute:


> curl -O http://python-distribute.org/distribute_setup.py
> /usr/local/bin/python distribute_setup.py


I couldn't find any decent docs, though. It looks like they've just copied the easy_install documentation which I found impossible to figure out so far. But, poking around, I found easy_install and easy_install-2.7 in bin:


> which easy_install-2.7
/Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install-2.7


The way my $PATH is set up, easy_install runs the wrong Python. That's OK, we just do:


> easy_install-2.7 -U numpy
> easy_install-2.7 pyobjc==2.2
> easy_install-2.7 -U pip


pyobjc has lots of warnings but looks OK


> /usr/local/bin/python 
Python 2.7.1 (r271:86882M, Nov 30 2010, 10:35:34)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.__version__
'1.5.1'
>>> import objc
>>> objc.__version__
'2.2'
>>> from Foundation import *
>>>
[1]+ Stopped /usr/local/bin/python


Next, I installed matplotlib using instructions from Gavin Huttley (here, here). Since matplotlib-1.0.0 is available, I went for it. In the make.osx file:


PYVERSION=2.7
PYTHON=python${PYVERSION}
ZLIBVERSION=1.2.3
PNGVERSION=1.2.39
FREETYPEVERSION=2.3.11
MACOSX_DEPLOYMENT_TARGET=10.6
OSX_SDK_VER=10.6
ARCH_FLAGS="-arch i386-arch x86_64"


I changed it to Python 2.7.

I also needed to update to libpng-1.2.39 and libfreetype-2.3.11 (although these are not the latest versions.. In fact, I had a bit of trouble with libpng since I got back a file that was really html, though titled as .gz or .bz2 or .xz. I finally found it here). For the other one:


> FREETYPEVERSION=2.3.11
> curl -O http://ftp.twaren.net/Unix/NonGNU/freetype/freetype-{$FREETYPEVERSION}.tar.bz2


As I said, the build instructions were as given at the link.

[UPDATE: Poking around in libpng file INSTALL, I notice that it says: "Before installing libpng, you must first install zlib, if it is not already on your system." So I'll do it in that order next time.]

I tested matplotlib by running the script from here.

Then, I got PyCogent (download link):


> cd PyCogent-1.5
> /usr/local/bin/python setup.py build
> sudo /usr/local/bin/python setup.py install
>>> from cogent import *
>>>
[2]+ Stopped /usr/local/bin/python



> cd tests
> /usr/local/bin/python alltests.py "$@"


I had a few failures:


Ran 3602 tests in 184.766s

FAILED (failures=12, errors=4)


Some of these are related to executables not present. Looks pretty good. Finally, let's setup a new Xcode project:

Xcode > Cocoa-Python application

change SDK to 10.6
delete Python.framework
drag in new Python.framework
under Targets > X > Link Binary ..
drag in new Python.framework


Since our Python is a universal binary with 64-bit:


> /usr/local/bin/python
Python 2.7.1 (r271:86882M, Nov 30 2010, 10:35:34)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; print hex(sys.maxint)
0x7fffffffffffffff
[2]+ Stopped /usr/local/bin/python
> /usr/local/bin/python -c "import struct; print struct.calcsize('P')"
8
> /usr/local/bin/python -c "import platform; print platform.architecture()"
('64bit', '')


Build the Xcode project as 64-bit as well. Add this to main.py:


import sys
print sys.version
print hex(sys.maxint)


And run it from the Console:


2.7.1 (r271:86882M, Nov 30 2010, 10:35:34) 
[GCC 4.2.1 (Apple Inc. build 5664)]
0x7fffffffffffffff

It works!