Skip to content

Commit

Permalink
Use python debugger api (microsoft/vscode-python#23211)
Browse files Browse the repository at this point in the history
- Use Python Debugger API
- Use debugpy from Python Debugger
- Remove debugpy
  • Loading branch information
paulacamargo25 authored and seeM committed May 12, 2024
1 parent 1aac033 commit 4189286
Show file tree
Hide file tree
Showing 22 changed files with 82 additions and 161 deletions.
6 changes: 3 additions & 3 deletions extensions/positron-python/.github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ contact_links:
- name: 'Jupyter'
url: https://github.com/microsoft/vscode-jupyter/issues
about: 'For issues relating to the Jupyter extension (including the interactive window)'
- name: 'Debugpy'
url: https://github.com/microsoft/debugpy/issues
about: 'For issues relating to the debugpy debugger'
- name: 'Python Debugger'
url: https://github.com/microsoft/vscode-python-debugger/issues
about: 'For issues relating to the Python debugger'
- name: Help/Support
url: https://github.com/microsoft/vscode-python/discussions/categories/q-a
about: 'Having trouble with the extension? Need help getting something to work?'
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ runs:
run: python -m pip install wheel nox
shell: bash

- name: Install Python Extension dependencies (jedi, debugpy, etc.)
- name: Install Python Extension dependencies (jedi, etc.)
run: nox --session install_python_libs
shell: bash

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ runs:
- name: pip install system test requirements
run: |
python -m pip install --upgrade -r build/test-requirements.txt
python -m pip --disable-pip-version-check install -t ./python_files/lib/python --implementation py --no-deps --upgrade --pre debugpy
shell: bash

# Bits from the VSIX are reused by smokeTest.ts to speed things up.
Expand Down
3 changes: 1 addition & 2 deletions extensions/positron-python/.github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ jobs:

- name: Install other Python requirements
run: |
python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
Expand Down Expand Up @@ -192,7 +191,7 @@ jobs:
- name: Install build pre-requisite
run: python -m pip install wheel nox

- name: Install Python Extension dependencies (jedi, debugpy, etc.)
- name: Install Python Extension dependencies (jedi, etc.)
run: nox --session install_python_libs

- name: Install test requirements
Expand Down
8 changes: 1 addition & 7 deletions extensions/positron-python/.github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ jobs:

- name: Install other Python requirements
run: |
python -m pip --disable-pip-version-check install -t ./python_files/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
Expand Down Expand Up @@ -180,7 +179,7 @@ jobs:
- name: Install build pre-requisite
run: python -m pip install wheel nox

- name: Install Python Extension dependencies (jedi, debugpy, etc.)
- name: Install Python Extension dependencies (jedi, etc.)
run: nox --session install_python_libs

- name: Install test requirements
Expand Down Expand Up @@ -380,11 +379,6 @@ jobs:
- name: Install Jedi requirements
run: python scripts/vendor.py

- name: Install debugpy
run: |
# We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
python -m pip --disable-pip-version-check install -t ./python_files/lib/python --implementation py --no-deps --upgrade --pre debugpy
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extends:

- script: |
nox --session install_python_libs
displayName: Install debugpy, Jedi, get-pip, etc
displayName: Install Jedi, get-pip, etc
- script: |
python ./build/update_ext_version.py --for-publishing
Expand Down
2 changes: 1 addition & 1 deletion extensions/positron-python/build/azure-pipeline.stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ extends:

- script: |
nox --session install_python_libs
displayName: Install debugpy, Jedi, get-pip, etc
displayName: Install Jedi, get-pip, etc
- script: |
python ./build/update_ext_version.py --release --for-publishing
Expand Down
7 changes: 0 additions & 7 deletions extensions/positron-python/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ def install_python_libs(session: nox.Session):

session.install("packaging")

# Install debugger
session.run(
"python",
"./python_files/install_debugpy.py",
env={"PYTHONPATH": "./python_files/lib/temp"},
)

# Download get-pip script
session.run(
"python",
Expand Down
66 changes: 0 additions & 66 deletions extensions/positron-python/python_files/install_debugpy.py

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 3 additions & 2 deletions extensions/positron-python/src/client/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ILanguageServerOutputChannel } from './activation/types';
import { PythonExtension } from './api/types';
import { isTestExecution, PYTHON_LANGUAGE } from './common/constants';
import { IConfigurationService, Resource } from './common/types';
import { getDebugpyLauncherArgs, getDebugpyPackagePath } from './debugger/extension/adapter/remoteLaunchers';
import { getDebugpyLauncherArgs } from './debugger/extension/adapter/remoteLaunchers';
import { IInterpreterService } from './interpreter/contracts';
import { IServiceContainer, IServiceManager } from './ioc/types';
import { JupyterExtensionIntegration } from './jupyter/jupyterIntegration';
Expand All @@ -22,6 +22,7 @@ import { buildEnvironmentApi } from './environmentApi';
import { ApiForPylance } from './pylanceApi';
import { getTelemetryReporter } from './telemetry';
import { TensorboardExtensionIntegration } from './tensorBoard/tensorboardIntegration';
import { getDebugpyPath } from './debugger/pythonDebugger';

export function buildApi(
ready: Promise<void>,
Expand Down Expand Up @@ -122,7 +123,7 @@ export function buildApi(
});
},
async getDebuggerPackagePath(): Promise<string | undefined> {
return getDebugpyPackagePath();
return getDebugpyPath();
},
},
settings: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from 'vscode';
import { EXTENSION_ROOT_DIR } from '../../../constants';
import { IInterpreterService } from '../../../interpreter/contracts';
import { traceLog, traceVerbose } from '../../../logging';
import { traceError, traceLog, traceVerbose } from '../../../logging';
import { PythonEnvironment } from '../../../pythonEnvironments/info';
import { sendTelemetryEvent } from '../../../telemetry';
import { EventName } from '../../../telemetry/constants';
Expand All @@ -26,6 +26,7 @@ import { Common, Interpreters } from '../../../common/utils/localize';
import { IPersistentStateFactory } from '../../../common/types';
import { Commands } from '../../../common/constants';
import { ICommandManager } from '../../../common/application/types';
import { getDebugpyPath } from '../../pythonDebugger';

