In various comments around PEP 704 - Require virtual environments by default for package installers , people seem to have liked the part of standardizing (or making it a guideline; choose your preferred term) on the name for a virtual environment in your workspace directory.
Unfortunately not everyone likes having their virtual environment in their workspace (see PEP 704 - Require virtual environments by default for package installers - #41 by tacaswell as an example). I also did a whole blog post at Classifying Python virtual environment workflows on the topic of the various ways people manage virtual environments and they definitely vary with no clear winner in terms of practices.
The problem space
The key axes people seem to work with their virtual environment management are:
- How many (1 or multiple)
- Where they are stored (locally in the workspace or some shared, central location)
- What makes the virtual environment(s) special (i.e. if there are multiple virtual environments, how do they differ from each other?)
The one-environment-locally is covered by PEP 704 by recommending .venv
. That’s seems to be what various tools are already doing, so I don’t think that’s really a contentious suggestion.
Things become tricky when the virtual environment is stored elsewhere on the file system. How are you to know where that location is? Each tool has their own default, so there’s no real way to discover any of this. A good amount of tools that store environments in a central location respect the WORKON_HOME
environment variable that comes from virtualenvwrapper, but that’s only helpful if the user happened to define it.
Then there’s which virtual environment to use when there are multiple options? From a tooling perspective (and I’m specifically talking from experience from VS Code and the Python Launcher for Unix), there’s currently no way to tie a workspace back to any of its virtual environments or what the preferred environment is when there’s more than one. This is important as you want some way to automatically select the right virtual environment as it means you get to skip environment activation which is a sticking point for beginners as well as tooling in general. Activation is even an issue with advanced users who may forget they activated a different environment earlier ; I’m willing to admit I’ve done that thanks to the side-effect that activation follows you around your terminal by default with most tools that don’t provide a run
command or you haven’t set up some integration in your shell (which is not typically portable across OSs, let alone shells).
Proposal
To help deal with the “where are the centrally stored environments” and “which of my multiple environments” problems, I’m proposing .venv
can also be a file which points to a virtual environment. Think of it like a hacky symlink just for virtual environments. Any tools that have an activate
command can just write that file and other tools can just pick up on it. It’s also flexible enough to let tools keep as many virtual environments as they want wherever they want w/o having to coordinate on other details. And the perk of using .venv
as the file name is it’s already in a bunch of .gitignore
files.
If people want concrete proposals for how the semantics would work, Support a `.venv` file · Discussion #165 · brettcannon/python-launcher · GitHub from @uranusjr suggests only supporting relative paths anchored to the file’s location so no one can accidentally/sneakily point at a virtual environment in a .venv
file they were simply handed. I’m not sure if WORKON_HOME
is widely used enough to just assume it’s a “standard” and also support it, but that’s also an option.
If we can also agree on where virtual environments can be stored globally/centrally, that’s also great! My guess is there’s some place the XDG specification or something that suggests the directory we use.
Add if a naming scheme to tie virtual environments to workspaces (when that makes sense), then that takes care of all the major issues I have seen come up from storing virtual environments outside of the workspace. The naming scheme would probably would entail something like the tail of the path plus a hash of the directory for a subdirectory to contain all virtual environments for the workspace, and then potentially some naming scheme for the virtual environments themselves (e.g. purpose/label, Python implementation, and Python version).
I do have a more elaborate, flexible solution outlined at Support a way for other tools to assist in environment/interpreter discovery · Discussion #168 · brettcannon/python-launcher · GitHub that could replace the location standardization (the file proposal would still be useful). But I’m not sure if it needs to be the way to handle this, and instead have the more elaborate solution act as an escape hatch for more elaborate scenarios (e.g. adding conda support to the mix for tools that need to support that scenario).