[python] How to leave/exit/deactivate a Python virtualenv

I'm using virtualenv and the virtualenvwrapper. I can switch between virtualenv's just fine using the workon command.

me@mymachine:~$ workon env1
(env1)me@mymachine:~$ workon env2
(env2)me@mymachine:~$ workon env1
(env1)me@mymachine:~$ 

How do I exit all virtual machines and work on my real machine again? Right now, the only way I have of getting back to me@mymachine:~$ is to exit the shell and start a new one. That's kind of annoying. Is there a command to work on "nothing", and if so, what is it? If such a command does not exist, how would I go about creating it?

This question is related to python virtualenv virtualenvwrapper

The answer is


I defined an alias, workoff, as the opposite of workon:

alias workoff='deactivate'

It is easy to remember:

[bobstein@host ~]$ workon django_project
(django_project)[bobstein@host ~]$ workoff
[bobstein@host ~]$

To activate a Python virtual environment:

$cd ~/python-venv/
$./bin/activate

To deactivate:

$deactivate

Use deactivate.

(my_env) user@user:~/my_env$ deactivate
user@user-Lenovo-E40-80:~/my_env$ 

Note, (my_env) is gone.


I found that when within a Miniconda3 environment I had to run:

conda deactivate

Neither deactivate nor source deactivate worked for me.


I use zsh-autoenv which is based off autoenv.

zsh-autoenv automatically sources (known/whitelisted) .autoenv.zsh files, typically used in project root directories. It handles "enter" and leave" events, nesting, and stashing of variables (overwriting and restoring).

Here is an example:

; cd dtree 
Switching to virtual environment: Development tree utiles
;dtree(feature/task24|?); cat .autoenv.zsh       
# Autoenv.
echo -n "Switching to virtual environment: "
printf "\e[38;5;93m%s\e[0m\n" "Development tree utiles"
workon dtree
# eof
dtree(feature/task24|?); cat .autoenv_leave.zsh 
deactivate

So when I leave the dtree directory, the virtual environment is automatically exited.

"Development tree utiles" is just a name… No hidden mean linking to the Illuminati in here.


I had the same problem while working on an installer script. I took a look at what the bin/activate_this.py did and reversed it.

Example:

#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys

# Path to virtualenv
venv_path = os.path.join('/home', 'sixdays', '.virtualenvs', 'test32')

# Save old values
old_os_path = os.environ['PATH']
old_sys_path = list(sys.path)
old_sys_prefix = sys.prefix


def deactivate():
    # Change back by setting values to starting values
    os.environ['PATH'] = old_os_path
    sys.prefix = old_sys_prefix
    sys.path[:0] = old_sys_path


# Activate the virtualenvironment
activate_this = os.path.join(venv_path, 'bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))


# Print list of pip packages for virtualenv for example purpose
import pip
print str(pip.get_installed_distributions())

# Unload pip module
del pip

# Deactivate/switch back to initial interpreter
deactivate()

# Print list of initial environment pip packages for example purpose
import pip
print str(pip.get_installed_distributions())

I am not 100% sure if it works as intended. I may have missed something completely.


It is very simple, in order to deactivate your virtual env

  • If using Anaconda - use conda deactivate
  • If not using Anaconda - use source deactivate

You can use virtualenvwrapper in order to ease the way you work with virtualenv.

Installing virtualenvwrapper:

pip install virtualenvwrapper

If you are using a standard shell, open your ~/.bashrc or ~/.zshrc if you use Oh My Zsh. Add these two lines:

export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

To activate an existing virtualenv, use command workon:

$ workon myenv
(myenv)$

In order to deactivate your virtualenv:

(myenv)$ deactivate

Here is my tutorial, step by step on how to install virtualenv and virtualenvwrapper.


Using the deactivate feature provided by the venv's activate script requires you to trust the deactivation function to be properly coded to cleanly reset all environment variables back to how they were before— taking into account not only the original activation, but also any switches, configuration, or other work you may have done in the meantime.

It's probably fine, but it does introduce a new, non-zero risk of leaving your environment modified afterwards.

However, it's not technically possible for a process to directly alter the environment variables of its parent, so we can use a separate sub-shell to be absolutely sure our venvs don't leave any residual changes behind:


To activate:

$ bash --init-file PythonVenv/bin/activate

  • This starts a new shell around the venv. Your original bash shell remains unmodified.

To deactivate:

$ exit OR [CTRL]+[D]

  • This exits the entire shell the venv is in, and drops you back to the original shell from before the activation script made any changes to the environment.

Example:

[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!

[user@computer ~]$ bash --init-file PythonVenv/bin/activate

(PythonVenv) [user@computer ~]$ echo $VIRTUAL_ENV
/home/user/PythonVenv

(PythonVenv) [user@computer ~]$ exit
exit

[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!

Use:

$ deactivate 

If this doesn't work, try

$ source deactivate

Anyone who knows how Bash source works will think that's odd, but some wrappers/workflows around virtualenv implement it as a complement/counterpart to source activate. Your mileage may vary.


Simply type the following command on the command line inside the virtual environment:

deactivate

Since the deactivate function created by sourcing ~/bin/activate cannot be discovered by the usual means of looking for such a command in ~/bin, you may wish to create one that just executes the function deactivate.

The problem is that a script named deactivate containing a single command deactivate will cause an endless loop if accidentally executed while not in the venv. A common mistake.

This can be avoided by only executing deactivate if the function exists (i.e. has been created by sourcing activate).

#!/bin/bash

declare -Ff deactivate  && deactivate

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to virtualenv

How to setup virtual environment for Python in VS Code? Conda version pip install -r requirements.txt --target ./lib What is the purpose of "pip install --user ..."? What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenv, etc? ImportError: No module named 'encodings' how to specify new environment location for conda create Use virtualenv with Python with Visual Studio Code in Ubuntu Is it ok having both Anacondas 2.7 and 3.5 installed in the same time? How to uninstall a package installed with pip install --user Unable to install boto3

Examples related to virtualenvwrapper

What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenv, etc? virtualenvwrapper and Python 3 bash: mkvirtualenv: command not found Where is virtualenvwrapper.sh after pip install? How do I remove/delete a virtualenv? List all virtualenv How to use MySQLdb with Python and Django in OSX 10.6? Use different Python version with virtualenv How to leave/exit/deactivate a Python virtualenv