I create my python virtual environment using:
python3 -m venv venv3
to activate, I source venv3/bin/activate
.
venv3/bin/activate
doesn't appear to be all that complex:
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
PATH="$_OLD_VIRTUAL_PATH"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
PS1="$_OLD_VIRTUAL_PS1"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "$1" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/pi/django-test/venv3"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "$PYTHONHOME" ] ; then
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
unset PYTHONHOME
fi
if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
_OLD_VIRTUAL_PS1="$PS1"
if [ "x(venv3) " != x ] ; then
PS1="(venv3) $PS1"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
I can see it modifying $PATH, and $PS1, creating a deactivate
function, and even backing up old variables that it modifies so it can restore them when the user runs the deactivate
function. All this makes sense.
The one thing I don't see is where python's sys.path is modified. On my system, this is what I see:
sys.path outside of virtual environment:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
sys.path inside of virtual environment:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/home/pi/django-test/venv3/lib/python3.5/site-packages']
Clearly, sys.path gets modified at some point, somehow. This makes sense, since that's how python knows where to find the third-party python libraries that are installed. I would think that this is the main feature of the virtual environment, but I can't see where it gets set.
I'm not trying to accomplish anything - mostly just curious.
Activating a virtual environment Before you can start installing or using packages in your virtual environment you'll need to activate it. Activating a virtual environment will put the virtual environment-specific python and pip executables into your shell's PATH .
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.
To use the virtual environment you created to run Python scripts, simply invoke Python from the command line in the context where you activated it. For instance, to run a script, just run python myscript.py .
Once you can see the name of your virtual environment—in this case (venv) —in your command prompt, then you know that your virtual environment is active. You're all set and ready to install your external packages!
sys.path
is initiated in site.py
, it is set using the relative path of sys.prefix
, which is the path of python executable inside the virtual environment.
assuming you are using virtualenv
, rather than -m venv
, access to system-wide site-packages is controlled with a flag file named no-global-site-packages.txt
, under site dir of the virtual environment.
if the virtual environment is created without option --system-site-packages
, a file named no-global-site-packages.txt
will be written into the site
dir of venv.
during python startup, site.py
is executed, it will check the existence of no-global-site-packages.txt
, if this flag file not exists, system-wide site package path will be added to sys.path
, which is infered from sys.real_prefix
. site.py
in a virtualenv created venv is a modified version.
hope this could answer your question.
The short answer is that activating a virtual environment does not change sys.path
. sys.path
is determined once Python starts up; see https://docs.python.org/3.7/library/sys.html#sys.path. What the virtual environment does, by adjusting your PATH
environment variable, is change what interpreter actually runs when you simply run python
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With