ActivePython: multiple versions on OSX?
Ned Deily
nad at acm.org
Tue Jul 26 14:41:07 EDT 2011
In article
<CAL_Nh-xfr50Unhz-5otoNa6qai1P+8_+z0cJfrLXF1tbNgP21w at mail.gmail.com>,
Melton Low <softw.devl at gmail.com> wrote:
[...]
> On Mac OS X, a link is automatically installed in /usr/local/bin for each
> version of the Python executables, ie python2.7 for the 2.7.x and python3.2
> for 3.2.x. Just invoke your script with the appropriate Python version.
> eg. python3.2 yourscript to run 'yourscript'.
Yes, the default action for the python.org OS X installers is to install
the /usr/local/bin version specific links. However, that is not a
complete solution for managing framework versions. The main problem is
that, again by default, Distutils-packaged scripts are installed into
the framework bin directory. This means there is no ambiguity or
conflict among the same package/script installed in different versions
of Python - a good thing - but it also means the proper way to manage
which Python is invoked by `python` or by `python3` (and `python2 in the
future when PEP 394 is approved and implemented) is by ensuring the
desired "primary" version's framework bin directory comes first on the
shell PATH environment variable. The python.org installers provide a
script to do that, although somewhat crudely.
Let's say I've used the python.org 2.6, 2.7, and 3.2 installers (and
deselected the option to automatically update the shell scripts) and
then use Distribute to install easy_install into those instances. There
is also an Apple-supplied Python 2.6 and easy_install (and
easy_install-2.6) in /usr/bin.
$ curl -O http://python-distribute.org/distribute_setup.py
$/usr/local/bin/python2.6 distribute_setup.py
$/usr/local/bin/python2.7 distribute_setup.py
$/usr/local/bin/python3.2 distribute_setup.py
$ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
$ which python python2.6 python2.7
/usr/bin/python
/usr/bin/python2.6
/usr/local/bin/python2.7
$ which easy_install easy_install-2.6 easy_install-2.7
/usr/bin/easy_install
/usr/bin/easy_install-2.6
# note that there is no access to the easy_install-2.7
# nor to the correct easy_install-2.6 for the python.org 2.6
$ open /Applications/Python\ 2.6/Update\ Shell\ Profile.command
$ bash -l
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/2.6/bin:/usr/bin:/bin:/usr/
sbin:/sbin:/usr/local/bin:/usr/X11/bin
$ which python python2.6 python2.7
/Library/Frameworks/Python.framework/Versions/2.6/bin/python
/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
/usr/local/bin/python2.7
$ which easy_install easy_install-2.6 easy_install-2.7
/Library/Frameworks/Python.framework/Versions/2.6/bin/easy_install
/Library/Frameworks/Python.framework/Versions/2.6/bin/easy_install-2.6
$ open /Applications/Python\ 2.7/Update\ Shell\ Profile.command
$ bash -l
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frameworks
/Python.framework/Versions/2.6/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/loc
al/bin:/usr/X11/bin
$ which python python2.6 python2.7
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
$ which easy_install easy_install-2.6 easy_install-2.7
/Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install
/Library/Frameworks/Python.framework/Versions/2.6/bin/easy_install-2.6
/Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install-2.7
# Now "easy_install" refers to the 2.7 version just as "python" does.
Python 3 instances work similarly although, since Apple does not yet
ship a system Python 3, there is no conflict with /usr/bin and the
Python 3 framework bin directories include "python3" links instead of
"python" ones, so there is also no conflict with Python 2 instances.
$ open /Applications/Python\ 3.2/Update\ Shell\ Profile.command
$ bash -l
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/3.2/bin:/Library/Frameworks
/Python.framework/Versions/2.7/bin:/Library/Frameworks/Python.framework/V
ersions/2.6/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
$ which python python2.6 python2.7 python3 python3.2
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
/Library/Frameworks/Python.framework/Versions/3.2/bin/python3
/Library/Frameworks/Python.framework/Versions/3.2/bin/python3.2
$ which easy_install easy_install-2.6 easy_install-2.7 easy_install-3.2
/Library/Frameworks/Python.framework/Versions/3.2/bin/easy_install
/Library/Frameworks/Python.framework/Versions/2.6/bin/easy_install-2.6
/Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install-2.7
/Library/Frameworks/Python.framework/Versions/3.2/bin/easy_install-3.2
But here is a potential gotcha! Distribute does not provide a
"easy_install3" link when installing into a Python 3 instance so now the
unversioned "easy_install" command refers to the Python 3.2 version,
which may not be what you expected. You can change the search order of
PATH:
$ export
PATH=/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frame
works/Python.framework/Versions/2.6/bin:/Library/Frameworks/Python.framew
ork/Versions/3.2/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X1
1/bin
$ which easy_install easy_install-2.6 easy_install-2.7
easy_install-3.2/Library/Frameworks/Python.framework/Versions/2.7/bin/eas
y_install
/Library/Frameworks/Python.framework/Versions/2.6/bin/easy_install-2.6
/Library/Frameworks/Python.framework/Versions/2.7/bin/easy_install-2.7
/Library/Frameworks/Python.framework/Versions/3.2/bin/easy_install-3.2
To make this change permanent, you would need to edit the appropriate
shell startup file, for example, .bash_profile. Or be careful about the
order in which you run the Update Shell Profile commands in the first
place.
When in doubt, you can always use the version-specific name (in this
case that works but most Python packages do not provide version specific
links) or you can use an absolute path. There are, of course, other
strategies for dealing with the third-party packages in case of
ambiguities, for example using virtualenvs or using Distutils alternate
installation options, like --home.
The situation gets more complex if you have installed Pythons from
distributors other than python.org; these may be installed in the same
or in different locations and may or may not be framework builds. But
the general principles still apply.
The current state is not ideal, especially for new users of Python. I'm
hoping we can make life a bit easier by the time 3.3 is released next
year.
--
Ned Deily,
nad at acm.org
More information about the Python-list
mailing list