127

I am trying to add a path to the PYTHONPATH environment variable, that would be only visible from a particular virtualenv environment.

I tried SET PYTHONPATH=... under a virtualenv command prompt, but that sets the variable for the whole environment.

How do I achieve that?

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
Flavien
  • 7,497
  • 10
  • 45
  • 52

8 Answers8

193

You can usually avoid having to do anything with PYTHONPATH by using .pth files. Just put a file with a .pth extension (any basename works) in your virtualenv's site-packages folder, e.g. lib\python2.7\site-packages, with the absolute path to the directory containing your package as its only contents.

Danica
  • 28,423
  • 6
  • 90
  • 122
  • Unfortunately this does not work as an override. It appends the path, so if you're developing it doesn't work. – Erik Aronesty Aug 29 '18 at 21:34
  • 1
    Also, if you know the absolute path, what's the point of a variable? – Jamie Marshall Jan 06 '19 at 23:08
  • you can also navigate to your virtual environment's site-packages folder and create a symbolic link to the .pth file like this: ln -s path/to/somfile.pth. I found this useful when I needed the same directory to be accessible in multiple virtual environments – Data-phile May 01 '20 at 20:12
  • How to track this file if `venv` files not should be tracked ? – rvcristiand Jul 28 '21 at 01:44
  • This is the only thing that worked for my when using anaconda on macOS with current version of vscode. Pylance would not recognize my other modules folders without this `.pth` file. Thank you! – liquidRock Dec 13 '21 at 05:02
  • 2
    To correct OP, @JamieMarshall, docs say paths in PTH files can be relative to the PTH path. – bitoolean May 20 '22 at 19:43
95

If you're using virtualenv, you should probably also be using virtualenvwrapper, in which case you can use the add2virtualenv command to add paths to the Python path for the current virtualenv:

add2virtualenv directory1 directory2 …

crimeminister
  • 1,339
  • 9
  • 8
  • where does that utility come from? I tried pip install virtualenvwrapper and that didn't get it for me. – AlanObject Aug 17 '15 at 23:44
  • 3
    How about removing from virtualenv? – silverdagger Dec 23 '15 at 03:27
  • 1
    I want to add a friendly comment that on shared hosts and similar situations venv wrapper is not desired. In such cases one venv is in effect and all that is needed making the additional install is not desired. Locally things are different, but on server/image KISS is really important. – Marc Jan 01 '16 at 21:16
  • 2
    I'm not sure how the command worked when this was written, but `add2virtualenv` doesn't modify $PYTHONPATH, rather it modifies sys.path. – ForeverWintr Aug 14 '16 at 02:09
  • @ForeverWintr not according to the docs: http://virtualenvwrapper.readthedocs.io/en/latest/command_ref.html#add2virtualenv – ostergaard Oct 03 '16 at 11:54
  • 1
    @ajostergaard: Sorry, I should have provided a source. If you look at the source code for `add2virtualenv`, you can see it's modifying sys.path. I agree that the docs make it sound like it modifies the `PYTHONPATH` environment variable, but that appears to be incorrect. https://bitbucket.org/virtualenvwrapper/virtualenvwrapper/src/9e9ffa04050d7ecf4839a5d40fdde2c44c778bbc/virtualenvwrapper.sh?at=master&fileviewer=file-view-default#virtualenvwrapper.sh-866 – ForeverWintr Oct 03 '16 at 17:28
  • @ForeverWintr what I see there is that much stuff is written into _virtualenv_path_extensions.pth inside site-packages... AFAIK .pth files in site-packages are used to set PYTHONPATH not sys.path. The sys.path stuff appears to be stuff added to the top of the file if the file doesn't already exist. – ostergaard Oct 03 '16 at 18:03
  • 1
    @ForeverWintr I stand corrected - .pth files are used to setup sys.path. https://docs.python.org/2/library/site.html Confused.com! – ostergaard Oct 03 '16 at 18:05
  • I'd just noticed that myself and was trying to figure out what gets modified by `.pth` files. :) I can't remember now if I was aware of that when I wrote the original comment, or if I was only correct by accident. – ForeverWintr Oct 03 '16 at 18:09
  • @ForeverWintr turns out sys.path IS PYTHONPATH - which I never knew. :) "The search path can be manipulated from within a Python program as the variable sys.path." https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH – ostergaard Oct 03 '16 at 18:11
  • 1
    @ForeverWintr I always thought sys.path was the env PATH. Learn something new... :) – ostergaard Oct 03 '16 at 18:12
  • This just creates a pth file. Which is an append-only modification. – Erik Aronesty Aug 29 '18 at 21:36
6

If you are using virtualenvwrapper,

$ cd to the parent folder
$ add2virtualenv  folder_to_add

console will display

Warning: Converting "folder_to_add" to "/absoutle/path/to/folder_to_add"

That's it, and you should be good to go

Aneesh Panoli
  • 206
  • 3
  • 7
5

You can also try to put symlink to one of your virtualenv.

eg. 1) activate your virtualenv 2) run python 3) import sys and check sys.path 4) you will find python search path there. Choose one of those (eg. site-packages) 5) go there and create symlink to your package like: ln -s path-to-your-package name-with-which-you'll-be-importing

That way you should be able to import it even without activating your virtualenv. Simply try: path-to-your-virtualenv-folder/bin/python and import your package.

Slavko-t
  • 69
  • 2
  • 3
1
import sys
import os

print(str(sys.path))

dir_path = os.path.dirname(os.path.realpath(__file__))
print("current working dir: %s" % dir_path)

sys.path.insert(0, dir_path)

I strongly suggest you use virtualenv and virtualenvwrapper to avoid cluttering the path.

Emily
  • 543
  • 4
  • 12
Rubber Duck
  • 3,673
  • 3
  • 40
  • 59
1

I agree with most of the answers here that changing PYTHONPATH through whatever means is less elegant than adding the package you want through some form of link. However, I think the best way to add such links is through pip install -e /path/to/your/lib (after activating the virtualenv, of course). This also creates a .egg-link file in the appropriate site-packages directory, so there is no need for elaborate ways to find the right site-packages dir. And you do not need any virtualenv-specific tools installed.

As people pointed out above, that is not quite the same as changing PYTHONPATH because that appends to sys.path instead of prepending, but in many scenarios that is irrelevant.

Christian
  • 101
  • 1
  • 4
0

As suggested by @crimeminister above, you can use virtualenvwrapper then add2virtualenv like suggested by @Aneesh Panoli. If add2virtualenv is not working after pip install virtualenvwrapper, then follow instructions in the top voted answer by @chirinosky here. Works for me.

Hajar Razip
  • 449
  • 5
  • 11
0

Was having trouble installing Box2d in a virtual environment using Python 3.9.

Simply ran a pip install swig and then was able to successfully run pip install box2d

alphazwest
  • 3,483
  • 1
  • 27
  • 39