From 13c005c58665690bf18933baa86d816170c1623c Mon Sep 17 00:00:00 2001 From: Wasim Lorgat Date: Tue, 26 Dec 2023 14:27:07 +0000 Subject: [PATCH] Merged PR posit-dev/positron-python#290: update the active environment when starting a runtime Merge pull request #290 from posit-dev/sync-interpreter-changes update the active environment when starting a runtime -------------------- Commit message for posit-dev/positron-python@e5b33b8df1aad7826161d963c17876368eb12ab4: Merge remote-tracking branch 'origin/main' into sync-interpreter-changes -------------------- Commit message for posit-dev/positron-python@cf0cf6e9610234c45f358d37a0ee7c8ebbed86fc: always opt into the pythonTerminalEnvVarActivation experiment -------------------- Commit message for posit-dev/positron-python@5c8409d9d9312f366083a9152cebbec3146fe2a2: update the active environment when starting a runtime Addresses https://github.com/posit-dev/positron/issues/1491. Authored-by: Wasim Lorgat Signed-off-by: Wasim Lorgat --- .../src/client/common/experiments/helpers.ts | 13 +++++++++---- .../src/client/positron/extension.ts | 4 ++-- .../positron-python/src/client/positron/provider.ts | 11 ++++++++++- .../positron-python/src/client/positron/runtime.ts | 13 ++++++++++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/extensions/positron-python/src/client/common/experiments/helpers.ts b/extensions/positron-python/src/client/common/experiments/helpers.ts index 079342560db..a1b34ed5b0d 100644 --- a/extensions/positron-python/src/client/common/experiments/helpers.ts +++ b/extensions/positron-python/src/client/common/experiments/helpers.ts @@ -15,11 +15,16 @@ export function inTerminalEnvVarExperiment(experimentService: IExperimentService traceInfo('Not enabling terminal env var experiment in multiroot remote workspaces'); return false; } + // --- Start Positron --- + // Always opt into this experiment, as it is more reliable and a better UX than sending + // activation commands like `pyenv shell x.y.z` or `conda activate` to the terminal. + // It also provides a visual indicator in the terminal if the active interpreter changes. + // + // We leave the dead code path below to make merge conflicts easier to resolve. + return true; + // --- End Positron --- if (!experimentService.inExperimentSync(TerminalEnvVarActivation.experiment)) { return false; } - // --- Begin Positron --- - // return true; - return false; - // --- End Positron --- + return true; } diff --git a/extensions/positron-python/src/client/positron/extension.ts b/extensions/positron-python/src/client/positron/extension.ts index f59a7a6acb0..f2999e4d9f4 100644 --- a/extensions/positron-python/src/client/positron/extension.ts +++ b/extensions/positron-python/src/client/positron/extension.ts @@ -25,7 +25,7 @@ export async function activatePositron( traceInfo('activatePositron: registering python runtime provider'); positron.runtime.registerLanguageRuntimeDiscoverer( 'python', - pythonRuntimeDiscoverer(serviceContainer, runtimes, activatedPromise), + pythonRuntimeDiscoverer(serviceContainer, runtimes, activatedPromise, pythonApi), ); // Wait for all extension components to be activated before registering event listeners @@ -62,7 +62,7 @@ export async function activatePositron( if (interpreter) { // Set recommendedForWorkspace to false, since we change the active runtime // in the onDidChangeActiveEnvironmentPath listener. - const runtime = await createPythonRuntime(interpreter, serviceContainer, false); + const runtime = await createPythonRuntime(interpreter, serviceContainer, false, pythonApi); const runtimeMetadata = runtime.metadata; disposables.push(positron.runtime.registerLanguageRuntime(runtime)); runtimes.set(interpreterPath, runtimeMetadata); diff --git a/extensions/positron-python/src/client/positron/provider.ts b/extensions/positron-python/src/client/positron/provider.ts index f2f579e4528..8e1a3852db1 100644 --- a/extensions/positron-python/src/client/positron/provider.ts +++ b/extensions/positron-python/src/client/positron/provider.ts @@ -12,6 +12,7 @@ import * as positron from 'positron'; import * as semver from 'semver'; import * as vscode from 'vscode'; +import { PythonExtension } from '../api/types'; import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../common/constants'; import { IConfigurationService, IInstaller } from '../common/types'; import { IServiceContainer } from '../ioc/types'; @@ -37,6 +38,7 @@ export async function* pythonRuntimeDiscoverer( serviceContainer: IServiceContainer, runtimes: Map, activatedPromise: Promise, + pythonApi: PythonExtension, ): AsyncGenerator { try { traceInfo('pythonRuntimeProvider: Starting Python runtime provider'); @@ -80,7 +82,12 @@ export async function* pythonRuntimeDiscoverer( for (const interpreter of interpreters) { // Only register runtimes for supported versions if (isVersionSupported(interpreter?.version, '3.8.0')) { - const runtime = await createPythonRuntime(interpreter, serviceContainer, recommendedForWorkspace); + const runtime = await createPythonRuntime( + interpreter, + serviceContainer, + recommendedForWorkspace, + pythonApi, + ); // Ensure we only recommend one runtime for the workspace. recommendedForWorkspace = false; @@ -103,6 +110,7 @@ export async function createPythonRuntime( interpreter: PythonEnvironment, serviceContainer: IServiceContainer, recommendedForWorkspace: boolean, + pythonApi: PythonExtension, ): Promise { traceInfo('createPythonRuntime: getting service instances'); const configService = serviceContainer.get(IConfigurationService); @@ -245,6 +253,7 @@ export async function createPythonRuntime( languageClientOptions, interpreter, installer, + pythonApi, extra, ); } diff --git a/extensions/positron-python/src/client/positron/runtime.ts b/extensions/positron-python/src/client/positron/runtime.ts index 5b46c72a1a0..25ffa40a285 100644 --- a/extensions/positron-python/src/client/positron/runtime.ts +++ b/extensions/positron-python/src/client/positron/runtime.ts @@ -11,6 +11,7 @@ import * as vscode from 'vscode'; import { cloneDeep } from 'lodash'; import PQueue from 'p-queue'; import { LanguageClientOptions } from 'vscode-languageclient/node'; +import { PythonExtension } from '../api/types'; import { InstallOptions } from '../common/installer/types'; import { IInstaller, InstallerResponse, Product } from '../common/types'; import { IServiceContainer } from '../ioc/types'; @@ -59,6 +60,7 @@ export class PythonRuntime implements positron.LanguageRuntime, vscode.Disposabl readonly languageClientOptions: LanguageClientOptions, private readonly interpreter: PythonEnvironment, private readonly installer: IInstaller, + private readonly pythonApi: PythonExtension, readonly extra?: JupyterKernelExtra, readonly notebook?: vscode.NotebookDocument, ) { @@ -194,14 +196,20 @@ export class PythonRuntime implements positron.LanguageRuntime, vscode.Disposabl if (!this._kernel) { this._kernel = await this.createKernel(); } + + // Ensure that the ipykernel module is installed for the interpreter. await this._installIpykernel(); + // Update the active environment in the Python extension. + this.pythonApi.environments.updateActiveEnvironmentPath(this.interpreter.path); + // Register for console width changes, if we haven't already if (!this._consoleWidthDisposable) { this._consoleWidthDisposable = positron.window.onDidChangeConsoleWidth((newWidth) => { this.onConsoleWidthChange(newWidth); }); } + return this._kernel.start(); } @@ -223,9 +231,7 @@ export class PythonRuntime implements positron.LanguageRuntime, vscode.Disposabl // Log the error if we can't set the console width; this is not // fatal, so we don't rethrow the error const runtimeError = err as positron.RuntimeMethodError; - this._kernel.emitJupyterLog( - `Error setting console width: ${runtimeError.message} (${runtimeError.code})`, - ); + this._kernel.emitJupyterLog(`Error setting console width: ${runtimeError.message} (${runtimeError.code})`); } } @@ -345,6 +351,7 @@ export class PythonRuntime implements positron.LanguageRuntime, vscode.Disposabl cloneDeep(this.languageClientOptions), cloneDeep(this.interpreter), this.installer, + this.pythonApi, createJupyterKernelExtra(), notebook, );