I’m -1 because I think this entrenches dependence on an environment format that we know is confusing, wasteful, and fragile. Once we start promoting these kinds of guidelines, it becomes much harder to try something else.
If it’s not going to go into VCS, then it’s got no reason to be portable between tools. It’s a per-user setting at that point. Users who regularly switch between editors are the special breed.
If it’s not in VCS, it doesn’t help someone bootstrap. You can’t just clone a repo and “venv run” or whatever to get going.
On the basis that the “presence of a special directory is too magical” for PEP 582, I fail to see why the presence of a special file isn’t just as magical.
Having a file point to a shell script (which shell[s]?) that modifies the environment (which process?) so that a PATH
search will find a symlink/copy/redirector to a Python runtime is a very convoluted solution.
Standardising a setting for editors/tools just allows those tools to refuse to engage with alternatives that don’t/can’t use that standard. I’m sure most won’t want to do that, because it’s pretty user-hostile, but then the standardisation hasn’t really helped anyone.
For reference, when I was maintaining an editor our approach was “provide the path to Python and we’ll run that, or if you want us to create an environment we’ll use venv”. We also detected requirements.txt
and offered to create an environment using venv, and we would do a shallow directory search for Scripts\python.exe
to find likely environments. The only issues our users ran into were installing binary packages (much less likely to work 5+ years ago) and when referring to embedded copies of Python didn’t work well (IIRC, Maya was the worst). This file would not have helped.
If we were to go anywhere here, I’d suggest we do a PEP 517 but for environment creation and package installation:
[dev-environment]
requires=["pip"]
env-backend="venv.HypotheticalPublicApiForThisInterface"
env-name=".venv"
install-backend="pip.HypotheticalPublicApiForThisInterface"
install="file:dev-requirements.txt" # I forget if there's existing syntax for this
All it has to support is a “create an env when none exists”, “install packages into an otherwise empty env”. The env backend API knows how to create and can provide launch params (args/env/cwd/etc.). The install backend API knows how to resolve, download, extract, etc. They could be the same tool.
Front ends can allow overriding the env-name and install parameters, but a default install should use them. And a user can use whatever tools they want and just ignore pyproject.toml completely - it’s just a central place to provide the preferences for the project, just like PEP 517.
Compared to the .venv
file, this encourages innovation. Posy could support it. Conda could support it. Pip/venv could support it. Heroku/equivalent could support it. GitHub Actions could support it. Packages can be installed by linking, or by copying, or by installing import hooks, or whatever they like, because the activation arguments could turn python myproject.py
into python -m envlauncher.run myproject.py
, or (the equivalent of) subprocess.run("python myproject.py", env={"PYTHONPATH": ...})
.
Compared to the .venv
file, second-order tools (editors/IDEs) don’t need to know how to invoke the first-order tools (venv et al.), which means anyone can work in VS Code without Brett’s blessing
It still allows the env creator to put it wherever the user wants. One user may want to keep them inside working directories by default - another might want them stored in a specific central location. That remains a per-user configuration option, just like .venv
would be, except it can be configured once for a particular env backend and then used automatically for any project using that backend.
But I think the strongest point is that we get to reuse our existing magic file, which is quickly becoming a dumping ground for everyone’s dev settings anyway. No matter what was intended, this is what it is, so we might as well embrace it and add sections that will be useful to our users.