13 August 2012

How to run py2app on OSX 10.8 Mountain Lion and Python 3.2

This post is for teh Google and all poor souls trying to use py2app on Mountain Lion.

To make it short, the latest official release of py2app does not work with ML and Python 3.2, you have to get the current development snapshot. Unfortunately, py2app requires a number of smaller libraries written by his developer, Ronald Oussoren, and most of them have to be upgraded as well (and before you curse his name: he's single-handedly maintaining py2app, pyObjC and virtualenv-mac; what have you done recently for the community?).

So here's my recipe:

  1. Clone all required repos.
    Oussoren uses Bitbucket, which is better accessed through Mercurial (hg); you can get hg from your favourite package manager (Homebrew/MacPorts/Fink/whatever).
    Then:
    hg clone https://bitbucket.org/ronaldoussoren/altgraph
    hg clone https://bitbucket.org/ronaldoussoren/macholib
    hg clone https://bitbucket.org/ronaldoussoren/py2app
    
  2. Install the packages. Since you're basically tracking trunk, you should probably use the develop mode of setuptools:
    cd altgraph && python setup.py develop && cd ..
    cd macholib && python setup.py develop && cd ..
    cd py2app && python setup.py develop && cd ..
    Note that this means you'll have to keep these "source" folders available forever. If you don't like that, you should create an egg (e.g. python setup.py bdist_egg), then install it (easy_install dist/your-resulting.egg).

    For the record, altgraph will present itself as version 0.10, macholib as 0.7, and py2app as 1.5.
  3. Now you should be able to run your python setup.py py2app

Bonus achievement: if you're using PyQt, this version of py2app will give you Retina-ready packages, by automatically adding the NSPrincipalClass key to the generated Info.plist and setting it to NSApplication. Nice one, Roland!

2 comments:

greg Luce said...

Oh my goodness thank you so much for this. I was tearing my hair out trying to figure out how to do this.

Some notes in case they help others:
I was doing this on Lion with Python 3.2 installed as separate from Python 2.7 on the system, so all my commands had to be "python3" at the terminal rather than "python" (I think?)

Also it complained that it needed modulegraph as well

so: after installing Python 3.2 from http://www.python.org/download/releases/3.2.3/ and mercurial from http://mercurial.selenic.com/

I did

hg clone https://bitbucket.org/ronaldoussoren/altgraph
hg clone https://bitbucket.org/ronaldoussoren/macholib
hg clone https://bitbucket.org/ronaldoussoren/modulegraph
hg clone https://bitbucket.org/ronaldoussoren/py2app

cd altgraph && python3 setup.py develop && cd ..
cd macholib && python3 setup.py develop && cd ..
cd modulegraph && python3 setup.py develop && cd ..
cd py2app && python3 setup.py develop && cd ..

Then for some reason the file /py2app/py2app/recipes/pyside.py had on line 42 the line
print "resources", resources
which I had to change to
print("resources", resources)

And then
py2applet --make-setup [SCRIPTNAME].py
python3 setup.py py2app

There's a chance it required Distribute from http://pypi.python.org/pypi/distribute to work properly, since setuptools I don't think properly supports Python 3 yet.

Also I found that the actual script I was using was meant to run only in the terminal with input() commands, so I had to Show Contents on the resulting .app file and run the terminal scripts inside Contents/MacOS

Also if you copy the files out of the .app you have to keep the root called Contents otherwise it doesn't work

Anyways thanks again! You're a lifesaver!

toyg said...

Hi greg, I'm happy to see the post was useful!

Just to clarify, I wrote "python" rather than "python3" because I was doing everything in a virtualenv where Python 3 was the only interpreter. Virtualenv installs pip by default, which might be why I didn't need Distribute (?).

For the record, I wasn't very lucky with py2app and PyQt, the resulting package was very very crashy. I hope it'll work out better for your needs.