I am curious about what happens under the hood of the mkvirtualenv
command and so I am trying to understand how it calls virtualenv
.
The lowest hanging fruit is to figure where the virtualenv program is located after installation and where the mkvirtualenv program is located after installation. So:-
Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:07 |~|
calvin$ which mkvirtualenv
Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:10 |~|
calvin$ which virtualenv
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv
So the strange thing I see here is that which mkvirtualenv
does not give any result. Why?
Digging further, in the virtualenvwrapper directory after installing it, I see only 3 python files:-
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 12:28:05 |/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenvwrapper|
calvin$ ls -la
total 88
drwxr-xr-x 8 root wheel 272 Apr 13 15:07 .
drwxr-xr-x 29 root wheel 986 Apr 15 00:55 ..
-rw-r--r-- 1 root wheel 5292 Apr 13 15:05 hook_loader.py
-rw-r--r-- 1 root wheel 4810 Apr 13 15:07 hook_loader.pyc
-rw-r--r-- 1 root wheel 1390 Apr 13 15:05 project.py
-rw-r--r-- 1 root wheel 2615 Apr 13 15:07 project.pyc
-rw-r--r-- 1 root wheel 7381 Apr 13 15:05 user_scripts.py
-rw-r--r-- 1 root wheel 11472 Apr 13 15:07 user_scripts.pyc
And I suppose that the only reason why mkvirtualenv
is now available in my terminal is because I have added in a source/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh
. So answering the question I asked earlier, this is simply because mkvirtualenv
is expressed as a bash function and is available in my terminal because I have sourced virtualenvwrapper.sh in my .bashrc
or .bash_profile
files.
Digging into the virtualenvwrapper.sh
script, I see
# Create a new environment, in the WORKON_HOME.
#
# Usage: mkvirtualenv [options] ENVNAME
# (where the options are passed directly to virtualenv)
#
function mkvirtualenv {
typeset -a in_args
typeset -a out_args
typeset -i i
typeset tst
typeset a
typeset envname
typeset requirements
typeset packages
in_args=( "$@" )
if [ -n "$ZSH_VERSION" ]
then
i=1
tst="-le"
else
i=0
tst="-lt"
fi
while [ $i $tst $# ]
do
a="${in_args[$i]}"
# echo "arg $i : $a"
case "$a" in
-a)
i=$(( $i + 1 ));
project="${in_args[$i]}";;
-h)
mkvirtualenv_help;
return;;
-i)
i=$(( $i + 1 ));
packages="$packages ${in_args[$i]}";;
-r)
i=$(( $i + 1 ));
requirements="${in_args[$i]}";;
*)
if [ ${#out_args} -gt 0 ]
then
out_args=( "${out_args[@]-}" "$a" )
else
out_args=( "$a" )
fi;;
esac
i=$(( $i + 1 ))
done
set -- "${out_args[@]}"
eval "envname=\$$#"
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_virtualenv || return 1
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
\cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
[ -d "$WORKON_HOME/$envname" ] && \
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
typeset RC=$?
[ $RC -ne 0 ] && return $RC
# If they passed a help option or got an error from virtualenv,
# the environment won't exist. Use that to tell whether
# we should switch to the environment and run the hook.
[ ! -d "$WORKON_HOME/$envname" ] && return 0
# If they gave us a project directory, set it up now
# so the activate hooks can find it.
if [ ! -z "$project" ]
then
setvirtualenvproject "$WORKON_HOME/$envname" "$project"
fi
# Now activate the new environment
workon "$envname"
if [ ! -z "$requirements" ]
then
pip install -r "$requirements"
fi
for a in $packages
do
pip install $a
done
virtualenvwrapper_run_hook "post_mkvirtualenv"
}
Here's where I don't understand yet - I don't seem to see any direct reference to virtualenv
in this bash function. So how exactly does this bash function mkvirtualenv
pass the arguments from command line (e.g. mkvirtualenv -p python2.7 --no-site-packages mynewproject
) to the python virtualenv
program?
The mkvirtualenv command will create a new virtualenv (virtual environment). It gets installed as part of virtualenvwrapper. what is virtualenvwrapper?
The shell cannot find anything installed under mkvirtualenv. A simple solution to this is adding the location of the necessary script to your terminal shell’s configuration file. The exact steps differ slightly depending on what shell you are using. Of course, this is assuming that you have already installed Virtual Environment.
To find where your virtualenv was installed, type: Install virtualenvwrapper via pip3: We are going to modify your .bashrc file by adding a row that will adjust every new virtual environment to use Python 3.
Now open your terminal in the home directory by right clicking and choosing the option “Open in Terminal”. You can also press the CTRL, ALT, and T keys on your keyboard at the same time to open the Terminal application automatically. You first need to create a special directory that will hold all of your virtual environments.
So this is the line that does the trick.
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
\cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
[ -d "$WORKON_HOME/$envname" ] && \
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
$VIRTUALENVWRAPPER_VIRTUALENV
is in fact the location of where the current virtualenv
program resides.
In terminal,
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 13:24:14 |~|
calvin$ which $VIRTUALENVWRAPPER_VIRTUALENV
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv
Mytsery solved.
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