Search code examples
pythonpython-3.xmacports

MacPorts says I still have Python 2.7 when "python --version" is run


After instructing MacPorts to switch to Python 3.4, python --version still outputs 2.7.10. Note that "which python" does show that /opt/local/bin is coming before /usr/bin/ in my PATH:

$ which python
/opt/local/bin/python
$ python --version
Python 2.7.10
$ ls -l /opt/local/bin/python
lrwxr-xr-x  1 root  wheel  24 Aug  1 10:00 /opt/local/bin/python -> /opt/local/bin/python2.7
$ sudo port select --list python
Available versions for python:
    none
    python26-apple
    python27 (active)
    python27-apple
    python34
$ sudo port select --set python python34
Selecting 'python34' for 'python' succeeded. 'python34' is now active.
$ which python
/opt/local/bin/python
$ python --version
Python 2.7.10
$ ls -l /opt/local/bin/python
lrwxr-xr-x  1 root  wheel  24 Aug  1 10:00 /opt/local/bin/python -> /opt/local/bin/python3.4

Note how the symlink does change, but the stated version doesn't change. What gives?


Solution

  • tl;dr: Run hash -r.


    For speed reasons, shells keep a cache of what executable needs to be run when you type python into the shell.

    Consider what a shell would have to do without such a cache: For each command (that is not an absolute path) that you enter, the shell would have to

    1. go over the entries in $PATH, and for each entry
    2. issue a stat(2) system call to test whether the command exists in the currently searched directory. Remember that this might involve slow rotational disks or even network file systems back when shells were originally developed.

    To speed this up, most shells will only do this once for each command until either $PATH is changed, or you manually tell the shell to drop the cache (e.g. using hash -r in bash, rehash in some other shells).

    It was news to me that some shells also cache the symlinks, though.