Software development and beyond

How to install Python development versions on Fedora

In this post I will discuss how and why you might install a development version of Python on Fedora and manage multiple Python versions using pyenv.

Python development version

Why

Using different Python versions is sometimes necessary for testing or performance reasons, or when we work with a number of projects that use incompatible versions.

Using development versions allow us to try new features and make sure our programs would run in the new versions too, even before a final version is released.

Managing multiple Python versions

Pyenv is a tool for Python version management. It allows us to install multiple Python versions and switch between them on one system. A very neat feature of Pyenv is that it makes it possible to use a particular Python version for a specific folder, so it is easy to set different version for each project we might have. It works well with both final releases as well as development versions.

There are a few steps to install Pyenv. First we should clone the repository. The suggested location for that is ~/.pyenv:

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

The next step is to set PYENV_ROOT environment variable and put Pyenv on the PATH. Change the location in case you cloned it into a different directory:

# for Bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile

# for Zsh
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc

Last step involves activating Pyenv every time we start a shell with eval "$(pyenv init -)" which we again need to put in either .bash_profile or .zshrc depending on our shell.

After restarting the shell we should be able to access Pyenv on the command line:

> pyenv --version
pyenv 1.2.23-54-gabcbf6e1

We will see how to use Pyenv shortly, but first we need to make sure that we can build various CPython versions.

Prerequisites for building CPython

To build development versions of Python we need some CPython build dependencies on our system. In case of Fedora that means installing:

# First we install some common development tools like gcc and make, Fedora provides a group of packages for that call Development Tools
sudo dnf groupinstall "Development Tools" -y

# To build Python we need some additional packages
sudo dnf install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel findutils -y

In case we miss any of the necessary packages, the installation of Python would fail. We would get an output similar to this (here OpenSSL is missing):

Cloning https://github.com/python/cpython...
Installing Python-3.10-dev...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (Fedora 33 using python-build 1.2.23-54-gabcbf6e1)

Inspect or clean up the working tree at /tmp/python-build.20210306120241.7314
Results logged to /tmp/python-build.20210306120241.7314.log

Last 10 log lines:
	 ./python -E -m ensurepip \
		$ensurepip --root=/ ; \
fi
Looking in links: /tmp/tmp8c5ul8mb
Processing /tmp/tmp8c5ul8mb/setuptools-52.0.0-py3-none-any.whl
Processing /tmp/tmp8c5ul8mb/pip-21.0.1-py3-none-any.whl
Installing collected packages: setuptools, pip
  WARNING: The scripts pip3 and pip3.10 are installed in '/home/pstribny/.pyenv/versions/3.10-dev/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-21.0.1 setuptools-52.0.0
pyenv install 3.10-dev  270.71s user 19.84s system 374% cpu 1:17.53 total

In case this happens to you, just consult the Common build problems page for instructions regarding your system.

Working with Pyenv

Pyenv offers various commands to install different Python versions and switch between them.

It is important to know that Pyenv can set either a global or a local version. The local option is useful if we need to set a Python version for a specific folder (it will work with the current working directory).

Simply typing pyenv global or pyenv local will reveal the currently set version. Upon a fresh installation we will probably see the system Python version set as the global version and no local version set for a folder we might be currently in:

> pyenv global
system
> pyenv local
pyenv: no local version configured for this directory

To see which versions of Python are installed on the system, type pyenv versions:

> pyenv versions
* system (set by /home/pstribny/.pyenv/version)
  3.10-dev

In this case a Python 3.10 development version is already installed and we can see a star (*) indicating which version is currently in use.

Install Python development version

Assuming we don't have any other version installed, we might want to see which versions can be installed:

> pyenv install --list
  ...
  3.8.7
  3.8.8
  3.9.0
  3.9-dev
  3.9.1
  3.9.2
  3.10.0a5
  3.10-dev
  ...
  graalpython-20.2.0
  graalpython-20.3.0
  ...
  micropython-1.12
  micropython-1.13
  ...
  pypy3.7-c-jit-latest
  pypy3.7-7.3.2-src
  pypy3.7-7.3.2
  pypy3.7-7.3.3-src
  pypy3.7-7.3.3

As we can see, we can install alternative Python versions like Pypy, Micropython, or Graal Python as well.

Today we are mostly interested in development versions. Since the last release version is 3.9.2, we might want to try 3.10-dev to play with the new pattern matching feature. Let's install it:

pyenv install 3.10-dev

Now we can set it globally or for a folder:

pyenv global 3.10-dev
pyenv local 3.10-dev

After that python should point to the correct version:

> python --version
Python 3.10.0a6+

We can always set Python back to our system version:

# for global
pyenv global system

# for local
pyenv local --unset

Last updated on 7.3.2021.

python