Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Details on the A/B experiment removing python.pythonPath support #12313

Closed
karrtikr opened this issue Jun 12, 2020 · 46 comments
Closed

Details on the A/B experiment removing python.pythonPath support #12313

karrtikr opened this issue Jun 12, 2020 · 46 comments
Assignees
Labels
area-environments Features relating to handling interpreter environments feature-request Request for new features or functionality needs proposal Need to make some design decisions

Comments

@karrtikr
Copy link

karrtikr commented Jun 12, 2020

Summary of the situation

For security reasons we need to not automatically trust the python.pythonPath setting when it originates from a .vscode/settings.json file in a workspace. We also had a long-standing request to not write a user's environment path to .vscode/settings.json to allow for it to be committed to version control without be specific to any one user's machine.

We set up an A/B experiment to measure impact on users in dropping support for python.pythonPath. This issue is a response from users who were negatively impacted. We are working with various teams within Microsoft to try and come up with a situation where we can bring back some semblance of the old semantics while still providing the level of security and safety we need to.

To stay updated on our work to resolve the situation, please feel free to subscribe to this issue -- there's a "Subscribe" button in the right column -- and we will post updates to this issue as things develop.

Related issues:

Wiki: https://github.com/microsoft/vscode-python/wiki/AB-Experiments

Opting out of the experimental semantics

To opt out of the experiment, you can set “python.experiments.optOutFrom” to either the specific experiment or to ["All"] to opt out of all experiments. See https://github.com/microsoft/vscode-python/wiki/AB-Experiments#faq for more details.

Original post

Originally posted by @zor-el in #12002 (comment)

I'm posting this coming from #2125 because that issue is referenced from the announcing blog post.

Complete removal of python.pythonPath from the settings is a massively breaking change that IMO isn't warranted by the #2125 issue that has been used to justify it in the above blog post. (This change has certainly been breaking things left and right for me.) The explanation in that blog post's comment that "it can be useful" doesn't invalidate my argument. A breaking change is harmful, so it should be significantly outweighed by a benefit that cannot by obtained otherwise. This is not the case here though, IMO.

Although it is true that pythonPath would likely be different for different people, I'd argue that is true for the entire (or most of) .vscode/settings.json. For example, extensions can and do store settings in .vscode/settings.json that may just as well conflict with other users.

Settings are not generally transferable from user to user and from machine to machine, so there is little point in sharing them. In those cases that one would want to share them, one would certainly want to separate transferable from non-transferable settings.

Note the OP's issue wasn't the existence of python.pythonPath, but the unsolicited modification of .vscode/settings.json, which sneaks in non-transferable content into (in their case) shared settings.

Apparently the underlying issue is the lack of means for separation of transferable from non-transferable settings. That separation is inadequately addressed by removal of pythonPath (it is a general issue, not one specific to Python). The concrete issue #2125 is not about pythonPath removal either but about unsolicited modification of .vscode/settings.json. That is just as inadequately addressed by mere removal of pythonPath (IMO it could have been solved without breaking everybody's settings).

Question: Why can we not keep python.pythonPath for backward compatibility and simply ask the user for permission to overwrite it (and hint at the fact that the setting may not be transferable)?

Perhaps even the experiment's pythonPath caching behavior could remain intact, but an explicit pythonPath setting could take precedence?

@ghost ghost added the triage-needed Needs assignment to the proper sub-team label Jun 12, 2020
@Almenon
Copy link

Almenon commented Jun 12, 2020

I'd also like to add that this is a breaking change to my extension, which relies on the pythonPath setting. Possibly other extensions too. If the setting does change preferably an API would be provided to access the setting before it is removed.

@karrtikr
Copy link
Author

karrtikr commented Jun 12, 2020

An API is exposed #11294. Follow all changes regarding pythonPath setting here #11015.

#11294 (comment) describes how we helped upgrade code runner extension to use the new API, you can do similarly for your extension. This code snippet could be very helpful.

@zor-el I recommend opening new issues for discussing how removing this setting is breaking things for you.

@thernstig
Copy link

thernstig commented Jun 12, 2020

@zor-el We are a large team of developers, and sharing .vscode/settings.json is definitely needed. It sets up the linting tools to use for our products, and many other rules. It is not true that settings are not transferable, and it it is a core feature of VS Code.

@luabud

This comment has been minimized.

@zor-el
Copy link

zor-el commented Jun 13, 2020

