Managing Multiple Python Versions With pyenv
pyenv is a tool for managing multiple Python versions. Even if you already have Python installed on your system, it worth to have pyenv installed so that you can easily try out new language features or help contribute to a project that is on a different version of Python. So, let’s review the reasoning to manage different Python versions easily and flexibly:
- Install Python in your user space
- Install multiple versions of Python
- Specify the exact Python version you want
- Switch between the installed versions
pyenvlets you do all of these things and more.
Using pyenv to Install Python
Now that you have pyenv installed, installing Python is the next step. You have many versions of Python to choose from. If you wanted to see all the available CPython 3.6 through 3.8, you can do this:
$ pyenv install --list | grep " 3\."
Once you find the version you want, you can install it with a single command:
pyenv install -v 3.7.2
As mentioned before, pyenv works by building Python from source. Each version that you have installed is located nicely in your pyenv root directory:
$ ls ~/.pyenv/versions/
All of your versions will be located here. This is handy because removing these versions is trivial:
$ rm -rf ~/.pyenv/versions/2.7.15
Of course pyenv also provides a command to uninstall a particular Python version:
$ pyenv uninstall 2.7.15
Using Your New Python
Now that you’ve installed a couple of different Python versions, let’s see some basics on how to use them. First, check what versions of Python you have available:
$ pyenv versions
The * indicates that the system Python version is active currently. You’ll also notice that this is set by a file in your root pyenv directory. This means that, by default, you are still using your system Python:
$ python -V
If you try to confirm this using which, you’ll see this:
$ which python
This might be surprising, but this is how pyenv works. pyenv inserts itself into your PATH and from your OS’s perspective is the executable that is getting called. If you want to see the actual path, you can run the following:
$ pyenv which python
If, for example, you wanted to use version 2.7.15, then you can use the global command:
$ pyenv global 2.7.15 $ python -V $ pyenv versions
pyenv offers many commands. You can see a complete list of all available commands with this:
$ pyenv commands
This outputs all command names. Each command has a –help flag that will give you more detailed information. For example, if you wanted to see more information on the shims command you could run the following:
$ pyenv shims --help
The help message describes what the command is used for and any options you can use in conjunction with the command. In the following sections, you’ll find a quick, high-level overview of the most used commands.
You’ve already seen the install command above. This command can be used to install a specific version of Python. For example, if you wanted to install 3.6.8 you would use this:
$ pyenv install 3.6.8
The output shows us pyenv downloading and installing Python. Some of the common flags you may want to use are the following:
Flag Description -l/–list Lists all available Python versions for installation -g/–debug Builds a debug version of Python -v/–verbose Verbose mode: print compilation status to stdout
The versions command displays all currently installed Python versions:
$ pyenv versions
This output shows not only that 2.7.15, 3.6.8, 3.8-dev, and your system Python are installed, but also shows you that the system Python is active. If you only care about the current active version, you can use the following command:
$ pyenv version
This command is similar to versions but only shows you the current active Python version.
The which command is helpful for determining the full path to a system executable. Because pyenv works by using shims, this command allows you to see the full path to the executable pyenv is running. For example, if you wanted to see where pip is installed, you could run this:
$ pyenv which pip
The output displays the full system path for pip. This can be helpful when you’ve installed command-line applications.
The global command sets the global Python version. This can be overridden with other commands, but is useful for ensuring you use a particular Python version by default. If you wanted to use 3.6.8 by default, then you could run this:
$ pyenv global 3.6.8
This command sets the ~/.pyenv/version to 3.6.8. For more information, see the section on specifying your Python version.
The local command is often used to set an application-specific Python version. You could use it to set the version to 2.7.15:
$ pyenv local 2.7.15
This command creates a .python-version file in your current directory. If you have pyenv active in your environment, this file will automatically activate this version for you.
The shell command is used to set a shell-specific Python version. For example, if you wanted to test out the 3.8-dev version of Python, you can do this:
$ pyenv shell 3.8-dev
This command activates the version specified by setting the PYENV_VERSION environment variable. This command overwrites any applications or global settings you may have. If you want to deactivate the version, you can use the –unset flag.
pyenv and Virtual Environments
What is important to know:
- pyenv manages multiple versions of Python itself.
- virtualenv/venv manages virtual environments for a specific Python version.
- pyenv-virtualenv manages virtual environments for across varying versions of Python.
Creating Virtual Environments
$ pyenv virtualenv <python_version> <environment_name> $ pyenv virtualenv 3.6.8 myproject
Activating your Environment
$ pyenv local myproject
This command a .python-version file in your current working directory and because you ran eval
$(pyenv virtualenv-init -) in your environment, the environment will automatically be activated. You can verify this by running the following:
$ pyenv which python /home/foss/.pyenv/versions/myproject/bin/python
Another way to manually activate/deactivate your Python environment is:
$ pyenv activate <environment_name> $ pyenv deactivate
Working With Multiple Environments
If there is the need to work with two different projects:
- project1 supports Python 2.7 and 3.6.
- project2 supports Python 3.6 and experiments with 3.8-dev.
First, create a virtual environment for project1:
$ cd project1/ $ pyenv which python /usr/bin/python $ pyenv virtualenv 3.6.8 project1 ... $ pyenv local project1 $ python -V /home/foss/.pyenv/versions/project1/bin/python
When you leave the project folder you are back to the default Python version:
$ cd $HOME $ pyenv which python /usr/bin/python
Now create a virtual environment for project2:
$ cd project2/ $ pyenv which python /usr/bin/python $ pyenv virtualenv 3.8-dev project2 ... $ pyenv local 3.8-dev $ pyenv which python /home/foss/.pyenv/versions/3.8-dev/bin/python
These are one time steps for your projects. Now, as you cd between the projects, your environments will automatically activate:
Now you can switch between your projects and
pyenv will take care of automatically activating the correct Python versions and the correct virtual environments.
Activating Multiple Versions Simultaneously
As described in the example above, project2 uses experimental features in 3.8. Suppose you wanted to ensure that your code still works on Python 3.6. If you try running python3.6, you’ll get this:
$ cd project2/ $ python3.6 -V pyenv: python3.6: command not found The `python3.6' command exists in these Python versions: 3.6.8 3.6.8/envs/project1 project1
pyenv tells you that, while Python 3.6 is not available in the current active environment, it is present in other environments.
pyenv gives you a way to activate multiple environments:
$ pyenv local project2 3.6.8
That indicates to
pyenv to use the virtual environment project2 as the first option. So if a command, for example python, can be resolved in both environments, it will pick project2 before 3.6.8:
$ python3.6 -V Python 3.6.8
pyenv attempts to find the python3.6 command, and because it finds it in an environment that is active, it allows the command to execute. This is extremely useful for tools like tox that require multiple versions of Python to be available on your PATH in order to execute.
Suppose that in the above example, you’ve found a compatibility problem with your library and would like to do some local testing. The testing requires that you install all the dependencies. You should follow the steps to create a new environment:
$ pyenv virtualenv 3.6.8 project2-tmp $ pyenv local project2-tmp
Once you’re satisfied with your local testing, you can easily switch back to your default environment:
$ pyenv local project2 3.6.8