Set two different python versions with pyenv with different names?
Pyenv allows you to use different versions of Python at once using "advanced" mode
Example from documentation:
$ pyenv local 2.7.6 3.3.3$ pyenv versions system* 2.7.6 (set by /Users/yyuu/path/to/project/.python-version)* 3.3.3 (set by /Users/yyuu/path/to/project/.python-version)$ python --versionPython 2.7.6$ python2.7 --versionPython 2.7.6$ python3.3 --versionPython 3.3.3
For more information, please look at:https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local-advanced
I know this question is from a while ago, but I stumbled upon the same problem, and here's the approach that I took.
To make sure we're on the same page...
Initially, I had (and I assume you do too) both python
and python3
pointing to system's Python:
$ pyenv versions* system (set by /home/nigorojr/.pyenv/version) 3.7.4$ python --version && pyenv which pythonPython 2.7.12/usr/bin/python$ python3 --version && pyenv which python3Python 3.5.2/usr/bin/python3
However, this is what I wanted:
$ python --version && pyenv which pythonPython 2.7.12/usr/bin/python$ python3 --version && pyenv which python3Python 3.7.4/home/nigorojr/.pyenv/versions/3.7.4/bin/python3
Approach
The approach I took is similar to @Kapitol's second suggestion. However, I created a shell script instead of an alias because I wanted other commands (including pyenv
) to be able to find my new python3
command.
I created ~/bin/python3
(with ~/bin
in my $PATH
variable) with the following content:
#!/bin/sh# PYENV_VERSION="$( pyenv versions | tr -d ' ' | awk '/^3\./ { print $1 }' | tail -n 1 )" pyenv exec python3 $@# Or simply,PYENV_VERSION="3.7.4" pyenv exec python3 $@
With this shell script, I get:
$ python --version && pyenv which pythonPython 2.7.12/usr/bin/python$ python3 --version && pyenv which python3Python 3.7.4/home/nigorojr/bin/python3
Note 1: Using exec python3 $@
instead of pyenv exec python3 $@
in the shell script does not work because it becomes an infinite recursive call to the script itself (depending on $PATH
). Using pyenv exec
ensures that the pyenv
Python gets called no matter how the $PATH
variable is ordered.
Note 2: Having all the pipes to get the latest version managed by pyenv
does slow down the startup when calling python3
. Thus, I would recommend simply setting your desired Python version in PYENV_VERSION
if you have a particular version you want to use.
Note 3: Be aware that pip3
and other commands will not be found with this approach. One solution is to create a shell script for each command that you use. Another solution is to run pyenv global system 3.7.4
so that pyenv
can search in 3.7.4 if the command is not installed in the system.
Checking that it works
To make sure that everything is working as expected, I wrote the following Python script:
#!/usr/bin/env pythonimport sysprint(sys.version)
and ran:
$ ./sample.py2.7.12 (default, Oct 8 2019, 14:14:10)[GCC 5.4.0 20160609]$ python ./sample.py2.7.12 (default, Oct 8 2019, 14:14:10)[GCC 5.4.0 20160609]$ python3 ./sample.py3.7.4 (default, Sep 16 2019, 16:09:11)[GCC 5.4.0 20160609]
Changing the first line to #!/usr/bin/env python3
, I got:
$ ./sample.py3.7.4 (default, Sep 16 2019, 16:09:11)[GCC 5.4.0 20160609]$ python ./sample.py2.7.12 (default, Oct 8 2019, 14:14:10)[GCC 5.4.0 20160609]$ python3 ./sample.py3.7.4 (default, Sep 16 2019, 16:09:11)[GCC 5.4.0 20160609]
To conclude, with the abovementioned approach, you can have python
point to system's Python 2 while having python3
point to the version installed with pyenv
.
It's probably better to be explicit when you run your python. ie. Specify the version you want via the PYENV_VERSION environment version. If you have python 2.7.12 installed via pyenv, you should be able to verify with:
PYENV_VERSION=2.7.12 python -V
You really should be creating a new virtualenv to make sure you don't run into any dependency issues if you decide to run multiple projects with the same python version. Pyenv has a plugin that supports this. Then you could do something like:
pyenv virtualenv 2.7.12 python2-envpyenv virtualenv 3.7.4 python3-env
You can then active your shell with:
pyenv shell python3-env
In which case python
would point to the 3.7.4 shim.
Or:
pyenv shell python2-env
In which case python
would point to the 2.7.12 shim. (You can call these virtualenvs whatever you like, I just used python2-env and python3-env as an example.)
If you're really set on using python3 and python, you could always set an alias in your .bashrc:
alias python3='PYENV_VERSION=3.7.4 python'alias python='PYENV_VERSION=2.7.12 python'