Why does virtualenv inherit $PYTHONPATH from my shell?

末鹿安然 提交于 2019-12-06 01:41:34

问题


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)

回答1:


You can also change the Pythonpath by adding to your virtualenv's /bin/activate file:

export PYTHONPATH="/your/path"

Further explained here:

Quote:

To have it restored to its original value on deactivate, you could add

export OLD_PYTHONPATH="$PYTHONPATH"

before the previously mentioned line, and add the following line to your bin/postdeactivate script.


You might also want to have a look at this answer which talks about using add2virtualenv for adding directories.




回答2:


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.




回答3:


The $PYTHONPATH appears in your virtualenv because that virtualenv is just a part of your shell environment, and you (somewhere) told your shell to export the value of PYTHONPATH to child shells.

One of the joys of working in virtual environments is that there is much less need to put additional directories on your PYTHONPATH, but it appears as though you have unwittingly been treating it as a global (for all shells) setting, when it's more suited to being a per-project setting.



来源:https://stackoverflow.com/questions/24583777/why-does-virtualenv-inherit-pythonpath-from-my-shell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!