Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deactivate conflict in virtualenvwapper and anaconda

I'm using virtualenv to switch my python dev env. But when I run workon my_env, I meet such error message:

Error: deactivate must be sourced. Run 'source deactivate'
instead of 'deactivate'.

Usage: source deactivate

removes the 'bin' directory of the environment activated with 'source
activate' from PATH.

After some searches on google, it seems that workon, which is defined in /usr/local/bin/virtualenvwrapper.sh, calls deactivate. And there is a script with the same name is present in Anaconda's bin, so it gets called by workon by mistake.

Any suggestion for working around this conflict?

like image 303
Scofield77 Avatar asked May 18 '15 16:05

Scofield77


People also ask

How do you get out of Anaconda environment?

To exit the virtual environment, use the command conda deactivate . If you run conda info --envs again, there is no * in front of env_name . That's because the env_name virtual environment is no longer active.

How to check virtualenv is activated?

Note: Before installing a package, look for the name of your virtual environment within parentheses just before your command prompt. In the example above, the name of the environment is venv . If the name shows up, then you know that your virtual environment is active, and you can install your external dependencies.

How does virtualenv work?

A virtual environment is simply a tool that separates the dependencies of different projects by creating a separate isolated environment for each project. These are simply the directories so that unlimited virtual environments can be created. This is one of the popular tools used by most of the Python developers.


1 Answers

I agree with the comment by @FredrikHedman that renaming scripts in the anaconda/miniconda bin directory has the potential to be fragile. His full post led me to what I feel is a more robust answer. (Thanks!)

Rather than simply throwing away any errors thrown by calling deactivate, we could simply condition that call on whether the function would be called versus the file. As mentioned, virtualenv and virtualenvwrapper create a function named deactivate; the *condas call a script file of the same name.

So, in the virtualenvwrapper.sh script, we can change the following two lines which test for whether deactivate is merely callable:

type deactivate >/dev/null 2>&1
if [ $? -eq 0 ]

with the stricter test for whether it's a shell function:

if [ -n $ZSH_VERSION ] ; then
    nametype="$(type -w deactivate)"
else
    nametype="$(type -t deactivate)"
fi
if [ "${nametype##* }" == "function" ]

This change avoids triggering the spurious error noted in the original question, but doesn't risk redirecting other useful errors or output into silent oblivion.

Note the variable substitution on nametype in the comparison. This is because the output of type -w under zsh returns something like "name: type" as opposed to type -t under bash which returns simply "type". The substitution deletes everything up to the last space character, if any spaces exist, leaving only the type value. This harmlessly does nothing in bash.

(Thanks to @toprak for the zsh test and for the correct flag, type -w, under zsh. I look forward to more cross-shell coding tips!)

As ever, I appreciate constructive feedback and comments!

like image 86
Thomas Capote Avatar answered Sep 29 '22 22:09

Thomas Capote