Skip to content

Commit bed31ba

Browse files
author
Kartik Raj
authored
Do not show 'No interpreter is selected' when pythonPath in debug configuration is invalid (#14892)
* Assume source is launch.json for new properties if they're not equal to pythonPath * Add tests * Code reviews
1 parent e5c8fbb commit bed31ba

File tree

3 files changed

+153
-19
lines changed

3 files changed

+153
-19
lines changed

news/2 Fixes/14814.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not show "You need to select a Python interpreter before you start debugging" when "python" in debug configuration is invalid.

src/client/debugger/extension/configuration/resolvers/launch.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { IPlatformService } from '../../../../common/platform/types';
1212
import { IConfigurationService } from '../../../../common/types';
1313
import { DebuggerTypeName } from '../../../constants';
1414
import { DebugOptions, LaunchRequestArguments } from '../../../types';
15+
import { PythonPathSource } from '../../types';
1516
import { BaseConfigurationResolver } from './base';
1617
import { IDebugEnvironmentVariablesService } from './helper';
1718

@@ -183,18 +184,17 @@ export class LaunchConfigurationResolver extends BaseConfigurationResolver<Launc
183184
debugConfiguration: LaunchRequestArguments
184185
): Promise<boolean> {
185186
const diagnosticService = this.invalidPythonPathInDebuggerService;
186-
return (
187-
diagnosticService.validatePythonPath(debugConfiguration.python, this.pythonPathSource, folder?.uri) &&
188-
diagnosticService.validatePythonPath(
189-
debugConfiguration.debugAdapterPython,
190-
this.pythonPathSource,
191-
folder?.uri
192-
) &&
193-
diagnosticService.validatePythonPath(
194-
debugConfiguration.debugLauncherPython,
195-
this.pythonPathSource,
196-
folder?.uri
197-
)
198-
);
187+
for (const executable of [
188+
debugConfiguration.python,
189+
debugConfiguration.debugAdapterPython,
190+
debugConfiguration.debugLauncherPython
191+
]) {
192+
const source =
193+
executable === debugConfiguration.pythonPath ? this.pythonPathSource : PythonPathSource.launchJson;
194+
if (!(await diagnosticService.validatePythonPath(executable, source, folder?.uri))) {
195+
return false;
196+
}
197+
}
198+
return true;
199199
}
200200
}

src/test/debugger/extension/configuration/resolvers/launch.unit.test.ts

Lines changed: 139 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { OSType } from '../../../../../client/common/utils/platform';
1818
import { DebuggerTypeName } from '../../../../../client/debugger/constants';
1919
import { IDebugEnvironmentVariablesService } from '../../../../../client/debugger/extension/configuration/resolvers/helper';
2020
import { LaunchConfigurationResolver } from '../../../../../client/debugger/extension/configuration/resolvers/launch';
21+
import { PythonPathSource } from '../../../../../client/debugger/extension/types';
2122
import { DebugOptions, LaunchRequestArguments } from '../../../../../client/debugger/types';
2223
import { IInterpreterHelper } from '../../../../../client/interpreter/contracts';
2324
import { getOSType } from '../../../../common';
@@ -928,6 +929,8 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
928929

929930
test('Test validation of Python Path when launching debugger (with invalid "python")', async () => {
930931
const pythonPath = `PythonPath_${new Date().toString()}`;
932+
const debugLauncherPython = `DebugLauncherPythonPath_${new Date().toString()}`;
933+
const debugAdapterPython = `DebugAdapterPythonPath_${new Date().toString()}`;
931934
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
932935
const pythonFile = 'xyz.py';
933936
setupIoc(pythonPath);
@@ -936,23 +939,49 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
936939
diagnosticsService.reset();
937940
diagnosticsService
938941
.setup((h) =>
939-
h.validatePythonPath(TypeMoq.It.isValue(pythonPath), TypeMoq.It.isAny(), TypeMoq.It.isAny())
942+
h.validatePythonPath(
943+
TypeMoq.It.isValue(pythonPath),
944+
PythonPathSource.launchJson,
945+
TypeMoq.It.isAny()
946+
)
940947
)
941-
.returns(() => Promise.resolve(false))
942-
.verifiable(TypeMoq.Times.atLeastOnce());
948+
// Invalid
949+
.returns(() => Promise.resolve(false));
950+
diagnosticsService
951+
.setup((h) =>
952+
h.validatePythonPath(
953+
TypeMoq.It.isValue(debugLauncherPython),
954+
PythonPathSource.launchJson,
955+
TypeMoq.It.isAny()
956+
)
957+
)
958+
.returns(() => Promise.resolve(true));
959+
diagnosticsService
960+
.setup((h) =>
961+
h.validatePythonPath(
962+
TypeMoq.It.isValue(debugAdapterPython),
963+
PythonPathSource.launchJson,
964+
TypeMoq.It.isAny()
965+
)
966+
)
967+
.returns(() => Promise.resolve(true));
943968

944969
const debugConfig = await resolveDebugConfiguration(workspaceFolder, {
945970
...launch,
946971
redirectOutput: false,
947-
python: pythonPath
972+
python: pythonPath,
973+
debugLauncherPython,
974+
debugAdapterPython
948975
});
949976

950977
diagnosticsService.verifyAll();
951978
expect(debugConfig).to.be.equal(undefined, 'Not undefined');
952979
});
953980

