A proper way of setting up Python on Linux

Python is preinstalled on most Linux systems — but you should not use the system Python for development.
Doing so often leads to broken system tools, conflicting dependencies, and unrepeatable environments.

This article shows a clean, professional setup used by experienced developers:

  • Use pyenv to manage Python versions
  • Install a modern global Python (example: 3.12.2)
  • Use venv for project isolation
  • Add small shell helpers that remove daily friction

The result: predictable Python, no system breakage, and zero guesswork.


Why not use the system Python?

Linux distributions rely on Python internally (package managers, desktop tools, installers).

Problems with system Python:

  • Versions lag behind upstream
  • Upgrading can break your OS
  • Global pip install causes dependency conflicts

Rule:

System Python is for the OS. Your Python is for you.


Step 1: Install pyenv

pyenv lets you install and switch Python versions without touching the system Python.

Install dependencies (Ubuntu/Debian example)

sudo apt update
sudo apt install -y \
  build-essential \
  libssl-dev \
  zlib1g-dev \
  libbz2-dev \
  libreadline-dev \
  libsqlite3-dev \
  curl \
  git \
  libncursesw5-dev \
  xz-utils \
  tk-dev \
  libxml2-dev \
  libxmlsec1-dev \
  libffi-dev \
  liblzma-dev

Install pyenv

curl https://pyenv.run | bash

Add this to ~/.bashrc (or ~/.zshrc):

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

eval "$(pyenv init --path)"
eval "$(pyenv init -)"

Reload your shell:

exec $SHELL

Verify:

pyenv --version

Step 2: Install a modern global Python (3.12.2)

List available versions:

pyenv install --list

Install Python 3.12.2:

pyenv install 3.12.2

Set it as your global default:

pyenv global 3.12.2

Verify:

python --version
which python

You should see something like:

Python 3.12.2
~/.pyenv/shims/python

✔ This confirms pyenv is in control.


Step 3: Ensure venv support

Modern Python ships with venv built-in. Verify:

python -m venv --help

If that works, you’re ready.


Step 4: Create a venv() helper function

Typing the same commands repeatedly is pointless.
Add this function to your ~/.bashrc:

function venv() {
  echo "Setting up and activating venv in current directory"
  python -m venv venv
  source venv/bin/activate
  pip install --upgrade pip
  python --version
}

Usage

From any project directory:

venv

What this does:

  • Creates a ./venv directory
  • Activates it
  • Upgrades pip immediately

No thinking required.


Step 5: Auto-activate venv when entering a directory

This is a huge quality-of-life improvement.

Add this override to ~/.bashrc:

function cd() {

  # We should recognize both .venv and venv as environments
  
  # Deactivate old venv if needed
  if [[ -n "$VIRTUAL_ENV" && -d ./venv ]]; then
    if declare -F deactivate >/dev/null; then
      deactivate
    fi
  fi

  builtin cd "$@"
  
  # Activate new venv if it exists
  if [[ -d ./.venv ]]; then
    echo "Activating virtual environment in ./.venv..."
    . ./.venv/bin/activate
  fi
  if [[ -d ./venv ]]; then
    echo "Activating virtual environment in ./venv..."
    . ./venv/bin/activate
  fi
}

Result

  • cd project/ → venv activates automatically
  • cd .. → venv deactivates naturally
  • No manual source commands ever again

This mirrors professional workflows used in large Python codebases.


Recommended daily workflow

mkdir myproject
cd myproject
venv
pip install requests

Next time:

cd myproject
# venv auto-activates

Clean. Predictable. Repeatable.


Summary

This setup gives you:

✔ No system Python breakage
✔ One clean global Python version
✔ Isolated project environments
✔ Zero friction in daily use

pyenv + venv + small shell helpers is the correct way to run Python on Linux.

Once you use this approach, you’ll never go back.

Using this setup with VS Code

VS Code works very well with pyenv and venv, as long as you point it at the correct interpreter. First, install the official Python extension from Microsoft. Then open your project folder in VS Code after the virtual environment has been created. Press Ctrl + Shift + P, select “Python: Select Interpreter”, and choose the interpreter located inside your project, typically ./venv/bin/python. VS Code will remember this choice per workspace and automatically use the correct Python, pip, and installed packages for linting, testing, and debugging. If you use the terminal inside VS Code, it will usually activate the same virtual environment automatically, matching your shell behavior.

The key rule is simple:

  • always select the interpreter inside your project’s venv
  • never the system Python
  • never the bare pyenv global interpreter.

Common VS Code mistakes (and how to avoid them)

A very common mistake is letting VS Code auto-select the system Python or the pyenv global Python instead of your project’s virtual environment. If you see import errors or missing packages in VS Code but everything works in the terminal, this is almost always the reason. Another mistake is opening VS Code before creating the venv — VS Code will then lock onto the wrong interpreter and keep using it until you manually change it. Finally, avoid running pip install without checking which interpreter VS Code is using; always confirm that ./venv/bin/python is selected.


VS Code checklist for new projects

Use this checklist every time you start a new Python project:

  • Create the project directory and cd into it
  • Run venv to create and activate the virtual environment
  • Open the folder in VS Code after the venv exists
  • Press Ctrl + Shift + P → Python: Select Interpreter
  • Select ./venv/bin/python
  • Open the VS Code terminal and confirm (venv) is visible

If all of the above are true, VS Code, your shell, and Python are now perfectly aligned.

Why VS Code sometimes gets Python wrong

VS Code does not actually “understand” Python environments — it guesses based on what it sees when a folder is opened. If no virtual environment exists yet, VS Code will scan your system and often pick the first Python it finds in PATH, which may be the system Python or a pyenv shim. Once that choice is made, it is cached in the workspace settings and reused, even if you later create a venv. This is why opening VS Code after creating the virtual environment is so important. Selecting the interpreter manually forces VS Code to bind all Python-related features (linting, IntelliSense, debugging, testing, terminal) to the correct interpreter, ensuring that what you run, what you edit, and what you install are all using the same Python.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.