From 5955540fbe34920685ddfdb35ebc3938710e639b Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Wed, 6 Nov 2024 15:05:59 -0800 Subject: [PATCH 1/6] support interpreter paths with spaces --- src/extension/debugger/adapter/factory.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/extension/debugger/adapter/factory.ts b/src/extension/debugger/adapter/factory.ts index 16bb50e0..53c3f30f 100644 --- a/src/extension/debugger/adapter/factory.ts +++ b/src/extension/debugger/adapter/factory.ts @@ -76,7 +76,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac sendTelemetryEvent(EventName.DEBUGGER_ATTACH_TO_LOCAL_PROCESS); } - const executable = command.shift() ?? 'python'; + let executable = command.shift() ?? 'python'; // "logToFile" is not handled directly by the adapter - instead, we need to pass // the corresponding CLI switch when spawning it. @@ -85,6 +85,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac if (configuration.debugAdapterPath !== undefined) { const args = command.concat([configuration.debugAdapterPath, ...logArgs]); traceLog(`DAP Server launched with command: ${executable} ${args.join(' ')}`); + executable = `"${executable}"`; // surround executable with quotes to handle spaces return new DebugAdapterExecutable(executable, args); } From e6241207a789afc69e987268886124ce2bc4f4ec Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Mon, 11 Nov 2024 15:25:20 -0800 Subject: [PATCH 2/6] use fileToCommandArgumentForPythonExt and add test --- src/extension/debugger/adapter/factory.ts | 3 ++- .../unittest/adapter/factory.unit.test.ts | 23 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/extension/debugger/adapter/factory.ts b/src/extension/debugger/adapter/factory.ts index 53c3f30f..114e89c1 100644 --- a/src/extension/debugger/adapter/factory.ts +++ b/src/extension/debugger/adapter/factory.ts @@ -25,6 +25,7 @@ import { Commands, EXTENSION_ROOT_DIR } from '../../common/constants'; import { Common, DebugConfigStrings, Interpreters } from '../../common/utils/localize'; import { IPersistentStateFactory } from '../../common/types'; import { ResolvedEnvironment } from '@vscode/python-extension'; +import { fileToCommandArgumentForPythonExt } from '../../common/stringUtils'; // persistent state names, exported to make use of in testing export enum debugStateKeys { @@ -85,7 +86,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac if (configuration.debugAdapterPath !== undefined) { const args = command.concat([configuration.debugAdapterPath, ...logArgs]); traceLog(`DAP Server launched with command: ${executable} ${args.join(' ')}`); - executable = `"${executable}"`; // surround executable with quotes to handle spaces + executable = fileToCommandArgumentForPythonExt(executable); return new DebugAdapterExecutable(executable, args); } diff --git a/src/test/unittest/adapter/factory.unit.test.ts b/src/test/unittest/adapter/factory.unit.test.ts index 78a5e7a6..847d5bdb 100644 --- a/src/test/unittest/adapter/factory.unit.test.ts +++ b/src/test/unittest/adapter/factory.unit.test.ts @@ -41,7 +41,7 @@ suite('Debugging - Adapter Factory', () => { const nodeExecutable = undefined; const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'bundled', 'libs', 'debugpy', 'adapter'); - const pythonPath = path.join('path', 'to', 'python', 'interpreter'); + const pythonPath = path.join('path', 'to', 'pythonA', 'interpreter'); const interpreter = { architecture: Architecture.Unknown, path: pythonPath, @@ -291,6 +291,27 @@ suite('Debugging - Adapter Factory', () => { assert.deepStrictEqual(descriptor, debugExecutable); }); + test('Add quotes to interpreter path with spaces', async () => { + const customAdapterPath = 'custom/debug/adapter/customAdapterPath'; + const session = createSession({ debugAdapterPath: customAdapterPath }); + const interpreterPathSpaces = '/path/to/python interpreter with spaces'; + const interpreterPathSpacesQuoted = `"${interpreterPathSpaces}"`; + const debugExecutable = new DebugAdapterExecutable(interpreterPathSpacesQuoted, [customAdapterPath]); + + getInterpreterDetailsStub.resolves({ path: [interpreterPathSpaces] }); + const interpreterSpacePath = { + architecture: Architecture.Unknown, + path: interpreterPathSpaces, + sysPrefix: '', + sysVersion: '', + envType: 'Unknow', + version: new SemVer('3.7.4-test'), + }; + resolveEnvironmentStub.withArgs(interpreterPathSpaces).resolves(interpreterSpacePath); + const descriptor = await factory.createDebugAdapterDescriptor(session, nodeExecutable); + + assert.deepStrictEqual(descriptor, debugExecutable); + }); test('Use "debugAdapterPython" when specified', async () => { const session = createSession({ debugAdapterPython: '/bin/custompy' }); From 51f0770a54f37ff8397f896526415167244b34c4 Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Mon, 11 Nov 2024 15:27:41 -0800 Subject: [PATCH 3/6] fix unnecessary edit --- src/test/unittest/adapter/factory.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/unittest/adapter/factory.unit.test.ts b/src/test/unittest/adapter/factory.unit.test.ts index 847d5bdb..81e7fa7a 100644 --- a/src/test/unittest/adapter/factory.unit.test.ts +++ b/src/test/unittest/adapter/factory.unit.test.ts @@ -41,7 +41,7 @@ suite('Debugging - Adapter Factory', () => { const nodeExecutable = undefined; const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'bundled', 'libs', 'debugpy', 'adapter'); - const pythonPath = path.join('path', 'to', 'pythonA', 'interpreter'); + const pythonPath = path.join('path', 'to', 'python', 'interpreter'); const interpreter = { architecture: Architecture.Unknown, path: pythonPath, From fc9dc6ccfb52bf81e2154843ea2ba5d3335b6d17 Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Tue, 12 Nov 2024 09:11:44 -0800 Subject: [PATCH 4/6] switch to use path.join --- src/test/unittest/adapter/factory.unit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/unittest/adapter/factory.unit.test.ts b/src/test/unittest/adapter/factory.unit.test.ts index 81e7fa7a..62adf5cd 100644 --- a/src/test/unittest/adapter/factory.unit.test.ts +++ b/src/test/unittest/adapter/factory.unit.test.ts @@ -292,9 +292,9 @@ suite('Debugging - Adapter Factory', () => { assert.deepStrictEqual(descriptor, debugExecutable); }); test('Add quotes to interpreter path with spaces', async () => { - const customAdapterPath = 'custom/debug/adapter/customAdapterPath'; + const customAdapterPath = path.join('custom', 'debug', 'adapter', 'customAdapterPath'); const session = createSession({ debugAdapterPath: customAdapterPath }); - const interpreterPathSpaces = '/path/to/python interpreter with spaces'; + const interpreterPathSpaces = path.join('/path', 'to', 'python interpreter with spaces'); const interpreterPathSpacesQuoted = `"${interpreterPathSpaces}"`; const debugExecutable = new DebugAdapterExecutable(interpreterPathSpacesQuoted, [customAdapterPath]); From d3f94b4639634aed0750bd6411a33e77dbe65214 Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Tue, 12 Nov 2024 09:12:03 -0800 Subject: [PATCH 5/6] error fix --- src/test/unittest/adapter/factory.unit.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/unittest/adapter/factory.unit.test.ts b/src/test/unittest/adapter/factory.unit.test.ts index 62adf5cd..64b0aead 100644 --- a/src/test/unittest/adapter/factory.unit.test.ts +++ b/src/test/unittest/adapter/factory.unit.test.ts @@ -294,7 +294,7 @@ suite('Debugging - Adapter Factory', () => { test('Add quotes to interpreter path with spaces', async () => { const customAdapterPath = path.join('custom', 'debug', 'adapter', 'customAdapterPath'); const session = createSession({ debugAdapterPath: customAdapterPath }); - const interpreterPathSpaces = path.join('/path', 'to', 'python interpreter with spaces'); + const interpreterPathSpaces = path.join('path', 'to', 'python interpreter with spaces'); const interpreterPathSpacesQuoted = `"${interpreterPathSpaces}"`; const debugExecutable = new DebugAdapterExecutable(interpreterPathSpacesQuoted, [customAdapterPath]); From 07026d3f4cbc52e62932960303b521b5ce4f429f Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Tue, 12 Nov 2024 13:29:53 -0800 Subject: [PATCH 6/6] fix path to match desired --- src/test/unittest/adapter/factory.unit.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/unittest/adapter/factory.unit.test.ts b/src/test/unittest/adapter/factory.unit.test.ts index 64b0aead..86342d2c 100644 --- a/src/test/unittest/adapter/factory.unit.test.ts +++ b/src/test/unittest/adapter/factory.unit.test.ts @@ -41,7 +41,7 @@ suite('Debugging - Adapter Factory', () => { const nodeExecutable = undefined; const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'bundled', 'libs', 'debugpy', 'adapter'); - const pythonPath = path.join('path', 'to', 'python', 'interpreter'); + const pythonPath = 'path/to/python/interpreter'; const interpreter = { architecture: Architecture.Unknown, path: pythonPath, @@ -292,9 +292,9 @@ suite('Debugging - Adapter Factory', () => { assert.deepStrictEqual(descriptor, debugExecutable); }); test('Add quotes to interpreter path with spaces', async () => { - const customAdapterPath = path.join('custom', 'debug', 'adapter', 'customAdapterPath'); + const customAdapterPath = 'custom/debug/adapter/customAdapterPath'; const session = createSession({ debugAdapterPath: customAdapterPath }); - const interpreterPathSpaces = path.join('path', 'to', 'python interpreter with spaces'); + const interpreterPathSpaces = 'path/to/python interpreter with spaces'; const interpreterPathSpacesQuoted = `"${interpreterPathSpaces}"`; const debugExecutable = new DebugAdapterExecutable(interpreterPathSpacesQuoted, [customAdapterPath]);