Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set two different python versions with pyenv with different names?

Is it possible to set two different python versions for different names using pyenv? E.g. I want the python3 refer to version 3.7.4 but python refer to version 2 of python defined by system which is 2.7.12 so there will not be any conflicts and issues.

Currently I just can set version globally using pyenv global 3.7.4 which cause both python and python3 be version 3.7.4.

like image 309
Masked Man Avatar asked Sep 26 '19 11:09

Masked Man


2 Answers

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 --version
Python 2.7.6
$ python2.7 --version
Python 2.7.6
$ python3.3 --version
Python 3.3.3

For more information, please look at: https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local-advanced

like image 96
rmakoto Avatar answered Nov 03 '22 12:11

rmakoto


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 python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 3.5.2
/usr/bin/python3

However, this is what I wanted:

$ python --version && pyenv which python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 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 python
Python 2.7.12
/usr/bin/python
$ python3 --version && pyenv which python3
Python 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 python

import sys
print(sys.version)

and ran:

$ ./sample.py
2.7.12 (default, Oct  8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python ./sample.py
2.7.12 (default, Oct  8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python3 ./sample.py
3.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.py
3.7.4 (default, Sep 16 2019, 16:09:11)
[GCC 5.4.0 20160609]
$ python ./sample.py
2.7.12 (default, Oct  8 2019, 14:14:10)
[GCC 5.4.0 20160609]
$ python3 ./sample.py
3.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.

like image 35
NigoroJr Avatar answered Nov 03 '22 12:11

NigoroJr