How to install Python

Mon May 15 2023E.W.Ayers

There are lots of different ways of installing python. This is the setup that I have stabilised on. This article is beta, it has errors in it.

1. Install Pyenv

The best way to use python is with pyenv. Pyenv is a wrapper around the python and pip shell commands that makes sure you are using the right version. Unfortunately the installation instructions for it miss loads of steps.

1.1. For mac

brew install pyenv

Put this in your .zshrc

export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

1.2. For ubuntu:

sudo apt-get update
sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev
curl | bash

Now paste this in ~/.profile

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

Then restart the shell and do.

pyenv install 3.10.11
pyenv global 3.10.11

2. The absolute chaos of package management

Before you start working on any Python project, run the following

# set a local python version
pyenv local 3.10.10
# set up a 'virtual environment'
python -m venv .venv
source .venv/bin/activate

Now your shell gets put in a special fairy land where the python version is 3.10.10 and if you pip install stuff, it will live in the fairy land and not be able to encroach on other lands.

The problem is that you have to keep remembering to run source .venv/bin/activate whenever you make a new terminal. VSCode has a feature where it will know that you are in a python environment and will inject this into new terminals that you make.

2.1. aliases

I have these aliases in my .zshrc.

alias p="python"
alias pi="pip install"
alias pvmk="python -m venv .venv"
alias pv="source .venv/bin/activate"

2.2. Using someone else's project.

Clone their repo, go into it. To install their package run pip install -e .. You should now be able to import the project without breaking things.

2.3. If you are making a new project: use Hatch

There are loads of Python project managers. Just use Hatch. It's new and sucks the least.

pip install hatch

3. Gotchas

4. How it should work

If I was in charge of Python, I would have done it like this:

  1. Python itself comes with a version manager, the exact same CLI as rustup for Rust.

  2. Pip is the version, environment and package manager. There are no other package managers or tools (poetry, pyenv, pipenv, hatch etc). You can't install Python without Pip.

  3. Scrap 'virtual environments'. The version of Python and the versions of the requisite packages needed should be entirely specified by pyproject.toml. When you run code, Python looks for this project file in the working directory and parents and uses that to determine the environment. You can specify additional environments like Hatch does.

  4. Allow importing Python packages inline: eg import "pypi:numpy=^3.10.2" as np. Now we can have standalone scripts that actually run.

This is a common problem in programming language design. The language designers think that version, environment, package management isn't their problem, and instead a load of broken, competing products emerge to fill that need. The lesson is that if you make a serious programming language, you have to include PEVM as a core part of the language tooling.