Skip to content

Improve how to notify the user they don't have Python installed when installing the Python extension for the first time #19379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
46 changes: 16 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"onDebugInitialConfigurations",
"onLanguage:python",
"onDebugResolve:python",
"onCommand:python.createNewFile",
"onCommand:python.execInTerminal",
"onCommand:python.debugInTerminal",
"onCommand:python.sortImports",
Expand Down Expand Up @@ -107,13 +106,23 @@
"when": "workspacePlatform != webworker",
"steps": [
{
"id": "python.installPythonWin",
"id": "python.createPythonFile",
"title": "Create a Python file",
"description": "[Open](command:toSide:workbench.action.files.openFile) or [create](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22python%22%7D) a Python file - make sure to save it as \".py\".\n[Create Python File](command:toSide:workbench.action.files.newUntitledFile?%7B%22languageId%22%3A%22python%22%7D)",
"media": {
"svg": "resources/walkthrough/open-folder.svg",
"altText": "Open a Python file or a folder with a Python project."
},
"when": ""
},
{
"id": "python.installPythonWin8",
"title": "Install Python",
"description": "The Python Extension requires Python to be installed. Install Python from the [Microsoft Store](https://aka.ms/AAd9rms).\n\n[Install Python](https://aka.ms/AAd9rms)\n",
"description": "The Python Extension requires Python to be installed. Install Python [from python.org](https://www.python.org/downloads).\n\n[Install Python](https://www.python.org/downloads)\n",
"media": {
"markdown": "resources/walkthrough/install-python-windows.md"
"markdown": "resources/walkthrough/install-python-windows-8.md"
},
"when": "workspacePlatform == windows"
"when": "workspacePlatform == windows && showInstallPythonTile"
},
{
"id": "python.installPythonMac",
Expand All @@ -122,7 +131,7 @@
"media": {
"markdown": "resources/walkthrough/install-python-macos.md"
},
"when": "workspacePlatform == mac",
"when": "workspacePlatform == mac && showInstallPythonTile",
"command": "workbench.action.terminal.new"
},
{
Expand All @@ -132,19 +141,9 @@
"media": {
"markdown": "resources/walkthrough/install-python-linux.md"
},
"when": "workspacePlatform == linux",
"when": "workspacePlatform == linux && showInstallPythonTile",
"command": "workbench.action.terminal.new"
},
{
"id": "python.createPythonFile",
"title": "Create a Python file",
"description": "[Open](command:toSide:workbench.action.files.openFile) or [create](command:toSide:python.createNewFile) a Python file - make sure to save it as \".py\".\n[Create Python File](command:toSide:python.createNewFile)",
"media": {
"svg": "resources/walkthrough/open-folder.svg",
"altText": "Open a Python file or a folder with a Python project."
},
"when": ""
},
{
"id": "python.selectInterpreter",
"title": "Select a Python Interpreter",
Expand Down Expand Up @@ -248,12 +247,6 @@
}
],
"commands": [
{
"title": "%python.command.python.createNewFile.title%",
"shortTitle": "%python.menu.createNewFile.title%",
"category": "Python",
"command": "python.createNewFile"
},
{
"category": "Python",
"command": "python.analysis.restartLanguageServer",
Expand Down Expand Up @@ -1710,13 +1703,6 @@
"when": "resourceLangId == python && !virtualWorkspace && shellExecutionSupported"
}
],
"file/newFile": [
{
"command": "python.createNewFile",
"group": "file",
"when": "!virtualWorkspace"
}
],
"view/title": [
{
"command": "testing.reRunFailTests",
Expand Down
1 change: 0 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"python.command.python.sortImports.title": "Sort Imports",
"python.command.python.startREPL.title": "Start REPL",
"python.command.python.createTerminal.title": "Create Terminal",
"python.command.python.createNewFile.title": "New Python File",
"python.command.python.execInTerminal.title": "Run Python File in Terminal",
"python.command.python.debugInTerminal.title": "Debug Python File",
"python.command.python.execInTerminalIcon.title": "Run Python File",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
## Install Python on Windows

If you don't have Python installed on your Windows machine, you can install it from the [Microsoft Store](https://aka.ms/AAd9rms).

To verify it's installed, create a new terminal (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>`</kbd>) and try running the following command:

```
python --version
```

You should see something similar to the following:
```
Python 3.9.5
```
## Install Python on Windows

If you don't have Python installed on your Windows machine, you can install it [from python.org](https://www.python.org/downloads).

To verify it's installed, create a new terminal (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>`</kbd>) and try running the following command:

```
python --version
```

You should see something similar to the following:
```
Python 3.9.5
```
For additional information about using Python on Windows, see [Using Python on Windows at Python.org](https://docs.python.org/3.10/using/windows.html).
3 changes: 2 additions & 1 deletion src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type CommandsWithoutArgs = keyof ICommandNameWithoutArgumentTypeMapping;
* @interface ICommandNameWithoutArgumentTypeMapping
*/
interface ICommandNameWithoutArgumentTypeMapping {
[Commands.InstallPython]: [];
[Commands.ClearWorkspaceInterpreter]: [];
[Commands.Set_Interpreter]: [];
[Commands.Set_ShebangInterpreter]: [];
Expand All @@ -40,7 +41,6 @@ interface ICommandNameWithoutArgumentTypeMapping {
[Commands.PickLocalProcess]: [];
[Commands.ClearStorage]: [];
[Commands.ReportIssue]: [];
[Commands.CreateNewFile]: [];
[Commands.RefreshTensorBoard]: [];
[LSCommands.RestartLS]: [];
}
Expand All @@ -57,6 +57,7 @@ export type AllCommands = keyof ICommandNameArgumentTypeMapping;
export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgumentTypeMapping {
['vscode.openWith']: [Uri, string];
['workbench.action.quickOpen']: [string];
['workbench.action.openWalkthrough']: [string | { category: string; step: string }, boolean | undefined];
['workbench.extensions.installExtension']: [
Uri | 'ms-python.python',
(
Expand Down
29 changes: 0 additions & 29 deletions src/client/common/application/commands/createFileCommand.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/client/common/application/contextKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

export enum ExtensionContextKey {
showInstallPythonTile = 'showInstallPythonTile',
HasFailedTests = 'hasFailedTests',
RefreshingTests = 'refreshingTests',
}
9 changes: 9 additions & 0 deletions src/client/common/application/walkThroughs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

export enum PythonWelcome {
name = 'pythonWelcome',
windowsInstallId = 'python.installPythonWin8',
linuxInstallId = 'python.installPythonLinux',
macOSInstallId = 'python.installPythonMac',
}
3 changes: 2 additions & 1 deletion src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export namespace Commands {
export const ViewOutput = 'python.viewOutput';
export const Start_REPL = 'python.startREPL';
export const Create_Terminal = 'python.createTerminal';
export const CreateNewFile = 'python.createNewFile';
export const Set_Linter = 'python.setLinter';
export const Enable_Linter = 'python.enableLinting';
export const Run_Linter = 'python.runLinting';
Expand All @@ -57,6 +56,7 @@ export namespace Commands {
export const LaunchTensorBoard = 'python.launchTensorBoard';
export const RefreshTensorBoard = 'python.refreshTensorBoard';
export const ReportIssue = 'python.reportIssue';
export const InstallPython = 'python.installPython';
}

// Look at https://microsoft.github.io/vscode-codicons/dist/codicon.html for other Octicon icon ids
Expand All @@ -72,6 +72,7 @@ export namespace Octicons {
export const Star = '$(star-full)';
export const Gear = '$(gear)';
export const Warning = '$(warning)';
export const Error = '$(error)';
}

export const DEFAULT_INTERPRETER_SETTING = 'python';
Expand Down
5 changes: 0 additions & 5 deletions src/client/common/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { ClipboardService } from './application/clipboard';
import { CommandManager } from './application/commandManager';
import { ReloadVSCodeCommandHandler } from './application/commands/reloadCommand';
import { ReportIssueCommandHandler } from './application/commands/reportIssueCommand';
import { CreatePythonFileCommandHandler } from './application/commands/createFileCommand';
import { DebugService } from './application/debugService';
import { DebugSessionTelemetry } from './application/debugSessionTelemetry';
import { DocumentManager } from './application/documentManager';
Expand Down Expand Up @@ -177,10 +176,6 @@ export function registerTypes(serviceManager: IServiceManager): void {
IExtensionSingleActivationService,
ReportIssueCommandHandler,
);
serviceManager.addSingleton<IExtensionSingleActivationService>(
IExtensionSingleActivationService,
CreatePythonFileCommandHandler,
);
serviceManager.addSingleton<IExtensionSingleActivationService>(
IExtensionSingleActivationService,
DebugSessionTelemetry,
Expand Down
8 changes: 8 additions & 0 deletions src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,14 @@ export namespace Interpreters {
}

export namespace InterpreterQuickPickList {
export const noPythonInstalled = localize(
'InterpreterQuickPickList.noPythonInstalled',
'Python is not installed, please download and install it',
);
export const clickForInstructions = localize(
'InterpreterQuickPickList.clickForInstructions',
'Click for instructions...',
);
export const globalGroupName = localize('InterpreterQuickPickList.globalGroupName', 'Global');
export const workspaceGroupName = localize('InterpreterQuickPickList.workspaceGroupName', 'Workspace');
export const enterPath = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

'use strict';

import { inject, injectable } from 'inversify';
import { IExtensionSingleActivationService } from '../../../../activation/types';
import { ExtensionContextKey } from '../../../../common/application/contextKeys';
import { ICommandManager, IContextKeyManager } from '../../../../common/application/types';
import { PythonWelcome } from '../../../../common/application/walkThroughs';
import { Commands, PVSC_EXTENSION_ID } from '../../../../common/constants';
import { IBrowserService, IDisposableRegistry } from '../../../../common/types';
import { IPlatformService } from '../../../../common/platform/types';

@injectable()
export class InstallPythonCommand implements IExtensionSingleActivationService {
public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false };

constructor(
@inject(ICommandManager) private readonly commandManager: ICommandManager,
@inject(IContextKeyManager) private readonly contextManager: IContextKeyManager,
@inject(IBrowserService) private readonly browserService: IBrowserService,
@inject(IPlatformService) private readonly platformService: IPlatformService,
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry,
) {}

public async activate(): Promise<void> {
this.disposables.push(this.commandManager.registerCommand(Commands.InstallPython, () => this._installPython()));
}

public async _installPython(): Promise<void> {
if (this.platformService.isWindows) {
const version = await this.platformService.getVersion();
if (version.major > 8) {
// OS is not Windows 8, ms-windows-store URIs are available:
// https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-store-app
this.browserService.launch('ms-windows-store://pdp/?ProductId=9PJPW5LDXLZ5');
return;
}
}
this.showInstallPythonTile();
}

private showInstallPythonTile() {
this.contextManager.setContext(ExtensionContextKey.showInstallPythonTile, true);
let step: string;
if (this.platformService.isWindows) {
step = PythonWelcome.windowsInstallId;
} else if (this.platformService.isLinux) {
step = PythonWelcome.linuxInstallId;
} else {
step = PythonWelcome.macOSInstallId;
}
this.commandManager.executeCommand(
'workbench.action.openWalkthrough',
{
category: `${PVSC_EXTENSION_ID}#${PythonWelcome.name}`,
step: `${PVSC_EXTENSION_ID}#${PythonWelcome.name}#${step}`,
},
false,
);
}
}
Loading