python.defaultInterpreterPath doesn't always work (plus feedback/concerns about DeprecatePythonPath experiment)
See original GitHub issuebug
After finding myself one of the 4% opted into the DeprecatePythonPath experiment, I’ve noticed some inconsistency in how the interpreter path is handled, and believe there is buggy behavior in how python.defaultInterpreterPath
is implemented. The replication is as follows:
- Clear out your local storage so you start fresh
- Set
python.defaultInterpreterPath
to your preferred python path (e.g. a local pyenv installation of 3.7.2) - Load up your project and notice that it detects the interpreter path properly
- Exit vscode
- Delete your python install and install a new one, simulating an upgrade (e.g. 3.7.4)
- Don’t forget to update
python.defaultInterpreterPath
to point to the new interpreter path - Reopen vscode and load up your project
Actual results:
vscode has now detected that the interpreter it had been using is no longer available, and is now in a state where there is no interpreter configured, and a user has to manually specify one.
Expected results:
vscode should detect that the cached state of the interpreter is incorrect (which it seems to do) but instead of “prompting” (it’s hardly a “prompt”) the user to select a new interpreter, it should fall back to the configured python.defaultInterpreterPath
(after all, that’s what a default is for).
Additionally:
- If you run this and choose not to fully delete the original python version, vscode will happily continue to use this old version instead of the one the project maintainers would prefer to enforce (see below for justification and use case).
- python envs installed in these subdirectories are not detected by vscode’s picker and do not always show up with autocompletion so I had to manually type out (copy/paste) the entire path in order to use it (this seems to have improved after wiping my local storage cache directories, but is still annoying).
Other thoughts
I work on a team that uses direnv to enforce a specific environment for each of our projects. This includes maintaining different versions of python in the project directories based on where these will be deployed (e.g. App Engine has access to 3.8 but App Engine Flex only 3.7.2), and allowing us to rebuild these environments on the fly, test out different versions on different branches (e.g. when Flex gets 3.8 we’ll make a branch to test that but still need to switch back and forth to work on “known stable” branches).
Since it seems likely from comments on #2125 that this experiment will become permanent, my initial solution to both of these was to add something the following to the shared settings.json
files in each repository to ensure that everyone is opted in to this experiment and will default to the proper python instance:
{
"python.experiments.optInto": ["DeprecatePythonPath - experiment"],
"python.defaultInterpreterPath": "${workspaceFolder}/.direnv/python-3.7.2/bin/python3",
// ...
}
However, due to the aforementioned bug, this means that many of our projects open up the “first” time with no interpreter set (seemingly conflicting with whatever value was cached before the experiment was activated), and that any attempts to upgrade or switch python interpreters for a specific project will mean the user has to manually specify the python interpreter every time he/she switches between branches with different python versions activated (and know which version to select, which means cracking open settings.json
or our .envrc
to see). This is not an improvement as far as usability goes.
So for now, I’ve opted my team out of this experiment (thanks for adding that option) until the usability issues have been resolved, and/or there are options that once again allow for project settings to control the python path:
{
"python.experiments. optOutFrom": ["DeprecatePythonPath - experiment"],
"python.pythonPath": "${workspaceFolder}/.direnv/python-3.7.2/bin/python3",
// ...
}
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:12
Today I just found myself in the exact same scenario as @ex-nerd reports. Our team also uses direnv and sets a different Python environment for each project, which is always relative to the workspace directory. We have always used the
pythonPath
setting in our workspace directories (.vscode/settings.json
), but now this does not work anymore.Yes, we can make our developers to manually select an environment in each one of their projects, but this is not intuitive (sometimes the required environment is not shown even though it’s in the
$PATH
and, more important, this requires manual action!), is error-prone (many of our developers don’t know the “internals” of our direnv structure and can select the wrong interpreter), and does not consider future version upgrades (if after some development we require a different Python version, we must tell our developers and ensure that they change their settings).So, yes, we understand the need to allow a user setting for all the scenarios where Python paths are not shared, but I don’t think that disabling the existing behaviour is a good idea as it breaks compatibility with some use cases and, even worse, it forces teams to waste work time trying to discover how this must be done now.
This should be as easy as testing the
pythonPath
parameter (ordefaultInterpreterPath
,recommendedInterpreterPath
,overrideInterpreterPath
or any other recognizable name) and if not available or not set, use the internal user setting.@karrtikr Yes… Granted, part of this is confusion around the experiment info page I was sent to when vscode notified me that I’d been opted in (which to my recollection didn’t mention that
python.defaultInterpreterPath
was not allowed in workspace settings, simply that it replacedpython.pythonPath
with slightly different functionality).There also seems to be something different between using a pyenv environment from its main location in
~/.pyenv/
and the actual active one installed as a virtual environment for each of my projects.But you keep answering me as if I’m not specifically reporting it as a bug that I can’t control the python interpreter from my workspace settings like I can if I opt out of this experiment and revert to previous behavior. This new experimental behavior previous convention and forces users to manually type in a path they may not know every time the project changes its interpreter settings (because for some reason it doesn’t show up in the picker … and I can’t even use something like
python.defaultInterpreterPath
in the workspace config to ensure that it does show up in the picker). The experiment asked for feedback and told me to come here to provide it. So I’m providing feedback: the current implementation breaks legitimate use cases where the project maintainers (e.g. my employer and several previous ones) use a.vscode/settings.json
file committed into the code base to ensure that all developers use the exact same version of python, which includes automatically switching them to new/different versions as they switch between branches. Storing manually-specified values outside of the project workspace is fine … but it is a mistake to remove the ability for the workspace config to specify what its defaults should be.