After starting out with Python on Ubuntu Linux, I've now for a good while been doing most of my sustained work on the Mac, currently Mac OS X 10.6. Unfortunately I've neglected to give proper attention to how Python is installed there and ended up with:
/usr/bin
(also, 2.5.4, which I'm not sure how it got there)/opt/local/bin/
. This is my defaultpip
to install libraries, which end up in some ungodly place (something like /opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/
- SRSLY?)Now I'm preparing to set up 2.7 and 3.2, and I am unhappy with the haphazard state of things. So what are your favourite approaches to organising the code and libraries, and how have you wrestled the Mac into submission?
I'd like to continue using pip
, but would like to have more control or at least understanding of what libraries for which version are getting installed and made accessible from where: I've had problems with installing py.test
via pip
and only being able to load it from the obsolete 2.6.1 Python, not my current 2.6.5 one. MacPorts has python_select
, but it's not overly helpful:
reason: chris$ python_select -l
Available versions:
current none python26 python26-apple
Most Python people I've asked don't use MacPorts, which I don't much like, but the stock Mac Python from python.org
. I've also heard the recommendation to use virtualenv
systematically, so what is the link to a good practical introduction?
virutalenv
is a great tool and is very useful for managing multiple Python instances on most platforms. On Mac OS X, though, things are more complicated because the use of framework builds makes it common to encounter multiple instances of even the same major version of Python. I suggest you first understand and be comfortable with how to manage framework installs on Mac OS X before delving into virtualenv
.
"/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/
- SRSLY?"
Yes, that's the default location within a Python Mac OS X framework build. Most distributors of Python on Mac OS X use a framework build, each generally using a different root, because it makes it simpler to support multiple versions and to keep all the site packages installed for a particular Python instance together in one place.
For Mac OS X 10.6, Apple supplies a Python 2.6 (rooted at /System/Library/Frameworks/Python.framework
and symlinked to /usr/bin/python2.6
) as well as a Python 2.5 (for compatibility with Mac OS X 10.5 - that's the /usr/bin/python2.5
you see). The python.org Mac OS X installers install to /Library/Frameworks/Python.framework
. MacPorts uses /opt/local/Library/Frameworks/Python.framework
.
The frameworks include a bin
directory (at ../Versions/x.x/bin
in the framework); this is normally the default location where package scripts will be installed. It's also where symlinks to the interpreter binaries are placed.
Here's a look at a python.org-style framework with multiple versions of Python installed:
$ cd /Library/Frameworks/Python.framework/Versions/
$ ls -l
total 8
drwxrwxr-x 8 root admin 340 Dec 23 2008 2.5/
drwxrwxr-x 8 root admin 340 Aug 10 21:42 2.6/
drwxrwxr-x 8 root admin 340 Jul 3 12:24 2.7/
drwxrwxr-x 7 root admin 306 Mar 23 17:42 3.1/
drwxrwxr-x 7 root admin 306 Aug 10 22:14 3.2/
lrwxr-xr-x 1 root admin 3 Aug 10 21:47 Current@ -> 2.6
$ cd 2.6
$ ls -l
total 7776
lrwxr-xr-x 1 root admin 17 Aug 10 21:47 Headers@ -> include/python2.6
drwxrwxr-x 3 root admin 102 Aug 10 21:42 Mac/
-r-xrwxr-x 1 root admin 3973552 Aug 10 21:41 Python*
drwxrwxr-x 4 root admin 170 Aug 10 21:48 Resources/
drwxrwxr-x 2 root admin 578 Aug 12 15:19 bin/
drwxrwxr-x 3 root admin 102 Aug 10 21:42 include/
drwxrwxr-x 3 root admin 646 Aug 10 21:43 lib/
drwxrwxr-x 3 root admin 102 Aug 10 21:41 share/
$ ls -l bin
total 264
-rwxrwxr-x 1 root admin 150 Aug 10 21:41 2to3*
-rwxr-xr-x 1 nad admin 360 Aug 12 15:19 easy_install*
-rwxr-xr-x 1 nad admin 368 Aug 12 15:19 easy_install-2.6*
lrwxr-xr-x 1 root admin 7 Aug 10 21:47 idle@ -> idle2.6
-rwxrwxr-x 1 root admin 138 Aug 10 21:41 idle2.6*
lrwxr-xr-x 1 root admin 8 Aug 10 21:47 pydoc@ -> pydoc2.6
-rwxrwxr-x 1 root admin 123 Aug 10 21:41 pydoc2.6*
lrwxr-xr-x 1 root admin 9 Aug 10 21:47 python@ -> python2.6
lrwxr-xr-x 1 root admin 16 Aug 10 21:47 python-config@ -> python2.6-config
-rwxrwxr-x 1 root admin 29584 Aug 10 21:43 python2.6*
-rwxrwxr-x 1 root admin 1463 Aug 10 21:42 python2.6-config*
lrwxr-xr-x 1 root admin 10 Aug 10 21:47 pythonw@ -> pythonw2.6
-rwxrwxr-x 1 root admin 29584 Aug 10 21:43 pythonw2.6*
lrwxr-xr-x 1 root admin 11 Aug 10 21:47 smtpd.py@ -> smtpd2.6.py
-rwxrwxr-x 1 root admin 18272 Aug 10 21:41 smtpd2.6.py*
Here's a MacPorts bin
including a number of additional site packages:
$ cd /opt/local/Library/Frameworks/Python.framework/Versions/2.6
$ ls -l bin
total 952
-rwxr-xr-x 2 root wheel 160 Jul 15 01:56 2to3*
-rwxr-xr-x 2 root wheel 1541 Jun 8 19:59 apirst2html.py*
-rwxr-xr-x 2 root wheel 363 Oct 5 2009 bdist_mpkg*
[...]
-rwxr-xr-x 2 root wheel 211 Jun 2 12:45 django-admin.py*
-rwxr-xr-x 2 root wheel 410 Jul 15 17:30 easy_install*
-rwxr-xr-x 2 root wheel 418 Jul 15 17:30 easy_install-2.6*
[...]
-rwxr-xr-x 2 root wheel 368 Jun 24 02:00 pip*
-rwxr-xr-x 1 root wheel 342 Sep 18 2009 pkginfo*
[...]
lrwxr-xr-x 1 root wheel 9 Jul 15 01:58 python@ -> python2.6
lrwxr-xr-x 1 root wheel 16 Jul 15 01:58 python-config@ -> python2.6-config
-rwxr-xr-x 2 root wheel 24932 Jul 15 01:57 python2.6*
-rwxr-xr-x 2 root wheel 1473 Jul 15 01:57 python2.6-config*
[...]
If you install 2.7 or 3.1 Pythons using python.org installers or MacPorts, they are all rooted under /Library/Frameworks
or /opt/local/Library/Frameworks
and will happily co-exist with other versions. To successfully use framework installs, you need to manage your shell PATH
. In particular, you should ensure that the framework bin
directory of the Python(s) you want to use are on your PATH
. So for MacPorts, something like this in ~/.bash_profile
:
export PATH="/opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin:/opt/local/bin:$PATH
or for the python.org installers:
export PATH="/Library/Frameworks/Python.framework/Versions/2.6/bin:$PATH
In addition, generally you need to install a separate version of your favorite Python package management add-ons (like pip
or the easy_install
command from Distribute
or setuptools
) for each Python instance you use. Each one is installed into the default script directory (i.e. the framework bin
directory). MacPorts takes care of that automatically when you install its version of the package (sudo port install py26-pip
or sudo port install py31-distribute
). Note that Apple supplies a set of easy_install
links in /usr/bin
for its Pythons and they install packages to /Library/Python
. You need to make sure you use the easy_install
or pip
appropriate for your instance of Python. Making sure the instance's framework bin
directory is first in the PATH
ensures that.
Note, if you use MacPorts you can use its python_select
command to manage which Python instance is pointed to by /opt/local/bin/python
. Then if /opt/local/bin
appears earlier in your PATH list than other directories with a python
it will govern which is your default python
. But you really need to manage the PATH by adding the framework bin
directory so python_select
is generally not all that useful.
Another positive aspect of using MacPorts (or similar broad-based distributor) is that it makes available many popular Python packages including handling the occasional messy details of building and linking to 3rd-party C libraries not shipped with Mac OS X. For example, the MySQLdb
and PIL
packages are frequent stumbling blocks on Mac OS X because of the MySQL client libraries and libjpeg
, but MacPorts makes it much easier to get everything right. But you do have the choice to install things directly using MacPorts (sudo port py26-pil
) or via pip
(sudo pip install pil
) or easy_install
, or you can download the source, and do it yourself (sudo python setup.py ...
). And because all of them under the covers use Python's Distutils
to do the dirty work, all of these methods will generally end up installing a package's files in the same place for a given Python instance.