Many developers hesitate to use Ubuntu's backports repository for Python upgrades because:
- Potential dependency conflicts with system packages
- Risk of breaking apt-get operations
- Difficulty maintaining multiple Python versions
- Clean removal becomes problematic
The cleanest solution for most development scenarios:
# Install dependencies
sudo apt-get update
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev
# Install pyenv
curl https://pyenv.run | bash
# Add to shell config
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
source ~/.bashrc
# Install Python 3.7
pyenv install 3.7.12
# Set as global (or use per-project)
pyenv global 3.7.12
For data science workflows:
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
# Follow installer prompts
source ~/.bashrc
# Create Python 3.7 environment
conda create -n py37 python=3.7
conda activate py37
For complete isolation:
# Pull official Python image
docker pull python:3.7-slim
# Run interactive container
docker run -it --rm -v $(pwd):/app python:3.7-slim bash
# Inside container:
cd /app
python --version # Should show 3.7.x
After any method, confirm with:
python --version
pip --version
which python
- SSL errors: Ensure you have libssl-dev installed
- Missing _ctypes: Install libffi-dev package
- Pip not working: Run
python -m ensurepip --upgrade
- Shared libraries: Check LD_LIBRARY_PATH if getting import errors
Ubuntu 16.04's default Python 3.5 is deeply integrated into the system. While backports like deadsnakes
PPA can install Python 3.7, they often cause:
- Conflicts with
apt
dependencies - Broken system tools relying on Python 3.5
- Chaotic
update-alternatives
configurations
Pyenv allows per-user Python installations without touching system Python:
# Install dependencies
sudo apt-get update
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev
# Install pyenv
curl https://pyenv.run | bash
# Add to ~/.bashrc
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
source ~/.bashrc
# Install Python 3.7
pyenv install 3.7.12
# Set as default
pyenv global 3.7.12
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda
echo 'export PATH="$HOME/miniconda/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Create Python 3.7 environment
conda create -n py37 python=3.7
conda activate py37
# Run temporary container
docker run -it --rm python:3.7-slim
# Or create persistent environment
mkdir myproject
cd myproject
echo "FROM python:3.7-slim" > Dockerfile
echo "WORKDIR /app" >> Dockerfile
echo "COPY . ." >> Dockerfile
echo "RUN pip install -r requirements.txt" >> Dockerfile
# Build and run
docker build -t py37-app .
docker run -it --rm py37-app
For any method, verify with:
python --version
# Should output: Python 3.7.x
which python
# Should point to your custom installation path
If you must install system-wide (not recommended):
# Build from source
wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
tar xzf Python-3.7.12.tgz
cd Python-3.7.12
./configure --enable-optimizations --prefix=/usr/local
make -j$(nproc)
sudo make altinstall # Important: prevents overriding python3 binary
Then use python3.7
command explicitly.