pythonvirtualenvpythonpathvirtualenvwrapperzshrc

Why does virtualenv inherit $PYTHONPATH from my shell?


So I'm migrating all my tools from python2 to python3.4 on an Ubuntu 14.04 machine. So far I've done the following:

  1. aliased python to python3 in my zshrc for just my user
  2. installed pip3 on the system itself (but I'll just be using virtualenvs for everything anyway so I won't really use it)
  3. changed my virtualenvwrapper "make" alias to mkvirtualenv --python=/usr/bin/python3 ('workon' is invoked below as 'v')

Now curiously, and you can clearly see it below, running python3 from a virtualenv activated environment still inherits my $PYTHONPATH which is still setup for all my python2 paths. This wreaks havoc when installing/running programs in my virtualenv because the python3 paths show up AFTER the old python2 paths, so python2 modules are imported first in my programs. Nulling my $PYTHONPATH to '' before starting the virtualenv fixes this and my programs start as expected. But my questions are:

  1. Is this inheritance of $PYTHONPATH in virtualenvs normal? Doesn't that defeat the entire purpose?
  2. Why set $PYTHONPATH as an env-var in the shell when python already handles it's own paths internally?
  3. Am I using $PYTHONPATH correctly? Should I just be setting it in my 'zshrc' to only list my personal additions ($HOME/dev) and not the redundant '/usr/local/lib/' locations?
  4. I can very easily export an alternate python3 path for use with my virtualenvs just before invoking them, and reset them when done, but is this the best way to fix this?
    ○ echo $PYTHONPATH
    /usr/local/lib/python2.7/site-packages:/usr/local/lib/python2.7/dist-packages:/usr/lib/python2.7/dist-packages:/home/brian/dev

    brian@zeus:~/.virtualenvs
    ○ python2
    Python 2.7.6 (default, Mar 22 2014, 22:59:56)
    [GCC 4.8.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys, pprint
    >>> pprint.pprint(sys.path)
    ['',
     '/usr/local/lib/python2.7/dist-packages/pudb-2013.3.4-py2.7.egg',
     '/usr/local/lib/python2.7/dist-packages/Pygments-1.6-py2.7.egg',
     '/usr/local/lib/python2.7/dist-packages/urwid-1.1.1-py2.7-linux-x86_64.egg',
     '/usr/local/lib/python2.7/dist-packages/pythoscope-0.4.3-py2.7.egg',
     '/usr/local/lib/python2.7/site-packages',
     '/usr/local/lib/python2.7/dist-packages',
     '/usr/lib/python2.7/dist-packages',
     '/home/brian/dev',
     '/usr/lib/python2.7',
     '/usr/lib/python2.7/plat-x86_64-linux-gnu',
     '/usr/lib/python2.7/lib-tk',
     '/usr/lib/python2.7/lib-old',
     '/usr/lib/python2.7/lib-dynload',
     '/usr/lib/python2.7/dist-packages/PILcompat',
     '/usr/lib/python2.7/dist-packages/gst-0.10',
     '/usr/lib/python2.7/dist-packages/gtk-2.0',
     '/usr/lib/pymodules/python2.7',
     '/usr/lib/python2.7/dist-packages/ubuntu-sso-client',
     '/usr/lib/python2.7/dist-packages/ubuntuone-client',
     '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol',
     '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']
    >>>

    brian@zeus:~/.virtualenvs
    ○ v py3venv
    (py3venv)
    brian@zeus:~/.virtualenvs
    ○ python3
    Python 3.4.0 (default, Apr 11 2014, 13:05:11)
    [GCC 4.8.2] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys, pprint
    >>> pprint.pprint(sys.path)
    ['',
     '/usr/local/lib/python2.7/site-packages',
     '/usr/local/lib/python2.7/dist-packages',
     '/usr/lib/python2.7/dist-packages',
     '/home/brian/dev',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/plat-x86_64-linux-gnu',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/lib-dynload',
     '/usr/lib/python3.4',
     '/usr/lib/python3.4/plat-x86_64-linux-gnu',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/site-packages']
    >>>
    (py3venv)

Solution

  • I stumbled onto this answer about $PYTHONPATH which solved this for me just now. Essentially, setting $PYTHONPATH is optional and is a convenience to the user. It should only contain additional paths the user wants to add to their python path so that the user doesn't have to do this in python itself just to run a script from the terminal.

    So to solve my problem above, I set my $PYTHONPATH (in my zshrc) to only my additional folder of '$HOME/dev' and nothing else. This eliminated the references to python2 in my path and all my python3 programs are starting as expected in my virtualenv.