Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/2 Fixes/10071.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Re-install `Jupyter` instead of installing `kernelspec` if `kernelspec` cannot be found in the python environment.
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ function sortProductsInOrderForInstallation(products: Product[]) {
* @returns {string}
*/
export function getMessageForLibrariesNotInstalled(products: Product[], interpreterName?: string): string {
// Even though kernelspec cannot be installed, display it so user knows what is missing.
const names = products
// Ignore kernelspec as it not something that can be installed.
.filter(product => product !== Product.kernelspec)
.map(product => ProductNames.get(product))
.filter(name => !!name)
.map(name => name as string);
Expand Down Expand Up @@ -131,15 +130,15 @@ export class JupyterInterpreterDependencyService {
_error?: JupyterInstallError,
token?: CancellationToken
): Promise<JupyterInterpreterDependencyResponse> {
const productsToInstall = await this.getDependenciesNotInstalled(interpreter, token);
const missingProducts = await this.getDependenciesNotInstalled(interpreter, token);
if (Cancellation.isCanceled(token)) {
return JupyterInterpreterDependencyResponse.cancel;
}
if (productsToInstall.length === 0) {
if (missingProducts.length === 0) {
return JupyterInterpreterDependencyResponse.ok;
}

const message = getMessageForLibrariesNotInstalled(productsToInstall, interpreter.displayName);
const message = getMessageForLibrariesNotInstalled(missingProducts, interpreter.displayName);

sendTelemetryEvent(Telemetry.JupyterNotInstalledErrorShown);
const selection = await this.applicationShell.showErrorMessage(
Expand All @@ -155,8 +154,15 @@ export class JupyterInterpreterDependencyService {

switch (selection) {
case DataScience.jupyterInstall(): {
// Ignore kernelspec as it not something that can be installed.
// If kernelspec isn't available, then re-install `Jupyter`.
if (missingProducts.includes(Product.kernelspec) && !missingProducts.includes(Product.jupyter)) {
missingProducts.push(Product.jupyter);
}
const productsToInstall = missingProducts.filter(product => product !== Product.kernelspec);
// Install jupyter, then notebook, then others in that order.
sortProductsInOrderForInstallation(productsToInstall);

let productToInstall = productsToInstall.shift();
const cancellatonPromise = createPromiseFromCancellation({
cancelAction: 'resolve',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { InterpreterType, PythonInterpreter } from '../../../../client/interpret

// tslint:disable: max-func-body-length

suite('Data Science - Jupyter Interpreter Configuration', () => {
suite('xData Science - Jupyter Interpreter Configuration', () => {
Comment thread
DonJayamanne marked this conversation as resolved.
Resolved
let configuration: JupyterInterpreterDependencyService;
let appShell: IApplicationShell;
let installer: IInstaller;
Expand Down Expand Up @@ -84,6 +84,33 @@ suite('Data Science - Jupyter Interpreter Configuration', () => {
test('Prompt to install if notebook is not installed', async () => testPromptIfModuleNotInstalled(true, false));
test('Prompt to install if jupyter & notebook is not installed', async () =>
testPromptIfModuleNotInstalled(false, false));
test('Reinstall Jupyter if jupyter and notebook are installed but kernelspec is not found', async () => {
when(installer.isInstalled(Product.jupyter, pythonInterpreter)).thenResolve(true);
when(installer.isInstalled(Product.notebook, pythonInterpreter)).thenResolve(true);
when(appShell.showErrorMessage(anything(), anything(), anything(), anything())).thenResolve(
// tslint:disable-next-line: no-any
DataScience.jupyterInstall() as any
);
when(pythonExecService.execModule('jupyter', deepEqual(['kernelspec', '--version']), anything())).thenReject(
new Error('Not found')
);
when(installer.install(anything(), anything(), anything())).thenResolve(InstallerResponse.Installed);

const response = await configuration.installMissingDependencies(pythonInterpreter);

// Jupyter must be installed & not kernelspec or anything else.
verify(installer.install(Product.jupyter, anything(), anything())).once();
verify(installer.install(anything(), anything(), anything())).once();
verify(
appShell.showErrorMessage(
anything(),
DataScience.jupyterInstall(),
DataScience.selectDifferentJupyterInterpreter(),
anything()
)
).once();
assert.equal(response, JupyterInterpreterDependencyResponse.cancel);
});

async function testInstallationOfJupyter(
installerResponse: InstallerResponse,
Expand Down