954-
test('Test validation of Python Path when launching debugger (with valid "python")', async () => {
981+
test('Test validation of Python Path when launching debugger (with invalid "debugLauncherPython")', async () => {
955982
const pythonPath = `PythonPath_${new Date().toString()}`;
983+
const debugLauncherPython = `DebugLauncherPythonPath_${new Date().toString()}`;
984+
const debugAdapterPython = `DebugAdapterPythonPath_${new Date().toString()}`;
956985
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
957986
const pythonFile = 'xyz.py';
958987
setupIoc(pythonPath);
@@ -961,7 +990,111 @@ getInfoPerOS().forEach(([osName, osType, path]) => {
961990
diagnosticsService.reset();
962991
diagnosticsService
963992
.setup((h) =>
964-
h.validatePythonPath(TypeMoq.It.isValue(pythonPath), TypeMoq.It.isAny(), TypeMoq.It.isAny())
993+
h.validatePythonPath(
994+
TypeMoq.It.isValue(pythonPath),
995+
PythonPathSource.launchJson,
996+
TypeMoq.It.isAny()
997+
)
998+
)
999+
.returns(() => Promise.resolve(true));
1000+
diagnosticsService
1001+
.setup((h) =>
1002+
h.validatePythonPath(
1003+
TypeMoq.It.isValue(debugLauncherPython),
1004+
PythonPathSource.launchJson,
1005+
TypeMoq.It.isAny()
1006+
)
1007+
)
1008+
// Invalid
1009+
.returns(() => Promise.resolve(false));
1010+
diagnosticsService
1011+
.setup((h) =>
1012+
h.validatePythonPath(
1013+
TypeMoq.It.isValue(debugAdapterPython),
1014+
PythonPathSource.launchJson,
1015+
TypeMoq.It.isAny()
1016+
)
1017+
)
1018+
.returns(() => Promise.resolve(true));
1019+
1020+
const debugConfig = await resolveDebugConfiguration(workspaceFolder, {
1021+
...launch,
1022+
redirectOutput: false,
1023+
python: pythonPath,
1024+
debugLauncherPython,
1025+
debugAdapterPython
1026+
});
1027+
1028+
diagnosticsService.verifyAll();
1029+
expect(debugConfig).to.be.equal(undefined, 'Not undefined');
1030+
});
1031+
1032+
test('Test validation of Python Path when launching debugger (with invalid "debugAdapterPython")', async () => {
1033+
const pythonPath = `PythonPath_${new Date().toString()}`;
1034+
const debugLauncherPython = `DebugLauncherPythonPath_${new Date().toString()}`;
1035+
const debugAdapterPython = `DebugAdapterPythonPath_${new Date().toString()}`;
1036+
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
1037+
const pythonFile = 'xyz.py';
1038+
setupIoc(pythonPath);
1039+
setupActiveEditor(pythonFile, PYTHON_LANGUAGE);
1040+
1041+
diagnosticsService.reset();
1042+
diagnosticsService
1043+
.setup((h) =>
1044+
h.validatePythonPath(
1045+
TypeMoq.It.isValue(pythonPath),
1046+
PythonPathSource.launchJson,
1047+
TypeMoq.It.isAny()
1048+
)
1049+
)
1050+
.returns(() => Promise.resolve(true));
1051+
diagnosticsService
1052+
.setup((h) =>
1053+
h.validatePythonPath(
1054+
TypeMoq.It.isValue(debugLauncherPython),
1055+
PythonPathSource.launchJson,
1056+
TypeMoq.It.isAny()
1057+
)
1058+
)
1059+
.returns(() => Promise.resolve(true));
1060+
diagnosticsService
1061+
.setup((h) =>
1062+
h.validatePythonPath(
1063+
TypeMoq.It.isValue(debugAdapterPython),
1064+
PythonPathSource.launchJson,
1065+
TypeMoq.It.isAny()
1066+
)
1067+
)
1068+
// Invalid
1069+
.returns(() => Promise.resolve(false));
1070+
1071+
const debugConfig = await resolveDebugConfiguration(workspaceFolder, {
1072+
...launch,
1073+
redirectOutput: false,
1074+
python: pythonPath,
1075+
debugLauncherPython,
1076+
debugAdapterPython
1077+
});
1078+
1079+
diagnosticsService.verifyAll();
1080+
expect(debugConfig).to.be.equal(undefined, 'Not undefined');
1081+
});
1082+
1083+
test('Test validation of Python Path when launching debugger (with valid "python/debugAdapterPython/debugLauncherPython")', async () => {
1084+
const pythonPath = `PythonPath_${new Date().toString()}`;
1085+
const workspaceFolder = createMoqWorkspaceFolder(__dirname);
1086+
const pythonFile = 'xyz.py';
1087+
setupIoc(pythonPath);
1088+
setupActiveEditor(pythonFile, PYTHON_LANGUAGE);
1089+
1090+
diagnosticsService.reset();
1091+
diagnosticsService
1092+
.setup((h) =>
1093+
h.validatePythonPath(
1094+
TypeMoq.It.isValue(pythonPath),
1095+
PythonPathSource.launchJson,
1096+
TypeMoq.It.isAny()
1097+
)
9651098
)
9661099
.returns(() => Promise.resolve(true))
9671100
.verifiable(TypeMoq.Times.atLeastOnce());

0 commit comments

Comments
 (0)