How I set up my Python projects using asdf and direnv
Martin Frost
Posted on June 30, 2023
I tend to do a lot of work in Python, and I think it can be mess to set up and fiddle with creating virtualenvs for each project, etc. For a long while, I used pyenv
and pyenv-virtualenv
to do this for me, but since I still used asdf
for a bunch of other things (like nodejs
, or other versions of other languages), I figured I should try to get their Python-plugin to play nicely with me and my setup as well.
Here's what I ended up with.
1. Install asdf
Go to the asdf getting started page and follow the instructions for your operating system. Basically, you need to install git
and curl
in order to get asdf
working.
2. Install asdf plugins
asdf plugin-install python
asdf plugin-install direnv
3. Install and configure direnv
asdf direnv setup --shell bash --version latest
4. Install a python version
First, make sure to install the suggested build dependencies for your operating system. These are listed in the pyenv
README.
After that, you can run the command to install a Python version: asdf install python 3.11.4
5. Create a sample project
git init hello_world
cd hello_world
echo "layout python" > .envrc
direnv allow
asdf local python 3.11.4
echo ".direnv/" >> .gitignore
Running python --version
will now print Python 3.11.4
The layout python
part that went into your .envrc tells direnv to set up Python with a virtualenv and put that in the .direnv/<python-version>
directory (in this case .direnv/python-3.11
). This means that any packages you pip install
will end up in there. Therefore, make sure to add that directory to your .gitignore
file, so that you don't accidentally vendor all of your dependencies, unless that's what you want.
The direnv allow
part is there to allow direnv to automatically load stuff when you switch to this directory. If you don't do this now, you will get a warning the next time you cd hello_world
, saying that you haven't allowed the .envrc
in this directory to run stuff locally. It's there as a security measure.
6. Commit your setup
git add .gitignore .tool-versions .envrc
git commit -m "Initial python/direnv setup"
7. Get this to work with your editor
So, how to get this goodness picked up automatically by your editor/IDE then? I mean, if you can't automatically run tests from inside Emacs/(neo)vim/VSCode/whatever, then it's not much use anyway.
Luckily, at least Visual Studio Code picks this up automatically, and even prompts you for the direnv allow
part separately, so if you only use VSCode as your daily driver, you can probably skip the manual direnv allow
step in the terminal. I imagine PyCharm and other more fully fleshed out IDEs also provide this luxury.
For Emacs or (neo)vim, you will need to configure whatever plugin you are using to use a shell where you have direnv configured, so with the above example, it should work if you shell out using bash
rather than sh
. If you configured direnv to use zsh
, then maybe you should consider having your editor use zsh
when shelling out.
Posted on June 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.