Jatin Kumar
Jatin Kumar

Reputation: 2785

How does pip know about virtualenv and where to install packages

I am familiar with how a python virtualenv works and when we activate, it mainly modifies VIRTUAL_ENV and PATH variable. Primarily it adds the bin directory of virtualenv to system PATH and sets VIRTUAL_ENV to point to the virtual env root directory.

As an experiment I did this using virtualenv (version 1.11.6):

# Created two fresh virtual environments
virtualenv /tmp/env1
virtualenv /tmp/env2
echo $PATH
> SOME_PATH_VALUE

# Play with env1
source /tmp/env1/bin/activate
echo $PATH
> /tmp/env1/bin:SOME_PATH_VALUE
pip list
> pip, setuptools, wsgiref
pip install wget
> pip, setuptools, `wget`, wsgiref

# Obviously env2 has pip, setuptools and wsgiref only as of now
export PATH=/tmp/env2/bin:$PATH
pip list
> pip, setuptools, wsgiref

With my experiments it was solely depending on PATH variable for determining the installation path, but I am not sure if thats the whole picture. So the key questions are:

  1. How does pip know where to install the requested package?
  2. If my virtualenv is configured not to look for site-packages (ensured that the no-global-site-packages.txt file exists in correct location) and PATH variable is correctly set, but pip install still looks into system site-packages, then how to debug this?

Upvotes: 1

Views: 812

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121148

Virtualenvs have the pip command installed in their bin/ directories. By swapping out the PATH you are executing a different pip command each time.

The bin/pip script is tied to the bin/python executable for that virtual env, and in turn that bin/python executable is tied to the virtualenv; you don't have to use source bin/activate to be able to use a virtualenv, because just the bin/python executable has all the information it needs.

You can see this by looking at the sys.prefix variable:

$ virtualenv-2.7 /tmp/env1
New python executable in /tmp/env1/bin/python2.7
Also creating executable in /tmp/env1/bin/python
Installing setuptools, pip...done.
$ virtualenv-2.7 /tmp/env2
New python executable in /tmp/env2/bin/python2.7
Also creating executable in /tmp/env2/bin/python
Installing setuptools, pip...done.
$ env1/bin/python -c 'import sys; print sys.prefix'
/private/tmp/env1
$ env2/bin/python -c 'import sys; print sys.prefix'
/private/tmp/env2

Upvotes: 1

Related Questions