And I think that's for the best. I'd much rather have a happy path that I stay on than use some sort of dark magic that nobody who comes after me will understand.
- Entrypoints? Getting there.
- Namespace packages? Ehh. Murky
- site-packages/mypackage.pth - I get it but I don't know why sometimes it appears and other times not
- c extensions? Ehhh.
- .so loading? Kinda magic.
- the confluence of editable installs, namespace packages, foo.pth, PYTHONPATH, sys.path, relative imports, entry points, virtualenvs, LD_LIBRARY_PATH, PATH, shell initialization, setup.py vs pyproject.toml? Um yeah that's some heavy wizardry.
Tbf, you don't need the vast majority of that to be effective in python.
I now have the rule of, only ever use pip inside a venv. If your venv is more than a little bit complex, write a requirements.txt file so you can generate it. So it's something like
$ cat > requirements.txt << EOF
tensorflow
Django==3.2.5
cryptography
EOF
$ echo venv > .gitignore
$ python3 -m venv venv
$ venv/bin/pip install -r requirements.txt
$ venv/bin/python
or, if you prefer, $ . venv/bin/activate
(venv)$ pip install -r requirements.txt
(venv)$ python
Then when your Python version changes, or you get confused about what's installed, or whatever, you can just blow away the entire venv and recreate it: $ rm -r venv
$ python3 -m venv venv
$ venv/bin/pip install -r requirements.txt
and you're in a known-good place.Either of these rules works fine. The thing that works poorly is using pip install outside of a venv (with or without root).
Skip the relative imports in the article. No need to read it entirely anymore ;-)