The environment is part of the project, not scratch space. A user who opens the project tomorrow, or clones it on another machine, should find the environment where their editor, their tooling, and their habits expect it.
Where it goes
Create it inside the project directory — .venv at the project root is the
convention nearly every editor and tool auto-detects:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
For a greenfield project, prefer uv, which manages a project-local .venv for
you and is much faster:
uv venv
uv pip install -e . # or `uv sync` when there is a lockfile
uv run python -m yourpkg # runs in the project env without activating
Never put the environment in /tmp, ~/envs, or any other scratch location
outside the project. It is invisible to the user's tooling, it is not what they
will look for, and on /tmp it is deleted out from under them.
PEP 668: "externally-managed-environment"
Homebrew, Debian, and Ubuntu mark the system interpreter as externally managed,
so pip install outside a virtualenv refuses with:
error: externally-managed-environment
That is the signal to create the project environment — not an obstacle to work
around. Do not pass --break-system-packages, set
PIP_BREAK_SYSTEM_PACKAGES, or delete the EXTERNALLY-MANAGED marker: those
mutate an interpreter the OS owns, leave the project with no environment of its
own, and can break other software on the machine.
Hand off commands the user can run
Write the run instructions against the project environment, so they work from a fresh shell in the project directory:
source .venv/bin/activate
python -m yourpkg ...
or, with uv, uv run python -m yourpkg ....
Do not hand back absolute paths into an environment outside the project
(/tmp/whatever/bin/python -m yourpkg). Even when they work right now, they
tell the user their project has no environment of its own.
Respect what is already there
If the project already has an environment or a declared tool — a .venv, a
uv.lock, Poetry, Pipenv, conda — use it rather than introducing a second one.
Check before creating.