Skip to content

Commit ebaba5c

Browse files
Cherry-pick pipenv changes and pythonpath prompt changes to release (#11700)
* Show the prompt again if user clicks on more info (#11664) * Show the prompt again if user clicks on more info * Review feedback * Use Learn more as text for the link. * Leave pipenv in a corner until the user decides to select an interpreter (#11654) * add onSuggestion option * Swap onActivation with onSuggestion * Update unit tests * Remove registration of IPipenvService * Move didTriggerInterpreterSuggestions logic inside pipenv locator * Fix existing unit tests * Add new unit tests * Replace typemoq any param with object * Shorten the tests * Fix warning * Duplicate teardown Co-authored-by: Kim-Adeline Miguel <[email protected]>
1 parent 11c0cbf commit ebaba5c

File tree

28 files changed

+315
-239
lines changed

28 files changed

+315
-239
lines changed

package.nls.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@
240240
"DataScience.liveShareServiceFailure": "Failure starting '{0}' service during live share connection.",
241241
"DataScience.documentMismatch": "Cannot run cells, duplicate documents for {0} found.",
242242
"DataScience.pythonInteractiveCreateFailed": "Failure to create a 'Python Interactive' window. Try reinstalling the Python extension.",
243-
"diagnostics.removePythonPathSettingsJson": "The setting \"python.pythonPath\" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the \"python.pythonPath\" entry from your settings.json.",
244-
"diagnostics.removePythonPathCodeWorkspace": "The setting \"python.pythonPath\" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the \"python.pythonPath\" entry from your .code-workspace file.",
245-
"diagnostics.removePythonPathCodeWorkspaceAndSettingsJson": "The setting \"python.pythonPath\" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the \"python.pythonPath\" entry from your settings.json and .code-workspace file.",
243+
"diagnostics.removePythonPathSettingsJson": "The setting \"python.pythonPath\" defined in your settings.json is now deprecated. Do you want us to delete it from your settings.json only? [Learn more](https://aka.ms/AA7jfor).",
244+
"diagnostics.removePythonPathCodeWorkspace": "The setting \"python.pythonPath\" defined in your workspace settings is now deprecated. Do you want us to delete it from your .code-workspace file only? [Learn more](https://aka.ms/AA7jfor).",
245+
"diagnostics.removePythonPathCodeWorkspaceAndSettingsJson": "The setting \"python.pythonPath\" defined in your workspace settings is now deprecated. Do you want us to delete it from your .code-workspace file and settings.json? [Learn more](https://aka.ms/AA7jfor).",
246246
"diagnostics.warnSourceMaps": "Source map support is enabled in the Python Extension, this will adversely impact performance of the extension.",
247247
"diagnostics.disableSourceMaps": "Disable Source Map Support",
248248
"diagnostics.warnBeforeEnablingSourceMaps": "Enabling source map support in the Python Extension will adversely impact performance of the extension.",

src/client/activation/activationManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager {
7373
this.experiments.sendTelemetryIfInExperiment(DeprecatePythonPath.control);
7474

7575
// Get latest interpreter list in the background.
76-
this.interpreterService.getInterpreters(resource, { onActivation: true }).ignoreErrors();
76+
this.interpreterService.getInterpreters(resource).ignoreErrors();
7777

7878
await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource);
7979

src/client/application/diagnostics/checks/macPythonInterpreter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export class InvalidMacPythonInterpreterService extends BaseDiagnosticsService {
101101
return [];
102102
}
103103

104-
const interpreters = await this.interpreterService.getInterpreters(resource, { onActivation: true });
104+
const interpreters = await this.interpreterService.getInterpreters(resource);
105105
if (interpreters.filter((i) => !this.helper.isMacDefaultPythonPath(i.path)).length === 0) {
106106
return [
107107
new InvalidMacPythonInterpreterDiagnostic(

src/client/application/diagnostics/checks/pythonPathDeprecated.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { IWorkspaceService } from '../../../common/application/types';
99
import { DeprecatePythonPath } from '../../../common/experimentGroups';
1010
import { IDisposableRegistry, IExperimentsManager, Resource } from '../../../common/types';
1111
import { Common, Diagnostics } from '../../../common/utils/localize';
12-
import { learnMoreOnInterpreterSecurityURI } from '../../../interpreter/autoSelection/constants';
1312
import { IServiceContainer } from '../../../ioc/types';
1413
import { BaseDiagnostic, BaseDiagnosticsService } from '../base';
1514
import { IDiagnosticsCommandFactory } from '../commands/types';
@@ -97,13 +96,6 @@ export class PythonPathDeprecatedDiagnosticService extends BaseDiagnosticsServic
9796
{
9897
prompt: Common.noIWillDoItLater()
9998
},
100-
{
101-
prompt: Common.moreInfo(),
102-
command: commandFactory.createCommand(diagnostic, {
103-
type: 'launch',
104-
options: learnMoreOnInterpreterSecurityURI
105-
})
106-
},
10799
{
108100
prompt: Common.doNotShowAgain(),
109101
command: commandFactory.createCommand(diagnostic, { type: 'ignore', options: DiagnosticScope.Global })

src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@
33

44
'use strict';
55

6-
import { inject, injectable } from 'inversify';
6+
import { inject, injectable, named } from 'inversify';
77
import { Uri } from 'vscode';
88
import '../../../common/extensions';
9-
import { IInterpreterService, InterpreterType, IPipEnvService } from '../../../interpreter/contracts';
9+
import {
10+
IInterpreterLocatorService,
11+
IInterpreterService,
12+
InterpreterType,
13+
IPipEnvService,
14+
PIPENV_SERVICE
15+
} from '../../../interpreter/contracts';
1016
import { IWorkspaceService } from '../../application/types';
1117
import { IFileSystem } from '../../platform/types';
1218
import { ITerminalActivationCommandProvider, TerminalShellType } from '../types';
@@ -15,7 +21,9 @@ import { ITerminalActivationCommandProvider, TerminalShellType } from '../types'
1521
export class PipEnvActivationCommandProvider implements ITerminalActivationCommandProvider {
1622
constructor(
1723
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService,
18-
@inject(IPipEnvService) private readonly pipenvService: IPipEnvService,
24+
@inject(IInterpreterLocatorService)
25+
@named(PIPENV_SERVICE)
26+
private readonly pipenvService: IPipEnvService,
1927
@inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService,
2028
@inject(IFileSystem) private readonly fs: IFileSystem
2129
) {}

src/client/common/utils/localize.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ export namespace Diagnostics {
3232
);
3333
export const removePythonPathSettingsJson = localize(
3434
'diagnostics.removePythonPathSettingsJson',
35-
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the "python.pythonPath" entry from your settings.json.'
35+
'The setting "python.pythonPath" defined in your settings.json is now deprecated. Do you want us to delete it from your settings.json only? [Learn more](https://aka.ms/AA7jfor).'
3636
);
3737
export const removePythonPathCodeWorkspace = localize(
3838
'diagnostics.removePythonPathCodeWorkspace',
39-
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the "python.pythonPath" entry from your .code-workspace file.'
39+
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it from your .code-workspace file only? [Learn more](https://aka.ms/AA7jfor).'
4040
);
4141
export const removePythonPathCodeWorkspaceAndSettingsJson = localize(
4242
'diagnostics.removePythonPathCodeWorkspaceAndSettingsJson',
43-
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it? This will only remove the "python.pythonPath" entry from your settings.json and .code-workspace file.'
43+
'The setting "python.pythonPath" defined in your workspace settings is now deprecated. Do you want us to delete it from your .code-workspace file and settings.json? [Learn more](https://aka.ms/AA7jfor).'
4444
);
4545
export const invalidPythonPathInDebuggerSettings = localize(
4646
'diagnostics.invalidPythonPathInDebuggerSettings',

src/client/interpreter/autoSelection/rules/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class SystemWideInterpretersAutoSelectionRule extends BaseRuleService {
2525
resource: Resource,
2626
manager?: IInterpreterAutoSelectionService
2727
): Promise<NextAction> {
28-
const interpreters = await this.interpreterService.getInterpreters(resource, { onActivation: true });
28+
const interpreters = await this.interpreterService.getInterpreters(resource);
2929
// Exclude non-local interpreters.
3030
const filteredInterpreters = interpreters.filter(
3131
(int) =>

src/client/interpreter/configuration/interpreterSelector/interpreterSelector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class InterpreterSelector implements IInterpreterSelector {
2727
}
2828

2929
public async getSuggestions(resource: Resource) {
30-
let interpreters = await this.interpreterManager.getInterpreters(resource);
30+
let interpreters = await this.interpreterManager.getInterpreters(resource, { onSuggestion: true });
3131
if (this.experimentsManager.inExperiment(DeprecatePythonPath.experiment)) {
3232
interpreters = interpreters.filter((item) => this.interpreterSecurityService.isSafe(item) !== false);
3333
}

src/client/interpreter/contracts.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface IVirtualEnvironmentsSearchPathProvider {
2828
}
2929

3030
export type GetInterpreterOptions = {
31-
onActivation?: boolean;
31+
onSuggestion?: boolean;
3232
};
3333

3434
export type GetInterpreterLocatorOptions = GetInterpreterOptions & { ignoreCache?: boolean };
@@ -38,6 +38,7 @@ export const IInterpreterLocatorService = Symbol('IInterpreterLocatorService');
3838
export interface IInterpreterLocatorService extends Disposable {
3939
readonly onLocating: Event<Promise<PythonInterpreter[]>>;
4040
readonly hasInterpreters: Promise<boolean>;
41+
didTriggerInterpreterSuggestions?: boolean;
4142
getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise<PythonInterpreter[]>;
4243
}
4344

@@ -126,7 +127,7 @@ export interface IInterpreterHelper {
126127
}
127128

128129
export const IPipEnvService = Symbol('IPipEnvService');
129-
export interface IPipEnvService {
130+
export interface IPipEnvService extends IInterpreterLocatorService {
130131
executable: string;
131132
isRelatedPipEnvironment(dir: string, pythonPath: string): Promise<boolean>;
132133
}

src/client/interpreter/locators/index.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ const flatten = require('lodash/flatten') as typeof import('lodash/flatten');
3030
*/
3131
@injectable()
3232
export class PythonInterpreterLocatorService implements IInterpreterLocatorService {
33+
public didTriggerInterpreterSuggestions: boolean;
34+
3335
private readonly disposables: Disposable[] = [];
3436
private readonly platform: IPlatformService;
3537
private readonly interpreterLocatorHelper: IInterpreterLocatorHelper;
3638
private readonly _hasInterpreters: Deferred<boolean>;
39+
3740
constructor(
3841
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
3942
@inject(InterpreterFilter) private readonly interpreterFilter: IInterpreterFilter
@@ -42,6 +45,7 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi
4245
serviceContainer.get<Disposable[]>(IDisposableRegistry).push(this);
4346
this.platform = serviceContainer.get<IPlatformService>(IPlatformService);
4447
this.interpreterLocatorHelper = serviceContainer.get<IInterpreterLocatorHelper>(IInterpreterLocatorHelper);
48+
this.didTriggerInterpreterSuggestions = false;
4549
}
4650
/**
4751
* This class should never emit events when we're locating.
@@ -106,18 +110,27 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi
106110
// The order is important because the data sources at the bottom of the list do not contain all,
107111
// the information about the interpreters (e.g. type, environment name, etc).
108112
// This way, the items returned from the top of the list will win, when we combine the items returned.
109-
const keys: [string | undefined, OSType | undefined][] = [
113+
const keys: [string, OSType | undefined][] = [
110114
[WINDOWS_REGISTRY_SERVICE, OSType.Windows],
111115
[CONDA_ENV_SERVICE, undefined],
112116
[CONDA_ENV_FILE_SERVICE, undefined],
113-
options?.onActivation ? [undefined, undefined] : [PIPENV_SERVICE, undefined],
117+
[PIPENV_SERVICE, undefined],
114118
[GLOBAL_VIRTUAL_ENV_SERVICE, undefined],
115119
[WORKSPACE_VIRTUAL_ENV_SERVICE, undefined],
116120
[KNOWN_PATH_SERVICE, undefined],
117121
[CURRENT_PATH_SERVICE, undefined]
118122
];
119-
return keys
120-
.filter((item) => item[0] !== undefined && (item[1] === undefined || item[1] === this.platform.osType))
123+
124+
const locators = keys
125+
.filter((item) => item[1] === undefined || item[1] === this.platform.osType)
121126
.map((item) => this.serviceContainer.get<IInterpreterLocatorService>(IInterpreterLocatorService, item[0]));
127+
128+
// Set it to true the first time the user selects an interpreter
129+
if (!this.didTriggerInterpreterSuggestions && options?.onSuggestion === true) {
130+
this.didTriggerInterpreterSuggestions = true;
131+
locators.forEach((locator) => (locator.didTriggerInterpreterSuggestions = true));
132+
}
133+
134+
return locators;
122135
}
123136
}

0 commit comments

Comments
 (0)