@thernstig, perhaps the verbosity of my original comment is obscuring its essence (sorry if that's the case). My point was that settings are not transferable in general, not that they are not transferable at all, and that therefore a separation of transferable and non-transferable settings must clearly be the solution, not mere removal of settings. Obviously a definition about which settings are transferable and which aren't depends on the specific process of each team and cannot be universal.

I can see how moving settings from settings.json to an obscured unknown "internal" location can provide the separation, but it creates at least three problems:

  • It imposes a single definition on what is non-transferable on everybody, thereby punishing users who did share those settings in order to satisfy those who didn't (or vice versa).
  • It makes it impossible to selectively backup or even look up those settings because there's no defined place where they are readably stored.
  • It impedes project skeleton generators to cookie-cut a complete project including vscode settings.

I guess my point on some deeper level is that pivotal decisions such as this don't have to be a zero sum game. The sharers of setting X don't have to lose in order for its non-sharers to win (and vice versa). There clearly are win-win scenarios here, we just need to move on from the either-or thinking. Which is why I'm trying to have a discussion broader than just my personal issues with the situation.

@karrtikr karrtikr changed the title Queries about removal of pythonPath setting Queries about moving workspace pythonPath setting into VSCode storage Jun 13, 2020
@ghost ghost removed the triage-needed Needs assignment to the proper sub-team label Jun 15, 2020
@ericsnowcurrently ericsnowcurrently added triage-needed Needs assignment to the proper sub-team feature-request Request for new features or functionality area-environments Features relating to handling interpreter environments and removed triage-needed Needs assignment to the proper sub-team labels Jun 15, 2020
@williamcol3
Copy link

williamcol3 commented Jun 16, 2020

I agree with @zor-el in that I think this is a drastic, breaking change that is not proportional to the magnitude of the problem at hand. I will restate what I think is the problem for clarity:

People want to share {workspaceFolder}/.vscode/settings.json, for instance in a repository, to enable large teams to work in a common environment. The setting python.pythonPath breaks this workflow because the python path changes per-user (sometimes automatically by the extension).

Firstly, I disagree with the practice that .vscode/settings.json should be shared in the repository at all. Editor configuration is a deeply personal issue and independent editor configuration should remain enabled at the workspace level for all users. Placing .vscode/settings.json under version control breaks this. User-settings can be applied if the settings are constant across all projects on which a user is working, but this should not be forced on a user as a prerequisite for working on a project. However, I do recognize that many settings for a project are constant for all users of a project (i.e. linter/formatter choice). Therefore I also recognize why one would want to share settings.

Ideally, a solution would be enabled by VS Code proper. An example would be to enable extending settings from other files (example proposal at microsoft/vscode#15909). Such a change would enable sharing some settings via version control while leaving the greater configuration up to the user. If such a change or something similar is enacted, it is desirable to then enact the idiomatic approach. Therefore any proposed solution should be able to pivot easily in the future.

The proposed solution, as I understand it, is to store the python interpreter path in "internal storage" that is not directly visible to the user, require use of the vscode-python command Select Interpreter to specify the location, and expose the location through an API endpoint and configuration query for settings. In addition to the problems outlined earlier by zor-el:

  • It imposes a single definition on what is non-transferable on everybody, thereby punishing users who did share those settings in order to satisfy those who didn't (or vice versa).
  • It makes it impossible to selectively backup or even look up those settings because there's no defined place where they are readably stored.
  • It impedes project skeleton generators to cookie-cut a complete project including vscode settings.

I see additional problems:

  • The proposed solution is not general. There are other settings that a user may want to configure isolated to a single work-space that they do not want shared. In such instances, the proposed changes do not help at all.
  • In the event that an appropriate solution is enabled directly by VS Code proper, there will likely be significant inertia to reverting to the current approach.

Moreover, there exists a low-effort solution to remedy pain in the meantime by keeping python.pythonInterpreter constant: project-specific environment variables. For example, the project "FooBuzzBar" could depend on the environment variable FOOBUZZBAR_PYTHON_PATH and set python.pythonPath: ${env:FOOBUZZBAR_PYTHON_PATH}. This environment variable can then be defined in:

  • User variable definitions (i.e. .bash_profile on Linux)
  • Custom .desktop (or .lnk for windows) that sets the correct environment variables before starting
  • In that same vein, a custom startup script that is launch-able from command-line.

Moreover, due to the generality of the approach, there are many other possible implementations and, most importantly, the power is left with the user.

Note the ${env: ...} cannot reference environment variables defined in a dotenv file.

Project-specific environment variables are little awkward, but once set up are straightforward to use.

Another alternative, if settings do no change often, is to simply provide a settings template.

In conclusion, the proposed solution is an over-engineered solution with multiple problems (obscurity of information, non-generality of solution, etc.) to a problem that shouldn't exist, and when it does there are proportionally straightforward work-arounds. If/when a more idiomatic approach is enabled by changes to VS Code, there will be inertia to walking back the proposed changes and the extension will be left in a state of awkwardness.

@zor-el
Copy link

zor-el commented Jun 17, 2020

Thanks, @williamcol3, for chiming in so profoundly, and for keeping it on a general level like I did.

I'd like to reemphasize that, to me, it is not about weather or not sharing settings is a "good" thing or "bad", but about freedom of choice for everybody. (Sharing even a pythonPath to a git-ignored project-local virtual environment is definitely not something unheard of "in the wild".)

In that sense, I'd like to suggest a (hopefully) low friction solution alternative:

Instead of storing those settings "internally" (this approach painfully reminds me of the Windows registry), how about keeping them in .vscode/settings-python-internal.json or something like that. That way, users could choose to gitignore that file alone or the entire .vscode folder. It would allow such settings to be backed up, generated by project skeleton generators, grepped over, and programmatically updated (via jq, for example).

Thoughts?

@FlyingRedDonkey

This comment has been minimized.

@luabud
Copy link
Member

luabud commented Jun 17, 2020

Thank you all for providing such a detailed feedback. Let me try to explain a few points:

It imposes a single definition on what is non-transferable on everybody, thereby punishing users who did share those settings in order to satisfy those who didn't (or vice versa).

Our intention is not to punish anyone. We're becoming a very popular extension so we need to be more careful with our settings and solutions. Sharing path settings could be a potential security concern (one of these #7805) so we decided to go for a route where users can still define default settings (in User scope) and then have that to be added by everyone in the team. We're also working on being better at detecting environments, so ideally users won't have to keep setting paths - they'll just be listed in the interpreter list once Select Interpreter is run. And then it's a one click solution per workspace.

It makes it impossible to selectively backup or even look up those settings because there's no defined place where they are readably stored.

The path to the selected interpreter is printed out in the output, so you can always look it up and save that information in your user settings.

It impedes project skeleton generators to cookie-cut a complete project including vscode settings.

In general this doesn't work super well anyway, since paths are OS specific. This only really works for environments that are located in your workspace (and that is more common for virtual environments), but then it doesn't work between Windows and macOS/Linux.

The proposed solution is not general. There are other settings that a user may want to configure isolated to a single work-space that they do not want shared. In such instances, the proposed changes do not help at all.

For choosing what you'd like to share or not, the cleanest solution would have to be provided by VS Code generally.

In the event that an appropriate solution is enabled directly by VS Code proper, there will likely be significant inertia to reverting to the current approach.

We are not going to revert to the python.pythonpath setting as is. Our plan is to deprecate the path settings in the workspace level - but we want to make sure we found a good solution before we implement it.

Environment variables are tricky too since they raise even higher security concerns, so we just can't go that route.

@brettcannon

This comment has been minimized.

@williamcol3
Copy link

It imposes a single definition on what is non-transferable on everybody, thereby punishing users who did share those settings in order to satisfy those who didn't (or vice versa).

Our intention is not to punish anyone. We're becoming a very popular extension so we need to be more careful with our settings and solutions. Sharing path settings could be a potential security concern so we decided to go for a route where users can still define default settings (in User scope) and then have that to be added by everyone in the team. We're also working on being better at detecting environments, so ideally users won't have to keep setting paths - they'll just be listed in the interpreter list once Select Interpreter is run. And then it's a one click solution per workspace.

It makes it impossible to selectively backup or even look up those settings because there's no defined place where they are readably stored.

The path to the selected interpreter is printed out in the output, so you can always look it up and save that information in your user settings.

It impedes project skeleton generators to cookie-cut a complete project including vscode settings.

In general this doesn't work super well anyway, since paths are OS specific. This only really works for environments that are located in your workspace (and that is more common for virtual environments), but then it doesn't work between Windows and macOS/Linux.

I generally agree that you could work around the problems listed above, but the point is that I fail to see how the proposed solution improves the current situation. I see a lot of negatives to the changes but not many positives.

The proposed solution is not general. There are other settings that a user may want to configure isolated to a single work-space that they do not want shared. In such instances, the proposed changes do not help at all.

For choosing what you'd like to share or not, the cleanest solution would have to be provided by VS Code generally.

Ideally, yes. But that isn't the only solution. For instance, the C/C++ extension has their own configuration file, a c_cpp_properties.json, which contains very workspace-/user-specific settings. Just as compilerPath is a configuration setting in said file, I see no reason something like interpreterPath could not be a setting in a similar file used for the python extension. Such a file could hold other options as well. Such a file would be more general and more user-visible than internal storage, and you could still expose all needed information through an API. The specific responsibilities of an extension-specific settings file would need to be determined, but you could even extended the concept by allowing multiple settings files so that projects/users could separate to-be-shared and to-be-user-specified settings.

In the event that an appropriate solution is enabled directly by VS Code proper, there will likely be significant inertia to reverting to the current approach.

We are not going to revert to the python.pythonpath setting as is. Our plan is to deprecate the path settings in the workspace level - but we want to make sure we found a good solution before we implement it.

You're saying you plan to deprecate the path settings at the workspace level? By implication, does this mean they are not deprecated at the user level? Path settings seem wholly more appropriate at the workspace level (which I suppose is what Select Interpreter is for(?)) when considering the generally recommended workflow for python projects (virtual environment per project).

Environment variables are tricky too since they raise even higher security concerns, so we just can't go that route.

Firstly, if an agent has enough access to place a malevolent python interpreter/environment on a user's machine, that agent has enough access to change environment variables and "internal storage" with equal ease. If the history of cyber security has taught us anything it is that obscurity is not a valid defense mechanism. Furthermore, malevolent changes to internal storage would be less visible to the user and thus arguably pose more of a security risk.

Moreover, environment variables aren't a route that you, as extension authors, have to go. It is up to the users how they want to share settings. The point of the example was to show that there are viable, user-available solutions to the problem at hand (described in #2125).

On that note, there really should be a single place that states:

  1. What deficiencies exist that the proposed changes are addressing.
  2. What exactly the proposed changes are and how they address those deficiencies.

It is difficult to keep track of the various parts across what feels like too many issues. Based on the above issue, it seems like the only problem being addressed is the awkwardness of sharing settings.json due to pythonPath. This single problem seems small in comparison to the large changes proposed to address it.

@thernstig
Copy link

thernstig commented Jun 17, 2020

Side-note: I think some of you are underestimating how common it is to share workspace settings in a project. It is mentioned almost immediately in https://code.visualstudio.com/docs/getstarted/settings that explains these settings.

Working with a team of 40+ developers, setting up all project-specific configuration by some passionate VS Code power-users saves a lot of time for everyone working in the project. We have found no downsides, it has saved us much headache.

The .vscode/settings.json is meant to be shared and is a great solution.

That is why sharing interpreter settings (path) through that file is a bad idea - a virtual environment is host specific, user specific, OS specific.

There is a highly upvoted feature (microsoft/vscode#40233) to enable user+workspace specific settings. I would not mind if the interpreter path in the future gets put there instead.

@zor-el
Copy link

zor-el commented Jun 17, 2020

I think some of you are underestimating how common it is to share workspace settings in a project.

I don't see anybody underestimating anything, least of all sharing settings. What we are against is moving the settings to some "internal" and inaccessible location, for reasons clearly stated above, and not honoring pythonPath in settings.json at all.

In our case, we use project template generators that are fairly adjusted to our specific needs (probably for similar reasons why your team might be sharing the workspace settings), and with the pythonPath setting completely gone, those templates will be partly broken. (They were a non-trivial investment, probably not unlike your settings.json template, so it's gonna hurt.)

That is why sharing interpreter settings (path) through that file is a bad idea - a virtual environment is host specific, user specific, OS specific.

In case where the virtual environment is in the workspace folder (as it commonly is), we often agree to name the venv dir uniformly and to share even pythonPath. There's no downside for us there. As stated previously, the problem obviously wasn't whether pythonPath can be set there (some users want that, some don't), but that 'Select Interpreter' puts it there without user approval.

Thanks for the hint to microsoft/vscode#40233. It's very similar to what I've suggested above. I just upvoted it. :) Unfortunately that feature, if and when implemented, won't work with regard to our issues here, unless pythonPath (or a similar setting) is retained and placed in such a setting file. But that's something which apparently the extension team is adamantly opposed to, for reasons only hinted to but never disclosed.

@williamcol3
Copy link

Side-note: I think some of you are underestimating how common it is to share workspace settings in a project. It is mentioned almost immediately in https://code.visualstudio.com/docs/getstarted/settings that explains these settings.

Working with a team of 40+ developers, setting up all project-specific configuration by some passionate VS Code power-users saves a lot of time for everyone working in the project. We have found no downsides, it has saved us much headache.

The .vscode/settings.json is meant to be shared and is a great solution.

That is certainly my mistake. I assumed it would be recommended to not share due to how common it would be to have user+workspace specific settings. I would mark the general situation as a failure of VS Code and I anticipated it will be rectified eventually. Which I think furthers my point than any chosen solution should be easy to pivot to the future idiomatic solution.

That is why sharing interpreter settings (path) through that file is a bad idea - a virtual environment is host specific, user specific, OS specific.

There is a highly upvoted features (microsoft/vscode#40233) to enable user+workspace specific settings. I would not mind if the interpreter path in the future gets put there instead.

Not just interpreter path but any path specification, possibly database connection information (vscode-database for example), and things like integrated terminal environment variables (which you can set in settings). This isn't just limited to interpreter path, which is one of the reasons I don't think
the proposed solution is the best way to solve the problem.

@Almenon
Copy link

Almenon commented Jun 18, 2020

Side-note: I think some of you are underestimating how common it is to share workspace settings in a project. It is mentioned almost immediately in https://code.visualstudio.com/docs/getstarted/settings that explains these settings.

It's hard to say how common it is to share workspace settings without seeing statistics. Personally I think it's a antipattern to commit workspace setting to github - different people have different computers and different extensions, there's no one perfect settings that fits everyone.

I would assume most major projects have it gitignored, but I could be incorrect.

@thernstig
Copy link

thernstig commented Jun 18, 2020

@Almenon agree it needs statistics, my guess is as good as yours . But major projects do use it: https://github.com/microsoft/vscode/tree/master/.vscode

Personally, we also felt a great upswing doing so. But I digress, this is side-step of the topic and I think we cleared this one out.

I would recommend adding comments to microsoft/vscode#40233 on how you would like it to look.

@zor-el

In case where the virtual environment is in the workspace folder (as it commonly is), we often agree to name the venv dir uniformly and to share even pythonPath. There's no downside for us there. As stated previously, the problem obviously wasn't whether pythonPath can be set there (some users want that, some don't), but that 'Select Interpreter' puts it there without user approval.

We also do that 😄 We have our in the workspace folder and have forced everyone to install their venv into "python.pythonPath": "${workspaceFolder}/.venv", - but we use Pipenv and have enforced that with an env var in the project to always install the venv into that dir. There are users who dislike this and want to chose themselves where to place it, which was impossible before since changing the location updated our (shared) .settings file.

@Halkcyon
Copy link

@Almenon At my workplace, we share the workplace folder because it contains everything needed for a project to get started (even extension recommendations).

@karrtikr
Copy link
Author

karrtikr commented Jun 29, 2020

The following workaround will enable you to still share environments if,

  • The workspace folder contains only one virtual environment which you intend to share
  • All your user, workspace, and workspace folder interpreter path settings (python.pythonPath, python.defaultInterpreterPath) are empty.

If all the settings are empty, the extension autoselects the interpreter. The first place the extension looks in for the interpreter is the workspace folder itself, so the intended environment will automatically be selected.

@karrtikr
Copy link
Author

Would it be possible to have a versionable setting

For now, no. The general solution has to come from VSCode microsoft/vscode#40233.

or a sequence of fallbacks that would be traversed in order to pick the default interpreter

We do have a sequence of fallbacks we follow to select the interpreter,

1. First check user settings.json
        If we have user settings, then always use that, do not proceed.
2. Check workspace virtual environments (pipenv, etc).
        If we have some, then use those as preferred workspace environments.
3. Check list of cached interpreters (previously cachced from all the rules).
        If we find a good one, use that as preferred global env.
        Provided its better than what we have already cached as globally preffered interpreter (globallyPreferredInterpreter).
4. Check current path.
        If we find a good one, use that as preferred global env.
        Provided its better than what we have already cached as globally preffered interpreter (globallyPreferredInterpreter).
5. Check windows registry.
        If we find a good one, use that as preferred global env.
        Provided its better than what we have already cached as globally preffered interpreter (globallyPreferredInterpreter).
6. Check the entire system.
        If we find a good one, use that as preferred global env.
        Provided its better than what we have already cached as globally preffered interpreter (globallyPreferredInterpreter).

@jraygauthier
Copy link

jraygauthier commented Jun 30, 2020

For now, no.

Ok.

We do have a sequence of fallbacks we follow to select the interpreter,

It would be really nice to be able to customize via settings this sequence (it ordering, potentially removing some entries and adding some custom entries to it). Wouldn't that be more acceptable to version control than current python.pythonPath?

@karrtikr
Copy link
Author

karrtikr commented Jun 30, 2020

@jraygauthier Maybe, although that seems like much more work. Please take these discussions to #12665

@zor-el @williamcol3 I found one of the security concerns which motivated this solution #7805 for your reference. This was brought to us by the security team at Microsoft and independently by external people.

@williamcol3
Copy link

@zor-el @williamcol3 I found one of the security concerns which motivated this solution #7805 for your reference. This was brought to us by the security team at Microsoft and independently by external people.

Seems like the much easier solution would just be to get the users' permission to use a given path the first time the extension encounters it per workspace. I fail to see how storing the path and keeping it out of settings.json is necessary, but that is not a discussion for this thread.

I still have not seen a benefit that the proposed solution offers that other solutions do not also provide. It does, however, at the very least, have a cost for transitioning. I believe that cost is unnecessary.

@brettcannon
Copy link
Member

brettcannon commented Jul 2, 2020

@williamcol3 unfortunately prompting is a dark, black magic to get right. 😉 People will complain about prompting, and no matter if everyone here swore up and down that they personally would never complain about such a prompt, that doesn't mean other users would not feel put out by a prompting increase. There's also the simple fact that a lot of users just never pay attention to prompts, making the efficacy of them lower than you may expect. Now we obviously still use them to try to get people to pay attention, but this once again feeds back into some users just flat-out hating prompts and just perpetually ignore them.

So it's just not as simple as tossing a prompt up and calling it a day, no matter how much we wished it was.

And I will also say no one has denied that there isn't a cost to this change. But there is also a cost to not enacting a change like this as well. But we are continuing to talk about the situation on the team to see if we can come up with a solution that works for as many users as possible: those that "python.pythonPath", those that don't, and all the while still securing the safety of all of our users.

Followup

microsoft/vscode-eslint#1012 is about when eslint added a prompt requiring users to opt into running eslint via the user workspace and that has not been well received either.

@fredvd

This comment has been minimized.

@fredvd
Copy link

fredvd commented Jul 15, 2020

And on topic: I use VS code to work on projects where we use zc.buildout. It's common practice to have a virtualenv inside every project folder to have an isolated environment. We have even some tooling which can generate/modify the settings.json.

I was never able (since 2019) to get VS code to pick up the correct virtualenv / venv Python automatically. That was until I started setting my pythonPath explicitly in the settings.json using:

"python.pythonPath": "${workspaceFolder}/bin/python3.7"

The settings.json can be shared with other team members or put in VCS as we all have our Python inside the project and everything is relative/inside the workspace. zc.buildout also generates a list with paths of the used Python modules, which are written to an .env file. actually this is also called PYTHONPATH . In my settings.json I use python.envFile for that:

"python.envFile": "${workspaceFolder}/.vscode/.env",

I agree with most other peoples feedback here: if you want to improve the automatic detection (which worked very poorly so far in my experience), do this by all means. But why remove a setting which is used actively by a significant group of users who scaffold the IDE settings using automation tools? Without any fallback?

@zor-el
Copy link

zor-el commented Jul 16, 2020

Am I part of the happy 4% of users who got this new experimental feature? If so, could this be made A LOT clearer than it is now? I run an update and suddenly 'things' are deprecated. [...] It took me 1.5-2 hours to finally get to understand what is going on here, digest all information and fuss and how I can opt out. Thank you for taking me hostage for 2 hours in your experiment, where I only started my editor and accepted an minor update to then get some work done.

@fredvd I can totally relate to how you felt there. As a quick band aid though: I opted out of experiments and my pythonPath is now a valid option again, so everything works as it used to. I also turned off automatic updates so that I can keep a close eye on the changes to this extension before updating it. It's seems like more work, but it's less (and much less stress!) than trying to find out why stuff doesn't work that used to work perfectly. I hope this helps.

@silverguo
Copy link

silverguo commented Jul 18, 2020

I have the same feeling as lots of others in this thread, removing pythonPath is a breaking change to me.

After reading all the comments above, following questions are still unclear to me:

  • Is that already the final decision to remove pythonPath? If so, when will be the official release?
  • Could we have something else to declare the Python interpreter at workspace level? I feel it's more convenient than storing it by VSCode itself.

@jamilraichouni
Copy link

jamilraichouni commented Jul 19, 2020

Throwing in a use case description and some questions

I'm often working on one and the same projects on different computers with different paths, OS, user names.
So far, no matter on what machine I open VS Code, everything works as I'd have never changed the user account or machine.
The state I left a VS Code project on machine A is being restored in a completely different environment on computer B.

This is possible since every piece of setting is stored in human readable files (JSON) or SQLite DBs (editing JSON stored in SQLite is annoying, but still manageable).
Everything needed can be controlled (until now without exception). Something I enjoyed for ten years when using Sublime Text and I'm celebrating the same fact with VS Code so far ...

How that works:

  1. On every machine I set my env var DEVROOT.
  2. There is a ${DEVROOT}/repos/vscode/ which is synced via a remote store for all development computers I use and
    1. All .code-workspace files are at a central place ${DEVROOT}/repos/vscode/workspaces/.
    2. The directories Code and global .vscode (the one with .vscode/extensions) are in ${DEVROOT}/repos/vscode/appdata/`
  3. All projects are in git and checked out to ${DEVROOT}/repos/.

There is a custom CLI tool run for the launch of VS Code (name it wrapper) and also for adapting everything to the current environment (OS, user, machine) when a workspace is being opened.

I have a personal VS Code extension that knows its own "open workspace" command, offers a list of the configured .code-workspace to select from and triggers a kind of onOpenWorkspace event that calls the CLI tool.

When Code is launched

Then the tool iterates over everything of interest below Code/User.

  • Global settings in settings.json,
  • all interesting records in all .vcsdb SQLite databases and
  • other files (e. g. storage.json) are considered.

Finally, the CLI tool sets nice for Code to -20 respectively gives the Code.exe process a high prio in the Windows world.

When a workspace is loaded

The tool touches any setting, debug or task config on workspace level and also iterates over all folder definitions in the file .code-workspace to adapt

  • ${workspaceFolder}/.vscode/settings.json,
  • ${workspaceFolder}/.vscode/tasks.json,
  • ${workspaceFolder}/.vscode/launch.json,
  • ${workspaceFolder}/.env,
  • and more.

Summary

The big number of paths in .code-workspace, .json, .env, .vcsdb etc. files is adapted according to the user and machine dependent env var DEVROOT which is read when Code is being launched.

python.pythonPath is of high importance and set/ considered by the automation at multiple locations.

There are several threads/ posts on GitHub where people describe similar thinks. There are others wrapping VS Code to make it fit for the environment of request.

Questions

What happens when "python.pythonPath" is managed in some internal storage?

Will the current interpreter selection always be written to something an external tool can read from to get live information?
Will the choice for the interpreter be stored for all imaginable combinations of

  • workspace,
  • folder,
  • machine Id, and
  • user?

This hope to avoid that one will always see a prompt telling that the selected interpreter for a given project cannot be found just due to a switch from one computer to another.

Will we see a prompt every first time we change to some new user account/ machine when working on a new project or even a new workspace definition (.code-workspace) for already existing projects?

I hope that will not happen because that would be disruptive and annoying.

All best,
Jamil

@brettcannon
Copy link
Member

As a general answer to people asking what our plans are, we are still planning to move forward with supporting the use-case of not using python.pythonPath by default. BUT we may have a solution to let you all keep python.pythonPath (although we will probably rename the setting to be less confusing as that's a long-standing issue), which will be opt-in and entail waiving all security protections from us in the process. I can't share more until we have a clear spec and we get sign-off from our own security teams with our idea and work through the dev implications for ourselves. And we have no timeline for this, but what I can say is the current experimental semantics will not stop being an experiment until we have reached a final conclusion on this issue one way or another, so can continue to opt out of the experiment if it doesn't work for you.

@ndevenish
Copy link

unfortunately prompting is a dark, black magic to get right.

This comment about wanting to avoid prompting seems ironic given the way it's implemented is to show a prompt that sent me on a 1-2 hour diversion trying to work out what is going to break and why this change was being made, and it will presumably prompt almost every single user if/when it's merged in. Despite what I'm sure is best-intentions, to me this prompting change initially appeared hostile and aggressive; I don't remember consenting to this A/B testing and would never expect to be opted in to such experimental testing when using the VSCode stable builds. Your opt-out mechanism also has the exact same problem that you are purportedly trying to fix here, that there isn't a sub-workspace way to disable them. I'd suggest only deploying such major breaking-change testing to unstable installations in the future - the people who you can actually reasonably assume to have consented to experimental features.

The FAQ and page I'm sent to barely covers anything - and neither of the tickets it sends you do seem to cover much discussion (which was apparently all private). The first ticket #2125 seems to propose "keep pythonPath, fallback to local storage after workspace settings, this is an opt-in behaviour", but this doesn't seem to have been used, maybe because of the security concerns(?) but I couldn't see that discussed.

The questions I have (I realise some of which are touched on above) are:

  • Why is supporting/pushing development of local-settings features (e.g. Add ability to extend from other settings files vscode#15909 and [Feature] Local Workspace settings vscode#40233) not an option, and will this new way be changed again if/when they are implemented?
  • Does localstorage persist even if you don't explicitly reopen a workspace? I exclusively work on workspaces by opening directories with code <path>, without almost ever saving and loading "code-workspace" files. Will this be persisted? (I can't tell if it's not stored in a human-readable adjacent storage)
  • Whereas adding settings.json to the repo generally does sound like an antipattern, I realise that not doing so requires some extra effort. Since this seems to canonicalise this approach, is sharing a single central python install for a workspace now impossible?
  • Why does it need to be renamed? (incidentally a single "fix this for me [always|yes|no|never]" prompt or even automatic rewriting on a deprecation/changeover schedule sounds perfectly reasonable if this is an issue on it's own, conflating it with a massive change of behaviour sounds like wasting a lot of developers time)
  • Given that storing in the workspace settings looks like it's going to be an extremely minor use case, Prompting the first time a new path (globally?) is seen if and only if pythonPath is in the workspace, but saving pythonPath to localstorage if specified by the user, sounds like the best of both worlds, and for most users will not cause a prompt - either having no workspace with it specified or by having global pythonPath. Could even choose not to allow/trust python versions under the workspace automatically? Storing this (repromptable or ephemeral, easily regenerated when missing) information sounds like exactly what the localstorage is designed for?

I've had to try and dig through the internal storage before when I accidentally disabled a prompt I wanted to keep; and this was a nightmare, and it remains the case that VSCode really does have a lot of prompts that you need to pay attention to anyway.

I've been a keen VSCode user for ~4 years, and recommend to people. Obviously I'm not going to stop using it but this A/B being forced into my face and public "all our discussions on this breaking change are private, you aren't allowed to know why" attitude really is the first thing that has even a little damaged my confidence.

I'm opting out of this "feature" and all experiments now.

@brettcannon

This comment has been minimized.

@luabud
Copy link
Member

luabud commented Jul 22, 2020

@fredvd you mentioned the following:

Am I part of the happy 4% of users who got this new experimental feature? If so, could this be made A LOT clearer than it is now?

We tried to make that clear in the wiki page we linked to in the notification prompt. What would have been more helpful, or at least have prevented you from spending a lot of time understanding what is going on?

@jamilraichouni thanks for detailing your scenario. If python.defaultInterpreterPath is set in the User settings.json, then it will be picked up by the Python extension for the workspace you open. However if your tool configures it when launching VS Code and you switch between repos that would need different interpreters, then you would need to select the interpreter once per workspace and per machine. Your scenario and the one described in this comment are good examples of breaking changes, hence why we're working on an iteration plan as Brett mentioned.

@ndevenish This isn't an "experimental" change. We use the A/B experiment framework to gradually roll out changes instead of shipping to everyone as we normally would. We use that so we can get feedback and iterate on changes while providing a workaround to disable them (other than downgrading the extension and disabling auto-updates). We knew we had to make this change for security reasons, but we wanted to offer an explanation to those in the experiment as to what is going on and how to opt-out as we iterate on it. That was our intent with the wiki page. If there's more information we can add to that page that would help with answering questions, we’ll be happy to do so.

As to your questions:

Why is supporting/pushing development of local-settings features (e.g. microsoft/vscode#15909 and microsoft/vscode#40233) not an option, and will this new way be changed again if/when they are implemented?

Because it doesn't solve the security concern that was brought up to us (e.g. #7805). Depending on the solution we deliver for this as mentioned by Brett, we may be able to have an opt-in mechanism for the python.pythonPath setting while still maintaining security protections, and then it could be used normally if microsoft/vscode#40233 is implemented.

Does localstorage persist even if you don't explicitly reopen a workspace? I exclusively work on workspaces by opening directories with code , without almost ever saving and loading "code-workspace" files. Will this be persisted? (I can't tell if it's not stored in a human-readable adjacent storage)

Yes, it does as a workspace in VS Code is just the project root folder (not necessarily .code-workspace files, although it persists for those too).

Whereas adding settings.json to the repo generally does sound like an antipattern, I realise that not doing so requires some extra effort. Since this seems to canonicalise this approach, is sharing a single central python install for a workspace now impossible?

Not impossible. You could add the path to the python.defaultInterpreterPath in the user setting to be picked up automatically when you open a folder/workspace. Otherwise if it's a valid interpreter, it should be displayed in the list of environments available to be selected once you run the Python: Select Interpreter command. In that case it would be a one-time selection of the interpreter for the project (per machine). If the interpreter isn't available in the list, you can still add the path to it like you do for python.pythonPath setting. The only difference is that it's not stored in the settings.json file. You can still see if the extension selected the right interpreter by checking the path in the Python output channel.

This may change though, as Brett mentioned in the comment above. We're not saying we will never offer an opt-in mechanism to share interpreter paths, we're just saying that it needs to be opt-in and not on by default.

Why does it need to be renamed?

Because the name is confusing given the PYTHONPATH env variable. E.g. #8646.

Given that storing in the workspace settings looks like it's going to be an extremely minor use case, Prompting the first time a new path (globally?) is seen if and only if pythonPath is in the workspace, but saving pythonPath to localstorage if specified by the user, sounds like the best of both worlds, and for most users will not cause a prompt - either having no workspace with it specified or by having global pythonPath. Could even choose not to allow/trust python versions under the workspace automatically? Storing this (repromptable or ephemeral, easily regenerated when missing) information sounds like exactly what the localstorage is designed for?

These are things to be considered in our plan but again as Brett mentioned, our solution needs to take into account technical implications and we need to get sign-off from our own security teams.

Obviously I'm not going to stop using it but this A/B being forced into my face and public "all our discussions on this breaking change are private, you aren't allowed to know why" attitude really is the first thing that has even a little damaged my confidence.

I explained the reason why we use the A/B framework for controlled rollout. As to the private discussions you mentioned, part of security concerns are exemplified in #7805, though we were specifically asked not to give more details so we don’t give attackers a heads-up on how to exploit users.

@jamilraichouni
Copy link

jamilraichouni commented Jul 22, 2020

Thanks for this detailed feedback!

One question:

Is there any true specification describing in detail where and how this new way of storing the interpreter selection in the local storage is happening/ working?

VS Code is by far the most used tool on my side to do the daily business and also private stuff. For devs mostly doing Python development that setting is very central and of importance. I'd like to keep having a good understanding of what is happening under the hood. It is imaginable that others also want to see, if and how one can adapt automation tools to read and/ or touch this setting from outside (e. g. wrapper).

Is that possible?

Thank you,
Jamil

@luabud luabud added needs proposal Need to make some design decisions and removed needs decision labels Jul 22, 2020
@brettcannon
Copy link
Member

Is there any true specification describing in detail where and how this new way of storing the interpreter selection in the local storage is happening/ working?

Yes, all features like this get a spec written by the team internally. Since the code is already committed, you can have a look yourself, but we are using VS Code's private store for extensions to store the path to the environment.

Is that possible?

I am going to answer this by saying we are working on a potential spec and the required teams to be involved is growing, so we need to ask people to please be patient while we work through this.

@Halkcyon

This comment has been minimized.

@microsoft microsoft locked as too heated and limited conversation to collaborators Jul 23, 2020
@brettcannon

This comment has been minimized.

@brettcannon brettcannon changed the title Queries about moving workspace pythonPath setting into VSCode storage Details on the A/B experiment removing python.pythonPath support Jul 23, 2020
@brettcannon brettcannon pinned this issue Jul 23, 2020
@karrtikr
Copy link
Author

Hi everyone👋

We have replaced this experiment in favor of a new one which is slowly being rolled out. You can find the details in the updated wiki. In short,

  • The python.pythonPath setting is no longer used by the Python extension.
  • A new optional setting python.defaultInterpreterPath is introduced in the user and workspace scope, from which the extension will read the value when loading a project for the first time.
  • Changes to the python.defaultInterpreterPath will not be picked up by the Python extension once an interpreter is already selected for the workspace. The extension will also not set nor change the value of this setting, it will only read from it.

Essentially python.defaultInterpreterPath will be used as a fallback if no interpreter has been set. So you can use python.defaultInterpreterPath to share default vscode settings, but we do not modify the setting when you change an interpreter using Python: Select Interpreter command or the status bar.

Hopefully that'll work for most use cases. You can open new issues to provide feedback.

@brettcannon brettcannon unpinned this issue Jul 28, 2021
@brettcannon
Copy link
Member

https://devblogs.microsoft.com/python/python-in-visual-studio-code-july-2021-release/#selecting-a-python-interpreter-no-longer-modifies-workspace-settings announced how we resolved dropping python.pythonPath while still providing a way for people to specify via settings the environment they wanted selected.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-environments Features relating to handling interpreter environments feature-request Request for new features or functionality needs proposal Need to make some design decisions
Projects
None yet
Development

No branches or pull requests