Skip to article frontmatterSkip to article content

How Editable Installs Work

The magic behind pip's -e

Install your Package!

Installing a package takes time and manual effort, but it’s an important part of using someone elses software; Python packages are not just Python code that we can add to the PYTHONPATH, they’re meant to be installed to be used. But, it’s not convenient to keep re-installing it when you make changes; seeing the result of the edits to your code goes from a simple file-save to running a shell command. How can you see your changes in real-time?

Install your package editably

Editable wheel
A regular wheel file containing special file that enable editing of the package contents (using PEP 660).

The solution, as ever, can be found in pip. pip can build and install an Editable wheel for your package, using -e:

pip install -e .

We can build this wheel by hand:

!hatch build -t wheel:editable .

It contains very little!

!zipinfo ./arrow_to_knee*.whl

What do we see here that’s not familiar to us thus far? It’s the /_arrow_to_knee.pth file. More on that in a moment.

Python is a detective

To go any further, we are going to need to understand a little bit about how Python import statements actually work. We’re not going to dig into the line-by-line account of what Python is doing under the hood, but we are going to appreciate how extensible and powerful this part of the interpreter is.

At startup, Python runs some code that prepares sys.path. This includes finding .pth files in known directories, and processing them according to some rules:

The latter feature is somewhat incredible — one can use .pth files (slightly in poor form) to write code that runs at Python startup!

Editable wheel packages are designed around this .pth mechanism — they are designed to ship a .pth file that either exposes the source directory, or runs some code that handles this slightly more explicitly.