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?
One solution which works for me is to rename
deactivate
in Anaconda's bin:mv deactivate conda-deactivate
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 nameddeactivate
; 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 whetherdeactivate
is merely callable:with the stricter test for whether it's a shell 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 oftype -w
underzsh
returns something like "name: type
" as opposed totype -t
underbash
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 inbash
.(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!
In anaconda
activate
is an executable script located in the anacondabin
directory, but is a function in invirtualenvwrapper.sh
. So this is sort of a namespace collision problem, but also a case of overlap in functionality.Anacondas is a python distribution and – among many other things – has support for dealing with virtual environment via
conda env
while the virtualenvwrapper is focused on working with different virtual environments. Just renaming the anaconda/bin/activate script is a brittle solution and may breakconda
.The code of
virtualenvwrapper.sh
(functionworkon
) executesdeactivate
which happens to use the anaconda script. This script returns an error. Theworkon
code then goes on and removes thedeactivate
name and sources its owndeactivate
and also creates adeactivate
function on the fly.In summary, it does the right thing and the "error" can be viewed more as a warning. If you want to make it go away you can modify the workon function (search for the line
# Deactivate any current environment "destructively"
)(I have suggested this change to the virtualenvwrapper maintainer)
As I do not have enough reputations to add a comment: Thomas Capote's suggestion is fine (thx 4 that), except "zsh" does not have a "-t" option for the build-in command "type". Therefore its necessary to add another conditional statement to get desired result for "nametype":
Hope it helps other zsh users.
You can edit /usr/local/bin/virtualenvwrapper.sh to make
deactivate
point to an absolute path to whateverdeactivate
it is supposed to be referencing.