A hygienic Python setup for Linux, Mac, and WSL

Tenets

  • Never install anything in system python installs
  • Always use a virtualenv
  • virtualenvs are better when their state is managed (vs. direct pip installs into them), because then you can recreate them at will
  • CLI tools written in python shouldn’t be treated like python packages
  • Don’t pip-install tools that work across python versions into a specific python version (give them their own isolated install)

Implementation

  • Use pyenv to setup and manage multiple python installations (including anaconda)
  • Use pipenv and/or poetry to manage virtualenvs
  • Use pipx to install CLI tools written in python
  • Instead of pip installing (or pipx-installing) these tools, get isolated installs for each. pipenv and pipx can be installed with pip, but which pyenv python version would you install them in?
  • With this setup, nothing touches system python, and nothing ever actually gets pip installed into the pyenv python installs directly

pipenv and poetry

pipx

Isolated installs

homebrew

mac

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

linux

sudo apt-get install build-essential curl file git/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >> ~/.bashrc

pyenv

brew install pyenv# get latest versionsPY27=$(pyenv install --list | grep "^\s*2.7" | tr -d ' ' | tail -1)
PY35=$(pyenv install --list | grep "^\s*3.5" | tr -d ' ' | tail -1)
PY36=$(pyenv install --list | grep "^\s*3.6" | tr -d ' ' | tail -1)
PY37=$(pyenv install --list | grep "^\s*3.7" | tr -d ' ' | tail -1)
PY38=$(pyenv install --list | grep "^\s*3.8" | tr -d ' ' | tail -1)
# set global python version
pyenv install $PY38
pyenv global $PY38

pipenv

brew install pipenv# Optional, if you want virtualenvs for a projects to go inside the project rather than centrally. Then when you delete a project, the virtualenv doesn't stick around. I like this a lot!
# YOUR_DOTFILE should be .profile on mac, and on linux, your .bashrc or whatever for your shell
echo "export PIPENV_VENV_IN_PROJECT=1" >> YOUR_DOTFILE

poetry

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
poetry completions bash | sudo tee /etc/bash_completion.d/poetry.bash-completion > /dev/null
# Optional, if you want virtualenvs for a projects to go inside the project rather than centrally. Then when you delete a project, the virtualenv doesn't stick around.
# YOUR_DOTFILE should be .profile on mac, and on linux, your .bashrc or whatever for your shell
echo "export POETRY_VIRTUALENVS_IN_PROJECT=1" >> YOUR_DOTFILE

Notes

--

--

--

Cloud Robotics Research Scientist at @iRobot

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Best of Level Up Coding (August 2021)

Filtering ECG signal with stopband filter using Butterworth filter method

Category Routed Aliases

Hosting your website with GitHub Pages for free! (deploy straight from Git)

Atomico’s take on Open Source: our OS risk framework

Getting Acquainted with .Map, .Select and .Find

Help With Starting Point for a Low Pass Filter

Is there an error in the documentation for SPECTRUM.MTM

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ben Kehoe

Ben Kehoe

Cloud Robotics Research Scientist at @iRobot

More from Medium

Python monorepo with Pants

Click-params: a little companion to your click project

An image showing a terminal loading a software

Easiest Lambda Layers for Python Functions

Slow HTTP Response Times? Celery to the Rescue!