Skip to content

Activate banner prompt for Pylance #12817

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 30 commits into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
04e0b34
Fix path
May 6, 2020
9297d96
Merge branch 'master' of https://github.com/Microsoft/vscode-python
May 6, 2020
9f3d5ac
Merge branch 'master' of https://github.com/Microsoft/vscode-python
May 11, 2020
607bf98
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jun 1, 2020
e566214
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jun 11, 2020
4477900
Actually fix settings
Jun 18, 2020
d0d50de
Add news
Jun 18, 2020
03aa5f9
Add test
Jun 18, 2020
e4a032f
Format
Jun 18, 2020
27eeec7
Suppress 'jediEnabled' removal
Jun 18, 2020
89f432e
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jun 23, 2020
3ed655b
Drop survey first launch threshold
Jun 26, 2020
64ac38a
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jun 29, 2020
52a4325
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jun 30, 2020
67d7cb8
Merge branch 'master' of https://github.com/Microsoft/vscode-python
Jul 8, 2020
bbe5a7f
Remove LS experiments
Jul 8, 2020
f29f7d7
Frequency + tests
Jul 8, 2020
19ccc20
Fix test
Jul 8, 2020
4dec978
Update message to match spec
jakebailey Jul 15, 2020
a7fe6a8
Open workspace for extension rather than changing setting
jakebailey Jul 16, 2020
f7e631a
Fix localization string
jakebailey Jul 16, 2020
370d52b
Show banners asynchronously
jakebailey Jul 16, 2020
1396abd
Merge branch 'master' of https://github.com/Microsoft/vscode-python i…
Jul 20, 2020
2450fc7
Add experiments
Jul 20, 2020
0300726
Formatting
Jul 20, 2020
f0d528c
Typo
Jul 20, 2020
57de3f8
Put back verifyAll
Jul 20, 2020
b3c85fc
Remove obsolete experiments, add Pylance
Jul 21, 2020
1ca6b11
Suppress experiment if Pylance is installed
Jul 21, 2020
c1de88a
PR feedback
Jul 21, 2020
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
12 changes: 0 additions & 12 deletions experiments.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@
"min": 0,
"max": 0
},
{
"name": "LS - enabled",
"salt": "LS",
"min": 0,
"max": 4
},
{
"name": "LS - control",
"salt": "LS",
"min": 20,
"max": 24
},
{
"name": "UseTerminalToGetActivatedEnvVars - experiment",
"salt": "UseTerminalToGetActivatedEnvVars",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,6 @@
"default": [],
"items": {
"enum": [
"LS - enabled",
"AlwaysDisplayTestExplorer - experiment",
"ShowExtensionSurveyPrompt - enabled",
"Reload - experiment",
Expand All @@ -1841,6 +1840,7 @@
"DeprecatePythonPath - experiment",
"RunByLine - experiment",
"EnableTrustedNotebooks",
"tryPylance",
"All"
]
},
Expand All @@ -1852,7 +1852,6 @@
"default": [],
"items": {
"enum": [
"LS - enabled",
"AlwaysDisplayTestExplorer - experiment",
"ShowExtensionSurveyPrompt - enabled",
"Reload - experiment",
Expand All @@ -1866,6 +1865,7 @@
"DeprecatePythonPath - experiment",
"RunByLine - experiment",
"EnableTrustedNotebooks",
"tryPylance",
"All"
]
},
Expand Down
3 changes: 3 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
"python.snippet.launch.django.label": "Python: Django",
"python.snippet.launch.flask.label": "Python: Flask",
"python.snippet.launch.pyramid.label": "Python: Pyramid Application",
"LanguageService.proposePylanceMessage": "Try out a new faster, feature-rich language server for Python by Microsoft, Pylance! Install the extension now.",
"LanguageService.tryItNow": "Try it now",
"LanguageService.remindMeLater": "Remind me later",
"LanguageService.bannerLabelYes": "Yes, take survey now",
"LanguageService.bannerLabelNo": "No, thanks",
"LanguageService.lsFailedToStart": "We encountered an issue starting the Language Server. Reverting to the alternative, Jedi. Check the Python output panel for details.",
Expand Down
16 changes: 1 addition & 15 deletions src/client/activation/activationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import { LSNotSupportedDiagnosticServiceId } from '../application/diagnostics/ch
import { IDiagnosticsService } from '../application/diagnostics/types';
import { IApplicationShell, ICommandManager, IWorkspaceService } from '../common/application/types';
import { STANDARD_OUTPUT_CHANNEL } from '../common/constants';
import { LSControl, LSEnabled } from '../common/experiments/groups';
import { traceError } from '../common/logger';
import {
IConfigurationService,
IDisposableRegistry,
IExperimentsManager,
IOutputChannel,
IPersistentStateFactory,
IPythonSettings,
Expand Down Expand Up @@ -58,8 +56,7 @@ export class LanguageServerExtensionActivationService

constructor(
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
@inject(IPersistentStateFactory) private stateFactory: IPersistentStateFactory,
@inject(IExperimentsManager) private readonly abExperiments: IExperimentsManager
@inject(IPersistentStateFactory) private stateFactory: IPersistentStateFactory
) {
this.workspaceService = this.serviceContainer.get<IWorkspaceService>(IWorkspaceService);
this.interpreterService = this.serviceContainer.get<IInterpreterService>(IInterpreterService);
Expand Down Expand Up @@ -175,17 +172,6 @@ export class LanguageServerExtensionActivationService
* @returns `true` if user is using jedi, `false` if user is using language server
*/
public useJedi(): boolean {
// Check if `languageServer` setting is missing (default configuration).
if (this.isJediUsingDefaultConfiguration(this.resource)) {
// If user is assigned to an experiment (i.e. use LS), return false.
if (this.abExperiments.inExperiment(LSEnabled)) {
return false;
}
// Send telemetry if user is in control group
this.abExperiments.sendTelemetryIfInExperiment(LSControl);
return true; // Do use Jedi as it is default.
}
// Configuration is non-default, so `languageServer` should be present.
const configurationService = this.serviceContainer.get<IConfigurationService>(IConfigurationService);
const lstType = configurationService.getSettings(this.resource).languageServer;
this.sendTelemetryForChosenLanguageServer(lstType).ignoreErrors();
Expand Down
18 changes: 15 additions & 3 deletions src/client/activation/languageServer/activator.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { inject, injectable } from 'inversify';
import { inject, injectable, named } from 'inversify';
import * as path from 'path';

import { IWorkspaceService } from '../../common/application/types';
import { isTestExecution } from '../../common/constants';
import { traceDecorators } from '../../common/logger';
import { IFileSystem } from '../../common/platform/types';
import { IConfigurationService, Resource } from '../../common/types';
import { BANNER_NAME_PROPOSE_LS, IConfigurationService, IPythonExtensionBanner, Resource } from '../../common/types';
import { PythonInterpreter } from '../../pythonEnvironments/info';
import { LanguageServerActivatorBase } from '../common/activatorBase';
import { ILanguageServerDownloader, ILanguageServerFolderService, ILanguageServerManager } from '../types';

Expand All @@ -27,11 +29,21 @@ export class DotNetLanguageServerActivator extends LanguageServerActivatorBase {
@inject(IFileSystem) fs: IFileSystem,
@inject(ILanguageServerDownloader) lsDownloader: ILanguageServerDownloader,
@inject(ILanguageServerFolderService) languageServerFolderService: ILanguageServerFolderService,
@inject(IConfigurationService) configurationService: IConfigurationService
@inject(IConfigurationService) configurationService: IConfigurationService,
@inject(IPythonExtensionBanner)
@named(BANNER_NAME_PROPOSE_LS)
private proposePylancePopup: IPythonExtensionBanner
) {
super(manager, workspace, fs, lsDownloader, languageServerFolderService, configurationService);
}

public async start(resource: Resource, interpreter?: PythonInterpreter): Promise<void> {
if (!isTestExecution()) {
this.proposePylancePopup.showBanner().ignoreErrors();
}
return super.start(resource, interpreter);
}

@traceDecorators.error('Failed to ensure language server is available')
public async ensureLanguageServerIsAvailable(resource: Resource): Promise<void> {
const languageServerFolderPath = await this.ensureLanguageServerFileIsAvailable(resource, 'mscorlib.dll');
Expand Down
5 changes: 2 additions & 3 deletions src/client/activation/node/languageServerFolderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import { inject, injectable } from 'inversify';
import * as path from 'path';
import { SemVer } from 'semver';
import { IWorkspaceService } from '../../common/application/types';
import { PYLANCE_EXTENSION_ID } from '../../common/constants';
import { NugetPackage } from '../../common/nuget/types';
import { IConfigurationService, IExtensions, Resource } from '../../common/types';
import { IServiceContainer } from '../../ioc/types';
import { LanguageServerFolderService } from '../common/languageServerFolderService';
import { FolderVersionPair, ILanguageServerFolderService, NodeLanguageServerFolder } from '../types';

export const PylanceExtensionName = 'ms-python.vscode-pylance';

class FallbackNodeLanguageServerFolderService extends LanguageServerFolderService {
constructor(serviceContainer: IServiceContainer) {
super(serviceContainer, NodeLanguageServerFolder);
Expand Down Expand Up @@ -101,7 +100,7 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer
return undefined;
}

const extension = this.extensions.getExtension<ILSExtensionApi>(PylanceExtensionName);
const extension = this.extensions.getExtension<ILSExtensionApi>(PYLANCE_EXTENSION_ID);
if (!extension) {
return undefined;
}
Expand Down
17 changes: 13 additions & 4 deletions src/client/activation/none/activator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { injectable } from 'inversify';
import { inject, injectable, named } from 'inversify';
import {
CancellationToken,
CodeLens,
Expand All @@ -20,7 +20,8 @@ import {
TextDocument,
WorkspaceEdit
} from 'vscode';
import { Resource } from '../../common/types';
import { isTestExecution } from '../../common/constants';
import { BANNER_NAME_PROPOSE_LS, IPythonExtensionBanner, Resource } from '../../common/types';
import { PythonInterpreter } from '../../pythonEnvironments/info';
import { ILanguageServerActivator } from '../types';

Expand All @@ -33,8 +34,16 @@ import { ILanguageServerActivator } from '../types';
*/
@injectable()
export class NoLanguageServerExtensionActivator implements ILanguageServerActivator {
// tslint:disable-next-line: no-empty
public async start(_resource: Resource, _interpreter?: PythonInterpreter): Promise<void> {}
constructor(
@inject(IPythonExtensionBanner)
@named(BANNER_NAME_PROPOSE_LS)
private proposePylancePopup: IPythonExtensionBanner
) {}
public async start(_resource: Resource, _interpreter?: PythonInterpreter): Promise<void> {
if (!isTestExecution()) {
this.proposePylancePopup.showBanner().ignoreErrors();
}
}
// tslint:disable-next-line: no-empty
public dispose(): void {}
// tslint:disable-next-line: no-empty
Expand Down
4 changes: 2 additions & 2 deletions src/client/activation/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { DataScienceSurveyBanner } from '../datascience/dataScienceSurveyBanner';
import { InteractiveShiftEnterBanner } from '../datascience/shiftEnterBanner';
import { IServiceManager } from '../ioc/types';
import { ProposeLanguageServerBanner } from '../languageServices/proposeLanguageServerBanner';
import { ProposePylanceBanner } from '../languageServices/proposeLanguageServerBanner';
import { AATesting } from './aaTesting';
import { ExtensionActivationManager } from './activationManager';
import { LanguageServerExtensionActivationService } from './activationService';
Expand Down Expand Up @@ -86,7 +86,7 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp

serviceManager.addSingleton<IPythonExtensionBanner>(
IPythonExtensionBanner,
ProposeLanguageServerBanner,
ProposePylanceBanner,
BANNER_NAME_PROPOSE_LS
);
serviceManager.addSingleton<IPythonExtensionBanner>(
Expand Down
3 changes: 3 additions & 0 deletions src/client/common/application/applicationEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,7 @@ export class ApplicationEnvironment implements IApplicationEnvironment {
const version = parse(this.packageJson.version);
return !version || version.prerelease.length > 0 ? 'insiders' : 'stable';
}
public get uriScheme(): string {
return vscode.env.uriScheme;
}
}
4 changes: 4 additions & 0 deletions src/client/common/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ export interface IApplicationEnvironment {
* The version of the editor.
*/
readonly vscodeVersion: string;
/**
* The custom uri scheme the editor registers to in the operating system.
*/
readonly uriScheme: string;
}

export const IWebPanelMessageListener = Symbol('IWebPanelMessageListener');
Expand Down
1 change: 1 addition & 0 deletions src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const PYTHON_ALLFILES = [{ language: PYTHON_LANGUAGE }];

export const PVSC_EXTENSION_ID = 'ms-python.python';
export const CODE_RUNNER_EXTENSION_ID = 'formulahendry.code-runner';
export const PYLANCE_EXTENSION_ID = 'ms-python.vscode-pylance';
export const AppinsightsKey = 'AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217';

export namespace Commands {
Expand Down
8 changes: 5 additions & 3 deletions src/client/common/experiments/groups.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
export const LSControl = 'LS - control';
export const LSEnabled = 'LS - enabled';

// Experiment to check whether to always display the test explorer.
export enum AlwaysDisplayTestExplorerGroups {
control = 'AlwaysDisplayTestExplorer - control',
Expand Down Expand Up @@ -99,3 +96,8 @@ export enum RemoveKernelToolbarInInteractiveWindow {
export enum EnableTrustedNotebooks {
experiment = 'EnableTrustedNotebooks'
}

// Experiment to offer switch to Pylance language server
export enum TryPylance {
experiment = 'tryPylance'
}
2 changes: 1 addition & 1 deletion src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ export interface IPythonExtensionBanner {
readonly enabled: boolean;
showBanner(): Promise<void>;
}
export const BANNER_NAME_PROPOSE_LS: string = 'ProposeLS';
export const BANNER_NAME_PROPOSE_LS: string = 'ProposePylance';
export const BANNER_NAME_DS_SURVEY: string = 'DSSurveyBanner';
export const BANNER_NAME_INTERACTIVE_SHIFTENTER: string = 'InteractiveShiftEnterBanner';

Expand Down
7 changes: 7 additions & 0 deletions src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ export namespace AttachProcess {
}

export namespace LanguageService {
export const proposePylanceMessage = localize(
'LanguageService.proposePylanceMessage',
'Try out a new faster, feature-rich language server for Python by Microsoft, Pylance! Install the extension now.'
);
export const tryItNow = localize('LanguageService.tryItNow', 'Try it now');
export const remindMeLater = localize('LanguageService.remindMeLater', 'Remind me later');

export const bannerLabelYes = localize('LanguageService.bannerLabelYes', 'Yes, take survey now');
export const bannerLabelNo = localize('LanguageService.bannerLabelNo', 'No, thanks');
export const lsFailedToStart = localize(
Expand Down
Loading