From fcb40b088f42cafa87b63ac589b7e1a777b84478 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Mon, 21 Sep 2020 09:50:25 -0700 Subject: [PATCH 1/2] Find interpreter based on hash in kernelspec of nb metadata (#13856) --- .../jupyter/kernels/kernelSelector.ts | 26 ++++++++++++++++ .../datascience/notebookStorage/baseModel.ts | 30 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/client/datascience/jupyter/kernels/kernelSelector.ts b/src/client/datascience/jupyter/kernels/kernelSelector.ts index 4e9a172ce817..93ff0a676d8b 100644 --- a/src/client/datascience/jupyter/kernels/kernelSelector.ts +++ b/src/client/datascience/jupyter/kernels/kernelSelector.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import type { nbformat } from '@jupyterlab/coreutils'; import type { Kernel } from '@jupyterlab/services'; +import { sha256 } from 'hash.js'; import { inject, injectable } from 'inversify'; // tslint:disable-next-line: no-require-imports import cloneDeep = require('lodash/cloneDeep'); @@ -18,6 +19,7 @@ import { PythonEnvironment } from '../../../pythonEnvironments/info'; import { IEventNamePropertyMapping, sendTelemetryEvent } from '../../../telemetry'; import { Commands, KnownNotebookLanguages, Settings, Telemetry } from '../../constants'; import { IKernelFinder } from '../../kernel-launcher/types'; +import { getInterpreterInfoStoredInMetadata } from '../../notebookStorage/baseModel'; import { reportAction } from '../../progress/decorator'; import { ReportableAction } from '../../progress/types'; import { @@ -486,6 +488,17 @@ export class KernelSelector implements IKernelSelectionUsage { } } } + private async findInterpreterStoredInNotebookMetadata( + resource: Resource, + notebookMetadata?: nbformat.INotebookMetadata + ): Promise { + const info = getInterpreterInfoStoredInMetadata(notebookMetadata); + if (!info) { + return; + } + const interpreters = await this.interpreterService.getInterpreters(resource); + return interpreters.find((item) => sha256().update(item.path).digest('hex') === info.hash); + } // Get our kernelspec and interpreter for a local raw connection private async getKernelForLocalRawConnection( @@ -494,6 +507,19 @@ export class KernelSelector implements IKernelSelectionUsage { cancelToken?: CancellationToken, ignoreDependencyCheck?: boolean ): Promise { + // If user had selected an interpreter (raw kernel), then that interpreter would be stored in the kernelspec metadata. + // Find this matching interpreter & start that using raw kernel. + const interpreterStoredInKernelSpec = await this.findInterpreterStoredInNotebookMetadata( + resource, + notebookMetadata + ); + if (interpreterStoredInKernelSpec) { + return { + kind: 'startUsingPythonInterpreter', + interpreter: interpreterStoredInKernelSpec + }; + } + // First use our kernel finder to locate a kernelspec on disk const kernelSpec = await this.kernelFinder.findKernelSpec( resource, diff --git a/src/client/datascience/notebookStorage/baseModel.ts b/src/client/datascience/notebookStorage/baseModel.ts index db62829a4d0e..a865ec2a75a8 100644 --- a/src/client/datascience/notebookStorage/baseModel.ts +++ b/src/client/datascience/notebookStorage/baseModel.ts @@ -23,6 +23,19 @@ type KernelIdListEntry = { kernelId: string | undefined; }; +export function getInterpreterInfoStoredInMetadata( + metadata?: nbformat.INotebookMetadata +): { displayName: string; hash: string } | undefined { + if (!metadata || !metadata.kernelspec || !metadata.kernelspec.name) { + return; + } + // See `updateNotebookMetadata` to determine how & where exactly interpreter hash is stored. + // tslint:disable-next-line: no-any + const kernelSpecMetadata: undefined | any = metadata.kernelspec.metadata as any; + const interpreterHash = kernelSpecMetadata?.interpreter?.hash; + return interpreterHash ? { displayName: metadata.kernelspec.name, hash: interpreterHash } : undefined; +} + // tslint:disable-next-line: cyclomatic-complexity export function updateNotebookMetadata( metadata?: nbformat.INotebookMetadata, @@ -93,12 +106,29 @@ export function updateNotebookMetadata( metadata.kernelspec.display_name = displayName; kernelId = kernelSpecOrModel.id; } +<<<<<<< HEAD try { // This is set only for when we select an interpreter. // tslint:disable-next-line: no-any delete (metadata.kernelspec as any).metadata; } catch { // Noop. +======= + } else if (kernelConnection?.kind === 'startUsingPythonInterpreter') { + // Store interpreter name, we expect the kernel finder will find the corresponding interpreter based on this name. + const name = kernelConnection.interpreter.displayName || ''; + if (metadata.kernelspec?.name !== name || metadata.kernelspec?.display_name !== name) { + changed = true; + metadata.kernelspec = { + name, + display_name: name, + metadata: { + interpreter: { + hash: sha256().update(kernelConnection.interpreter.path).digest('hex') + } + } + }; +>>>>>>> da389971d... Find interpreter based on hash in kernelspec of nb metadata (#13856) } } return { changed, kernelId }; From 61ae79070bda4dfef58e627ace3cc5725b86f850 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Mon, 5 Oct 2020 16:50:17 -0700 Subject: [PATCH 2/2] Misc --- .../datascience/notebookStorage/baseModel.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/client/datascience/notebookStorage/baseModel.ts b/src/client/datascience/notebookStorage/baseModel.ts index a865ec2a75a8..1a4de63db0b5 100644 --- a/src/client/datascience/notebookStorage/baseModel.ts +++ b/src/client/datascience/notebookStorage/baseModel.ts @@ -106,29 +106,12 @@ export function updateNotebookMetadata( metadata.kernelspec.display_name = displayName; kernelId = kernelSpecOrModel.id; } -<<<<<<< HEAD try { // This is set only for when we select an interpreter. // tslint:disable-next-line: no-any delete (metadata.kernelspec as any).metadata; } catch { // Noop. -======= - } else if (kernelConnection?.kind === 'startUsingPythonInterpreter') { - // Store interpreter name, we expect the kernel finder will find the corresponding interpreter based on this name. - const name = kernelConnection.interpreter.displayName || ''; - if (metadata.kernelspec?.name !== name || metadata.kernelspec?.display_name !== name) { - changed = true; - metadata.kernelspec = { - name, - display_name: name, - metadata: { - interpreter: { - hash: sha256().update(kernelConnection.interpreter.path).digest('hex') - } - } - }; ->>>>>>> da389971d... Find interpreter based on hash in kernelspec of nb metadata (#13856) } } return { changed, kernelId };