diff --git a/news/2 Fixes/12530.md b/news/2 Fixes/12530.md new file mode 100644 index 000000000000..1dae3afc16cc --- /dev/null +++ b/news/2 Fixes/12530.md @@ -0,0 +1 @@ +Make sure not to set ```__file__``` unless necessary as this can mess up some modules (like multiprocessing) \ No newline at end of file diff --git a/src/client/datascience/interactive-common/interactiveBase.ts b/src/client/datascience/interactive-common/interactiveBase.ts index 01b55deed731..2d50ea5fb0c8 100644 --- a/src/client/datascience/interactive-common/interactiveBase.ts +++ b/src/client/datascience/interactive-common/interactiveBase.ts @@ -123,7 +123,7 @@ export abstract class InteractiveBase extends WebviewPanelHost; + protected abstract setFileInKernel(file: string, cancelToken: CancellationToken | undefined): Promise; + protected async clearResult(id: string): Promise { await this.ensureConnectionAndNotebook(); if (this._notebook) { @@ -631,16 +633,9 @@ export abstract class InteractiveBase extends WebviewPanelHost { + // Native editor doesn't set this as the ipython file should be set for a notebook. + } + protected async close(): Promise { // Fire our event this.closedEvent.fire(this); diff --git a/src/client/datascience/interactive-window/interactiveWindow.ts b/src/client/datascience/interactive-window/interactiveWindow.ts index 21edb8235f5c..abed18fe2f40 100644 --- a/src/client/datascience/interactive-window/interactiveWindow.ts +++ b/src/client/datascience/interactive-window/interactiveWindow.ts @@ -2,7 +2,8 @@ // Licensed under the MIT License. import type { nbformat } from '@jupyterlab/coreutils'; import * as path from 'path'; -import { Event, EventEmitter, Memento, Uri, ViewColumn } from 'vscode'; +import * as uuid from 'uuid'; +import { CancellationToken, Event, EventEmitter, Memento, Uri, ViewColumn } from 'vscode'; import { IApplicationShell, ICommandManager, @@ -420,6 +421,38 @@ export class InteractiveWindow extends InteractiveBase implements IInteractiveWi protected async closeBecauseOfFailure(_exc: Error): Promise { this.dispose(); } + + protected async setFileInKernel(file: string, cancelToken: CancellationToken | undefined): Promise { + // If in perFile mode, set only once + if (this.mode === 'perFile' && !this.fileInKernel && this.notebook && file !== Identifiers.EmptyFileName) { + this.fileInKernel = file; + await this.notebook.execute( + `__file__ = '${file.replace(/\\/g, '\\\\')}'`, + file, + 0, + uuid(), + cancelToken, + true + ); + } else if ( + (!this.fileInKernel || !this.fs.areLocalPathsSame(this.fileInKernel, file)) && + this.mode !== 'perFile' && + this.notebook && + file !== Identifiers.EmptyFileName + ) { + // Otherwise we need to reset it every time + this.fileInKernel = file; + await this.notebook.execute( + `__file__ = '${file.replace(/\\/g, '\\\\')}'`, + file, + 0, + uuid(), + cancelToken, + true + ); + } + } + protected ensureConnectionAndNotebook(): Promise { // Keep track of users who have used interactive window in a worksapce folder. // To be used if/when changing workflows related to startup of jupyter. diff --git a/src/client/datascience/jupyter/jupyterSession.ts b/src/client/datascience/jupyter/jupyterSession.ts index 71d4309cdd88..ff8f705a2895 100644 --- a/src/client/datascience/jupyter/jupyterSession.ts +++ b/src/client/datascience/jupyter/jupyterSession.ts @@ -23,6 +23,7 @@ import { reportAction } from '../progress/decorator'; import { ReportableAction } from '../progress/types'; import { IJupyterConnection, ISessionWithSocket } from '../types'; import { JupyterInvalidKernelError } from './jupyterInvalidKernelError'; +import { JupyterWaitForIdleError } from './jupyterWaitForIdleError'; import { JupyterWebSockets } from './jupyterWebSocket'; import { getNameOfKernelConnection } from './kernels/helpers'; import { KernelConnectionMetadata } from './kernels/types'; @@ -90,9 +91,13 @@ export class JupyterSession extends BaseJupyterSession { // Make sure it is idle before we return await this.waitForIdleOnSession(newSession, timeoutMS); } catch (exc) { - traceError('Failed to change kernel', exc); - // Throw a new exception indicating we cannot change. - throw new JupyterInvalidKernelError(kernelConnection); + if (exc instanceof JupyterWaitForIdleError) { + throw exc; + } else { + traceError('Failed to change kernel', exc); + // Throw a new exception indicating we cannot change. + throw new JupyterInvalidKernelError(kernelConnection); + } } return newSession;