Customize module search path (PYTHONPATH) via pipenv

(Came here for an answer, ended up giving one instead)

I have a similar project folder structure, so I had the same problem.
Thanks to your tip, my solution was to add an file .env at the same level as the Pipfile with the following content:

$ cat .env
PYTHONPATH=${PYTHONPATH}:src

Now, launching my app with something like

$ pipenv run python -m package.subpackage.app

seems to work ok from inside my project's folder and also from it's subfolders.

Side note(although is not a good/clean way to do things):
for your ModuleNotFoundError: No module named 'src' problem ... the "problem" is that the src (folder) is not a package, in order to fix that you could easily add an (empty) __init__.py file inside the src folder, thous making it a "package"; which in turn would make import src.baz possible.

(Later edit)
Actually this adds a record <project_folder>/${PYTHONPATH} in sys.path, which is useless, so the correct content of the .env file should be only PYTHONPATH=src.


I'm not sure there's a perfect solution for this, but in the interest of being explicit rather than implicit (PEP 20), I've decided to check in a file that needs to be sourced before running any script. This is one extra manual step but you can put this in a Makefile for instance.

env.sh

export PYTHONPATH=${PYTHONPATH}:${PWD}

Makefile

bar:
    source env.sh && pipenv run python scripts/bar.py
.PHONY: migrate

The solution is a bit similar to the approach Go takes with its GOPATH.

I think the other solutions are not as good:

  • pipenv aims to solve dependencies, I could be wrong but I did not find anything related to the problem of the PYTHONPATH.
  • Linking folders won't scale really well if you start having other scripts folder.