// persistent state names, exported to make use of in testing
export enum debugStateKeys {
Expand Down Expand Up @@ -90,15 +91,12 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac
traceLog(`DAP Server launched with command: ${executable} ${args.join(' ')}`);
return new DebugAdapterExecutable(executable, args);
}

const debuggerAdapterPathToUse = path.join(
EXTENSION_ROOT_DIR,
'python_files',
'lib',
'python',
'debugpy',
'adapter',
);
const debugpyPath = await getDebugpyPath();
if (!debugpyPath) {
traceError('Could not find debugpy path.');
throw new Error('Could not find debugpy path.');
}
const debuggerAdapterPathToUse = path.join(debugpyPath, 'adapter');

const args = command.concat([debuggerAdapterPathToUse, ...logArgs]);
traceLog(`DAP Server launched with command: ${executable} ${args.join(' ')}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@

'use strict';

import * as path from 'path';
import { EXTENSION_ROOT_DIR } from '../../../common/constants';
import '../../../common/extensions';

const pathToPythonLibDir = path.join(EXTENSION_ROOT_DIR, 'python_files', 'lib', 'python');
const pathToDebugger = path.join(pathToPythonLibDir, 'debugpy');
import { getDebugpyPath } from '../../pythonDebugger';

type RemoteDebugOptions = {
host: string;
port: number;
waitUntilDebuggerAttaches: boolean;
};

export function getDebugpyLauncherArgs(options: RemoteDebugOptions, debuggerPath: string = pathToDebugger) {
export async function getDebugpyLauncherArgs(options: RemoteDebugOptions, debuggerPath?: string) {
if (!debuggerPath) {
debuggerPath = await getDebugpyPath();
}

const waitArgs = options.waitUntilDebuggerAttaches ? ['--wait-for-client'] : [];
return [
debuggerPath.fileToCommandArgumentForPythonExt(),
Expand All @@ -25,7 +25,3 @@ export function getDebugpyLauncherArgs(options: RemoteDebugOptions, debuggerPath
...waitArgs,
];
}

export function getDebugpyPackagePath(): string {
return pathToDebugger;
}
30 changes: 30 additions & 0 deletions extensions/positron-python/src/client/debugger/pythonDebugger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { extensions } from 'vscode';

interface IPythonDebuggerExtensionApi {
debug: {
getDebuggerPackagePath(): Promise<string>;
};
}

async function activateExtension() {
const extension = extensions.getExtension('ms-python.debugpy');
if (extension) {
if (!extension.isActive) {
await extension.activate();
}
}
return extension;
}

async function getPythonDebuggerExtensionAPI(): Promise<IPythonDebuggerExtensionApi | undefined> {
const extension = await activateExtension();
return extension?.exports as IPythonDebuggerExtensionApi;
}

export async function getDebugpyPath(): Promise<string> {
const api = await getPythonDebuggerExtensionAPI();
return api?.debug.getDebuggerPackagePath() ?? '';
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { SemVer } from 'semver';
import { IContextKeyManager, IWorkspaceService } from '../common/application/types';
import { JUPYTER_EXTENSION_ID, PYLANCE_EXTENSION_ID } from '../common/constants';
import { GLOBAL_MEMENTO, IExtensions, IMemento, Resource } from '../common/types';
import { getDebugpyPackagePath } from '../debugger/extension/adapter/remoteLaunchers';
import { IEnvironmentActivationService } from '../interpreter/activation/types';
import { IInterpreterQuickPickItem, IInterpreterSelector } from '../interpreter/configuration/types';
import {
Expand All @@ -22,6 +21,7 @@ import {
} from '../interpreter/contracts';
import { PylanceApi } from '../activation/node/pylanceApi';
import { ExtensionContextKey } from '../common/application/contextKeys';
import { getDebugpyPath } from '../debugger/pythonDebugger';
import type { Environment } from '../api/types';

type PythonApiForJupyterExtension = {
Expand Down Expand Up @@ -110,7 +110,7 @@ export class JupyterExtensionIntegration {
this.interpreterSelector.getAllSuggestions(resource),
getKnownSuggestions: (resource: Resource): IInterpreterQuickPickItem[] =>
this.interpreterSelector.getSuggestions(resource),
getDebuggerPath: async () => dirname(getDebugpyPackagePath()),
getDebuggerPath: async () => dirname(await getDebugpyPath()),
getInterpreterPathSelectedForJupyterServer: () =>
this.globalState.get<string | undefined>('INTERPRETER_PATH_SELECTED_FOR_JUPYTER_SERVER'),
registerInterpreterStatusFilter: this.interpreterDisplay.registerVisibilityFilter.bind(
Expand Down
9 changes: 9 additions & 0 deletions extensions/positron-python/src/test/api.functional.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { assert, expect } from 'chai';
import * as path from 'path';
import * as sinon from 'sinon';
import { instance, mock, when } from 'ts-mockito';
import { buildApi } from '../client/api';
import { ConfigurationService } from '../client/common/configuration/service';
Expand All @@ -17,6 +18,7 @@ import { ServiceContainer } from '../client/ioc/container';
import { ServiceManager } from '../client/ioc/serviceManager';
import { IServiceContainer, IServiceManager } from '../client/ioc/types';
import { IDiscoveryAPI } from '../client/pythonEnvironments/base/locator';
import * as pythonDebugger from '../client/debugger/pythonDebugger';

suite('Extension API', () => {
const debuggerPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'lib', 'python', 'debugpy');
Expand All @@ -29,6 +31,7 @@ suite('Extension API', () => {
let interpreterService: IInterpreterService;
let discoverAPI: IDiscoveryAPI;
let environmentVariablesProvider: IEnvironmentVariablesProvider;
let getDebugpyPathStub: sinon.SinonStub;

setup(() => {
serviceContainer = mock(ServiceContainer);
Expand All @@ -47,6 +50,12 @@ suite('Extension API', () => {
);
when(serviceContainer.get<IInterpreterService>(IInterpreterService)).thenReturn(instance(interpreterService));
when(serviceContainer.get<IDisposableRegistry>(IDisposableRegistry)).thenReturn([]);
getDebugpyPathStub = sinon.stub(pythonDebugger, 'getDebugpyPath');
getDebugpyPathStub.resolves(debuggerPath);
});

teardown(() => {
sinon.restore();
});

test('Test debug launcher args (no-wait)', async () => {
Expand Down
Loading

0 comments on commit 4189286

Please sign in to comment.