Skip to content

Commit 0f9f79c

Browse files
committed
Support debugging python 3.6 (microsoft#19559)
1 parent 586d18f commit 0f9f79c

File tree

11 files changed

+93
-18
lines changed

11 files changed

+93
-18
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import os
5+
import sys
6+
7+
PY36 = sys.version_info < (3, 7)
8+
9+
10+
if __name__ == "__main__":
11+
# Launch diffrent version of debugpy according to python version.
12+
# Change `sys.path` to find debugpy package.
13+
if "debugpy" not in sys.modules:
14+
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15+
python_dir = "python" if not PY36 else "python36"
16+
sys.path[0] = os.path.join(root, "lib", python_dir)
17+
18+
import debugpy # noqa
19+
20+
del sys.path[0]
21+
22+
from debugpy.server import cli
23+
24+
cli.main()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import os
5+
import sys
6+
7+
PY36 = sys.version_info < (3, 7)
8+
9+
10+
if __name__ == "__main__":
11+
# Launch diffrent version of debugpy according to python version.
12+
# Change `sys.path` to find debugpy package.
13+
if "debugpy" not in sys.modules:
14+
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
15+
python_dir = "python" if not PY36 else "python36"
16+
sys.path[0] = os.path.join(root, "lib", python_dir)
17+
18+
import debugpy # noqa
19+
20+
del sys.path[0]
21+
22+
from debugpy.adapter.__main__ import main, _parse_argv
23+
24+
main(_parse_argv(sys.argv))
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import os
5+
import sys
6+
7+
PY36 = sys.version_info < (3, 7)
8+
9+
10+
if __name__ == "__main__":
11+
# Launch diffrent version of debugpy according to python version.
12+
# Change `sys.path` to find debugpy package.
13+
if "debugpy" not in sys.modules:
14+
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
15+
python_dir = "python" if not PY36 else "python36"
16+
sys.path[0] = os.path.join(root, "lib", python_dir)
17+
18+
import debugpy # noqa
19+
20+
del sys.path[0]
21+
22+
from debugpy.launcher.__main__ import main
23+
24+
main()

pythonFiles/install_debugpy.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
DEBUGGER_PYTHON_ABI_VERSIONS = ("cp310",)
1616
DEBUGGER_VERSION = "1.6.7" # can also be "latest"
1717

18+
PY36_DEBUGGER_DEST = os.path.join(EXTENSION_ROOT, "pythonFiles", "lib", "python36")
19+
PY36_DEBUGGER_PYTHON_ABI_VERSIONS = ("cp39",)
20+
PY36_DEBUGGER_VERSION = "1.5.1" # the last version supporting Python 3.6 and below
21+
1822

1923
def _contains(s, parts=()):
2024
return any(p in s for p in parts)
@@ -28,11 +32,11 @@ def _get_package_data():
2832
return json.loads(response.read())
2933

3034

31-
def _get_debugger_wheel_urls(data, version):
35+
def _get_debugger_wheel_urls(data, version, python_abi_versions):
3236
return list(
3337
r["url"]
3438
for r in data["releases"][version]
35-
if _contains(r["url"], DEBUGGER_PYTHON_ABI_VERSIONS)
39+
if _contains(r["url"], python_abi_versions)
3640
)
3741

3842

@@ -58,9 +62,12 @@ def main(root):
5862
else:
5963
use_version = DEBUGGER_VERSION
6064

61-
for url in _get_debugger_wheel_urls(data, use_version):
65+
for url in _get_debugger_wheel_urls(data, use_version, DEBUGGER_PYTHON_ABI_VERSIONS):
6266
_download_and_extract(root, url, use_version)
6367

68+
for url in _get_debugger_wheel_urls(data, use_version, PY36_DEBUGGER_PYTHON_ABI_VERSIONS):
69+
_download_and_extract(PY36_DEBUGGER_DEST, url, PY36_DEBUGGER_VERSION)
70+
6471

6572
if __name__ == "__main__":
6673
main(DEBUGGER_DEST)

src/client/apiTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface IExtensionApi {
2323
/**
2424
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
2525
* Users can append another array of strings of what they want to execute along with relevant arguments to Python.
26-
* E.g `['/Users/..../pythonVSCode/pythonFiles/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
26+
* E.g `['/Users/..../pythonVSCode/pythonFiles/dispatch_debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
2727
* @param {string} host
2828
* @param {number} port
2929
* @param {boolean} [waitUntilDebuggerAttaches=true]

src/client/debugger/extension/adapter/factory.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac
9494
const debuggerAdapterPathToUse = path.join(
9595
EXTENSION_ROOT_DIR,
9696
'pythonFiles',
97-
'lib',
98-
'python',
99-
'debugpy',
97+
'dispatch_debugpy',
10098
'adapter',
10199
);
102100

@@ -163,7 +161,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac
163161
}
164162
const prompts = [Interpreters.changePythonInterpreter, Common.doNotShowAgain];
165163
const selection = await showErrorMessage(
166-
l10n.t('The debugger in the python extension no longer supports python versions minor than 3.7.'),
164+
l10n.t('The debugger in the python extension no longer supports python versions minor than 2.7.'),
167165
{ modal: true },
168166
...prompts,
169167
);
@@ -183,7 +181,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac
183181

184182
private async getExecutableCommand(interpreter: PythonEnvironment | undefined): Promise<string[]> {
185183
if (interpreter) {
186-
if ((interpreter.version?.major ?? 0) < 3 || (interpreter.version?.minor ?? 0) <= 6) {
184+
if ((interpreter.version?.major ?? 0) < 3) {
187185
this.showDeprecatedPythonMessage();
188186
}
189187
return interpreter.path.length > 0 ? [interpreter.path] : [];

src/client/debugger/extension/adapter/remoteLaunchers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import * as path from 'path';
77
import { EXTENSION_ROOT_DIR } from '../../../common/constants';
88
import '../../../common/extensions';
99

10-
const pathToPythonLibDir = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python');
11-
const pathToDebugger = path.join(pathToPythonLibDir, 'debugpy');
10+
const pathToDebugger = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'dispatch_debugpy');
1211

1312
type RemoteDebugOptions = {
1413
host: string;

src/client/jupyter/jupyterIntegration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ type PythonApiForJupyterExtension = {
124124
resource?: InterpreterUri,
125125
): Promise<ProductInstallStatus>;
126126
/**
127-
* Returns path to where `debugpy` is. In python extension this is `/pythonFiles/lib/python`.
127+
* Returns path to where `debugpy` is. In python extension this is `/pythonFiles/dispatch_debugpy`.
128128
*/
129129
getDebuggerPath(): Promise<string>;
130130
/**

src/test/api.functional.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { IServiceContainer, IServiceManager } from '../client/ioc/types';
1919
import { IDiscoveryAPI } from '../client/pythonEnvironments/base/locator';
2020

2121
suite('Extension API', () => {
22-
const debuggerPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python', 'debugpy');
22+
const debuggerPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'dispatch_debugpy');
2323
const debuggerHost = 'somehost';
2424
const debuggerPort = 12345;
2525

src/test/debugger/extension/adapter/factory.unit.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ suite('Debugging - Adapter Factory', () => {
3939
let commandManager: ICommandManager;
4040

4141
const nodeExecutable = undefined;
42-
const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python', 'debugpy', 'adapter');
42+
const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'dispatch_debugpy', 'adapter');
4343
const pythonPath = path.join('path', 'to', 'python', 'interpreter');
4444
const interpreter = {
4545
architecture: Architecture.Unknown,
@@ -157,7 +157,7 @@ suite('Debugging - Adapter Factory', () => {
157157
sinon.assert.calledOnce(showErrorMessageStub);
158158
});
159159

160-
test('Display a message if python version is less than 3.7', async () => {
160+
test('Display a message if python version is less than 3', async () => {
161161
when(interpreterService.getInterpreters(anything())).thenReturn([]);
162162
const session = createSession({});
163163
const deprecatedInterpreter = {
@@ -166,7 +166,7 @@ suite('Debugging - Adapter Factory', () => {
166166
sysPrefix: '',
167167
sysVersion: '',
168168
envType: EnvironmentType.Unknown,
169-
version: new SemVer('3.6.12-test'),
169+
version: new SemVer('2.7.12-test'),
170170
};
171171
when(state.value).thenReturn(false);
172172
when(interpreterService.getActiveInterpreter(anything())).thenResolve(deprecatedInterpreter);

src/test/debugger/extension/adapter/remoteLaunchers.unit.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ suite('External debugpy Debugger Launcher', () => {
5252
});
5353

5454
suite('Path To Debugger Package', () => {
55-
const pathToPythonLibDir = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python');
5655
test('Path to debugpy debugger package', () => {
5756
const actual = launchers.getDebugpyPackagePath();
58-
const expected = path.join(pathToPythonLibDir, 'debugpy');
57+
const expected = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'dispatch_debugpy');
5958
expect(actual).to.be.deep.equal(expected);
6059
});
6160
});

0 commit comments

Comments
 (0)