Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/extension/debugger/adapter/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -76,7 +77,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.
Expand All @@ -85,6 +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 = fileToCommandArgumentForPythonExt(executable);
return new DebugAdapterExecutable(executable, args);
}

Expand Down
21 changes: 21 additions & 0 deletions src/test/unittest/adapter/factory.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' });
Expand Down
Loading