Skip to content

Commit

Permalink
Initialize env variable to resolve a number of debugger issues (#11058)
Browse files Browse the repository at this point in the history
* Initialize env var for debugpy to work properly

* Add news entry

* oops
  • Loading branch information
DonJayamanne authored Aug 18, 2022
1 parent 4b50f31 commit aab4afe
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 19 deletions.
2 changes: 2 additions & 0 deletions news/2 Fixes/11033.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Initialize the environment variable `PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING` for the `Python` debugger when debugging `Interactive Window` and `Notebooks`.
This also addresses the following issues [10600](https://github.com/microsoft/vscode-jupyter/issues/10600), [8146](https://github.com/microsoft/vscode-jupyter/issues/8146), [10106](https://github.com/microsoft/vscode-jupyter/issues/10106)
5 changes: 5 additions & 0 deletions src/interactive-window/debugger/startupCodeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { inject, injectable } from 'inversify';
import { Uri } from 'vscode';
import { isPythonKernelConnection } from '../../kernels/helpers';
import { IKernel, isLocalConnection, IStartupCodeProvider, StartupCodePriority } from '../../kernels/types';
import { InteractiveWindowView } from '../../platform/common/constants';
import { IFileSystem } from '../../platform/common/platform/types';
Expand All @@ -21,6 +22,10 @@ export class InteractiveWindowDebuggingStartupCodeProvider implements IStartupCo
) {}

async getCode(kernel: IKernel): Promise<string[]> {
if (!isPythonKernelConnection(kernel.kernelConnectionMetadata)) {
return [];
}

if (!this.isWebExtension) {
const useNewDebugger = this.configService.getSettings(undefined).forceIPyKernelDebugger === true;
if (useNewDebugger) {
Expand Down
24 changes: 24 additions & 0 deletions src/kernels/debuggerStartupCodeProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { injectable } from 'inversify';
import { isPythonKernelConnection } from './helpers';
import { IKernel, IStartupCodeProvider, StartupCodePriority } from './types';

@injectable()
export class DebugStartupCodeProvider implements IStartupCodeProvider {
public priority = StartupCodePriority.Base;

async getCode(kernel: IKernel): Promise<string[]> {
if (!isPythonKernelConnection(kernel.kernelConnectionMetadata)) {
return [];
}

return [
'import os as __VSCODE_os',
// Required to get pydevd to work properly in Python kernel, more info here https://github.com/microsoft/vscode-jupyter/issues/11033
'__VSCODE_os.environ["PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING"] = "1"',
'del __VSCODE_os'
];
}
}
36 changes: 18 additions & 18 deletions src/kernels/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,16 +458,14 @@ abstract class BaseKernel<TKernelExecution extends BaseKernelExecution> implemen
// Restart sessions and retries might make this hard to do correctly otherwise.
session.registerCommTarget(Identifiers.DefaultCommTarget, noop);

// If this is a live kernel, we shouldn't be changing anything by running startup code.
// Gather all of the startup code at one time and execute as one cell
const startupCode = await this.gatherInternalStartupCode();
await this.executeSilently(session, startupCode, {
traceErrors: true,
traceErrorsMessage: 'Error executing jupyter extension internal startup code',
telemetryName: Telemetry.KernelStartupCodeFailure
});
if (this.kernelConnectionMetadata.kind !== 'connectToLiveRemoteKernel') {
// Gather all of the startup code at one time and execute as one cell
const startupCode = await this.gatherInternalStartupCode();
await this.executeSilently(session, startupCode, {
traceErrors: true,
traceErrorsMessage: 'Error executing jupyter extension internal startup code',
telemetryName: Telemetry.KernelStartupCodeFailure
});

// Run user specified startup commands
await this.executeSilently(session, this.getUserStartupCommands(), {
traceErrors: true,
Expand Down Expand Up @@ -522,16 +520,18 @@ abstract class BaseKernel<TKernelExecution extends BaseKernelExecution> implemen
// Gather all of the startup code into a giant string array so we
// can execute it all at once.
const result: string[] = [];
if (isPythonKernelConnection(this.kernelConnectionMetadata)) {
const dirs = await Promise.all(
this.startupCodeProviders
.sort((a, b) => b.priority - a.priority)
.map((provider) => provider.getCode(this))
);
for (let dir of dirs) {
result.push(...dir);
}
const startupCode = await Promise.all(
this.startupCodeProviders.sort((a, b) => b.priority - a.priority).map((provider) => provider.getCode(this))
);
for (let code of startupCode) {
result.push(...code);
}

// If this is a live kernel, we shouldn't be changing anything by running startup code.
if (
isPythonKernelConnection(this.kernelConnectionMetadata) &&
this.kernelConnectionMetadata.kind !== 'connectToLiveRemoteKernel'
) {
// Set the ipynb file
const file = getFilePath(this.resourceUri);
if (file) {
Expand Down
7 changes: 7 additions & 0 deletions src/kernels/kernelStartupCodeProvider.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export class KernelStartupCodeProvider implements IStartupCodeProvider {
) {}

async getCode(kernel: IKernel): Promise<string[]> {
// If this is a live kernel, we shouldn't be changing anything by running startup code.
if (
!isPythonKernelConnection(kernel.kernelConnectionMetadata) &&
kernel.kernelConnectionMetadata.kind !== 'connectToLiveRemoteKernel'
) {
return [];
}
if (
!(
isLocalConnection(kernel.kernelConnectionMetadata) &&
Expand Down
2 changes: 2 additions & 0 deletions src/kernels/serviceRegistry.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { KernelAutoReConnectFailedMonitor } from './kernelAutoReConnectFailedMon
import { KernelAutoReconnectMonitor } from './kernelAutoReConnectMonitor';
import { PythonKernelInterruptDaemon } from './raw/finder/pythonKernelInterruptDaemon.node';
import { LocalKernelFinder } from './raw/finder/localKernelFinder.node';
import { DebugStartupCodeProvider } from './debuggerStartupCodeProvider';

export function registerTypes(serviceManager: IServiceManager, isDevMode: boolean) {
serviceManager.addSingleton<IExtensionSingleActivationService>(IExtensionSingleActivationService, Activation);
Expand Down Expand Up @@ -134,5 +135,6 @@ export function registerTypes(serviceManager: IServiceManager, isDevMode: boolea
serviceManager.addSingleton<CellOutputDisplayIdTracker>(CellOutputDisplayIdTracker, CellOutputDisplayIdTracker);

serviceManager.addSingleton<IStartupCodeProvider>(IStartupCodeProvider, KernelStartupCodeProvider);
serviceManager.addSingleton<IStartupCodeProvider>(IStartupCodeProvider, DebugStartupCodeProvider);
serviceManager.addSingleton<PythonKernelInterruptDaemon>(PythonKernelInterruptDaemon, PythonKernelInterruptDaemon);
}
4 changes: 3 additions & 1 deletion src/kernels/serviceRegistry.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IRawNotebookSupportedService } from './raw/types';
import { KernelCrashMonitor } from './kernelCrashMonitor';
import { registerTypes as registerJupyterTypes } from './jupyter/serviceRegistry.web';
import { injectable } from 'inversify';
import { IKernelFinder, IKernelProvider, IThirdPartyKernelProvider } from './types';
import { IKernelFinder, IKernelProvider, IStartupCodeProvider, IThirdPartyKernelProvider } from './types';
import { KernelProvider, ThirdPartyKernelProvider } from './kernelProvider.web';
import { KernelFinder } from './kernelFinder';
import { PreferredRemoteKernelIdProvider } from './jupyter/preferredRemoteKernelIdProvider';
Expand All @@ -25,6 +25,7 @@ import { PythonVariablesRequester } from './variables/pythonVariableRequester';
import { CellOutputDisplayIdTracker } from './execution/cellDisplayIdTracker';
import { KernelAutoReConnectFailedMonitor } from './kernelAutoReConnectFailedMonitor';
import { KernelAutoReconnectMonitor } from './kernelAutoReConnectMonitor';
import { DebugStartupCodeProvider } from './debuggerStartupCodeProvider';

@injectable()
class RawNotebookSupportedService implements IRawNotebookSupportedService {
Expand Down Expand Up @@ -82,4 +83,5 @@ export function registerTypes(serviceManager: IServiceManager, isDevMode: boolea
registerJupyterTypes(serviceManager, isDevMode);

serviceManager.addSingleton<CellOutputDisplayIdTracker>(CellOutputDisplayIdTracker, CellOutputDisplayIdTracker);
serviceManager.addSingleton<IStartupCodeProvider>(IStartupCodeProvider, DebugStartupCodeProvider);
}

0 comments on commit aab4afe

Please sign in to comment.