Skip to content

Commit 18bc975

Browse files
author
Kartik Raj
committed
Hide 'untrusted' interpreters from 'Select interpreter' dropdown list
1 parent d95f454 commit 18bc975

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

src/client/interpreter/configuration/interpreterSelector.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import {
88
IWorkspaceService
99
} from '../../common/application/types';
1010
import { Commands } from '../../common/constants';
11-
import { IConfigurationService, IPathUtils, Resource } from '../../common/types';
11+
import { DeprecatePythonPath } from '../../common/experimentGroups';
12+
import { IConfigurationService, IExperimentsManager, IPathUtils, Resource } from '../../common/types';
1213
import { Interpreters } from '../../common/utils/localize';
14+
import { IInterpreterSecurityService } from '../autoSelection/types';
1315
import { IInterpreterService, IShebangCodeLensProvider, PythonInterpreter } from '../contracts';
1416
import {
1517
IInterpreterComparer,
@@ -33,7 +35,9 @@ export class InterpreterSelector implements IInterpreterSelector {
3335
private readonly pythonPathUpdaterService: IPythonPathUpdaterServiceManager,
3436
@inject(IShebangCodeLensProvider) private readonly shebangCodeLensProvider: IShebangCodeLensProvider,
3537
@inject(IConfigurationService) private readonly configurationService: IConfigurationService,
36-
@inject(ICommandManager) private readonly commandManager: ICommandManager
38+
@inject(ICommandManager) private readonly commandManager: ICommandManager,
39+
@inject(IExperimentsManager) private readonly experimentsManager: IExperimentsManager,
40+
@inject(IInterpreterSecurityService) private readonly interpreterSecurityService: IInterpreterSecurityService
3741
) {}
3842
public dispose() {
3943
this.disposables.forEach((disposable) => disposable.dispose());
@@ -52,7 +56,11 @@ export class InterpreterSelector implements IInterpreterSelector {
5256
}
5357

5458
public async getSuggestions(resource: Resource) {
55-
const interpreters = await this.interpreterManager.getInterpreters(resource);
59+
let interpreters = await this.interpreterManager.getInterpreters(resource);
60+
if (this.experimentsManager.inExperiment(DeprecatePythonPath.experiment)) {
61+
interpreters = interpreters.filter((item) => this.interpreterSecurityService.isSafe(item) !== false);
62+
}
63+
this.experimentsManager.sendTelemetryIfInExperiment(DeprecatePythonPath.control);
5664
interpreters.sort(this.interpreterComparer.compare.bind(this.interpreterComparer));
5765
return Promise.all(interpreters.map((item) => this.suggestionToQuickPickItem(item, resource)));
5866
}

src/test/configuration/interpreterSelector.unit.test.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import {
1212
IDocumentManager,
1313
IWorkspaceService
1414
} from '../../client/common/application/types';
15+
import { DeprecatePythonPath } from '../../client/common/experimentGroups';
1516
import { PathUtils } from '../../client/common/platform/pathUtils';
1617
import { IFileSystem } from '../../client/common/platform/types';
17-
import { IConfigurationService, IPythonSettings } from '../../client/common/types';
18+
import { IConfigurationService, IExperimentsManager, IPythonSettings } from '../../client/common/types';
1819
import { Interpreters } from '../../client/common/utils/localize';
1920
import { Architecture } from '../../client/common/utils/platform';
21+
import { IInterpreterSecurityService } from '../../client/interpreter/autoSelection/types';
2022
import { InterpreterSelector } from '../../client/interpreter/configuration/interpreterSelector';
2123
import {
2224
IInterpreterComparer,
@@ -66,6 +68,8 @@ suite('Interpreters - selector', () => {
6668
let comparer: TypeMoq.IMock<IInterpreterComparer>;
6769
let pythonPathUpdater: TypeMoq.IMock<IPythonPathUpdaterServiceManager>;
6870
let shebangProvider: TypeMoq.IMock<IShebangCodeLensProvider>;
71+
let experimentsManager: TypeMoq.IMock<IExperimentsManager>;
72+
let interpreterSecurityService: TypeMoq.IMock<IInterpreterSecurityService>;
6973
let configurationService: TypeMoq.IMock<IConfigurationService>;
7074
let pythonSettings: TypeMoq.IMock<IPythonSettings>;
7175
const folder1 = { name: 'one', uri: Uri.parse('one'), index: 1 };
@@ -96,6 +100,12 @@ suite('Interpreters - selector', () => {
96100
let selector: TestInterpreterSelector;
97101

98102
setup(() => {
103+
experimentsManager = TypeMoq.Mock.ofType<IExperimentsManager>();
104+
experimentsManager.setup((e) => e.inExperiment(DeprecatePythonPath.experiment)).returns(() => false);
105+
experimentsManager
106+
.setup((e) => e.sendTelemetryIfInExperiment(DeprecatePythonPath.control))
107+
.returns(() => undefined);
108+
interpreterSecurityService = TypeMoq.Mock.ofType<IInterpreterSecurityService>();
99109
commandManager = TypeMoq.Mock.ofType<ICommandManager>();
100110
comparer = TypeMoq.Mock.ofType<IInterpreterComparer>();
101111
appShell = TypeMoq.Mock.ofType<IApplicationShell>();
@@ -124,7 +134,9 @@ suite('Interpreters - selector', () => {
124134
pythonPathUpdater.object,
125135
shebangProvider.object,
126136
configurationService.object,
127-
commandManager.object
137+
commandManager.object,
138+
experimentsManager.object,
139+
interpreterSecurityService.object
128140
);
129141
});
130142

@@ -140,7 +152,9 @@ suite('Interpreters - selector', () => {
140152
pythonPathUpdater.object,
141153
shebangProvider.object,
142154
configurationService.object,
143-
commandManager.object
155+
commandManager.object,
156+
experimentsManager.object,
157+
interpreterSecurityService.object
144158
);
145159

146160
const initial: PythonInterpreter[] = [
@@ -184,6 +198,27 @@ suite('Interpreters - selector', () => {
184198
});
185199
});
186200

201+
test('When in Deprecate PythonPath experiment, do not unsafe interpreters in the suggested interpreters list', async () => {
202+
// tslint:disable-next-line: no-any
203+
const interpreterList = ['interpreter1', 'interpreter2', 'interpreter3'] as any;
204+
interpreterService.setup((i) => i.getInterpreters(folder1.uri)).returns(() => interpreterList);
205+
// tslint:disable-next-line: no-any
206+
interpreterSecurityService.setup((i) => i.isSafe('interpreter1' as any)).returns(() => true);
207+
// tslint:disable-next-line: no-any
208+
interpreterSecurityService.setup((i) => i.isSafe('interpreter2' as any)).returns(() => false);
209+
// tslint:disable-next-line: no-any
210+
interpreterSecurityService.setup((i) => i.isSafe('interpreter3' as any)).returns(() => undefined);
211+
experimentsManager.reset();
212+
experimentsManager.setup((e) => e.inExperiment(DeprecatePythonPath.experiment)).returns(() => true);
213+
experimentsManager
214+
.setup((e) => e.sendTelemetryIfInExperiment(DeprecatePythonPath.control))
215+
.returns(() => undefined);
216+
// tslint:disable-next-line: no-any
217+
selector.suggestionToQuickPickItem = (item, _) => Promise.resolve(item as any);
218+
const suggestion = await selector.getSuggestions(folder1.uri);
219+
assert.deepEqual(suggestion, ['interpreter1', 'interpreter3']);
220+
});
221+
187222
// tslint:disable-next-line: max-func-body-length
188223
suite('Test method setInterpreter()', async () => {
189224
test('Update Global settings when there are no workspaces', async () => {

0 commit comments

Comments
 (0)