0

Problem: it's very annoying to have to install common dev dependencies in every python virtual environment (including virtual environments created by pipenv, poetry, etc.). For example, flake8, pylint, jedi, black, etc.

It would be nice to just set those up to be globally available from every virtual environment without having to manually install every time.

The last time someone asked how to do this, they got a bunch of comments scolding them for fighting their tools and no actual answer except a VSCode specific thing.

However, I recently came across a comment in the docs for the Elpy package (a Python package for Emacs) that suggests that such a thing really is possible more globally:

It is possible to create a single virtual env for the sole purpose of installing flake8 in there, and then simply link the command script to a directory inside your PATH, meaning you do not need to install the program in every virtual env separately.

That sounds like an amazing idea... and one that could apply to lots of other devtool-type dependencies. Unfortunately, the people who wrote the Elpy docs didn't go into any details of how such a thing would actually happen.

Can someone help translate the quoted paragraph into actual steps to achieve this goal? Like, "command script?" What's that? Is the idea just that a virtualenv lives in a directory somewhere, and that adding that directory to one's shell $PATH will make the libraries within it available to every other virtualenv somehow? Thanks!

Paul Gowder
  • 2,409
  • 1
  • 21
  • 36

1 Answers1

2

sure -- this is precisely how I set up my machine, including bootstrap steps from nothing:

# in .bashrc
export PATH=$HOME/bin:$PATH
# some script you run once
mkdir -p ~/opt
curl -o virtualenv.pyz https://bootstrap.pypa.io/virtualenv.pyz
python3 virtualenv.pyz ~/opt/venv
rm virtualenv.pyz

~/opt/venv/bin/pip install flake8 pre-commit tox twine
mkdir -p ~/bin
ln -s ~/opt/venv/bin/flake8 ~/bin/
ln -s ~/opt/venv/bin/pre-commit ~/bin/
ln -s ~/opt/venv/bin/tox ~/bin/
ln -s ~/opt/venv/bin/twine ~/bin/
# etc.

I first download virtualenv.pyz which is a zipapp so I don't need to invoke any global pip / potentially poorly packaged virtualenv

then I set up a virtualenv in ~/opt/venv

inside there I install my tools

and I symlink them into ~/bin which I've put on my PATH via .bashrc

My actual code for this lives in my configuration management repository: https://github.com/asottile/personal-puppet/blob/753d9491c27b17ae6a2a145fc2aad25d8896e76f/modules/desktop/manifests/venv.pp

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • Thank you. So Python can actually find libraries visible from one's ordinary shell PATH even in a virtualenv? I didn't realize that... that's super helpful. – Paul Gowder Jan 15 '21 at 23:19
  • yep, the shebang of the executables you install in the virtualenv points at the particular python – anthony sottile Jan 15 '21 at 23:31