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
12 changes: 8 additions & 4 deletions src/client/activation/common/defaultlanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import { injectable } from 'inversify';
import { PYLANCE_EXTENSION_ID } from '../../common/constants';
import { PYLANCE_EXTENSION_ID, PYREFLY_EXTENSION_ID } from '../../common/constants';
import { IDefaultLanguageServer, IExtensions, DefaultLSType } from '../../common/types';
import { IServiceManager } from '../../ioc/types';
import { LanguageServerType } from '../types';
Expand All @@ -28,9 +28,13 @@ export async function setDefaultLanguageServer(
}

async function getDefaultLanguageServer(extensions: IExtensions): Promise<DefaultLSType> {
let type = LanguageServerType.Jedi;
if (extensions.getExtension(PYLANCE_EXTENSION_ID)) {
return LanguageServerType.Node;
type = LanguageServerType.Node;
}

return LanguageServerType.Jedi;

if (extensions.getExtension(PYREFLY_EXTENSION_ID)) {
return {type: "none or (if pyrefly language services disabled)", languageServerType: type};
}
return {type: "always", languageServerType: type};
}
19 changes: 17 additions & 2 deletions src/client/common/configSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,29 @@ export class PythonSettings implements IPythonSettings {
let userLS = pythonSettings.get<string>('languageServer');
userLS = systemVariables.resolveAny(userLS);

// Default language server type: if `IDefaultLanguageServer?.defaultLSType` is undefined, default to `None`.
let defaultLS = LanguageServerType.None;

let defaultLSType = this.defaultLS?.defaultLSType;
if (defaultLSType !== undefined) {
// If we are sure what to default the language server type to, use it.
if (defaultLSType.type === "always") {
defaultLS = defaultLSType.languageServerType;
}
// If Pyrefly extension is installed, keep defaultLS = None unless Pyrefly has disabled language services.
else if (defaultLSType.type === "none or (if pyrefly language services disabled)" && pythonSettings.get<WorkspaceConfiguration>('pyrefly')?.get<boolean>('disableLanguageServices') !== true) {
defaultLS = defaultLSType.languageServerType;
}
}

// Validate the user's input; if invalid, set it to the default.
if (
else if (
!userLS ||
userLS === 'Default' ||
userLS === 'Microsoft' ||
!Object.values(LanguageServerType).includes(userLS as LanguageServerType)
) {
this.languageServer = this.defaultLS?.defaultLSType ?? LanguageServerType.None;
this.languageServer = defaultLS;
this.languageServerIsDefault = true;
} else if (userLS === 'JediLSP') {
// Switch JediLSP option to Jedi.
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 @@ -22,6 +22,7 @@ export const PYTHON_NOTEBOOKS = [

export const PVSC_EXTENSION_ID = 'ms-python.python';
export const PYLANCE_EXTENSION_ID = 'ms-python.vscode-pylance';
export const PYREFLY_EXTENSION_ID = 'meta.pyrefly';
export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
export const TENSORBOARD_EXTENSION_ID = 'ms-toolsai.tensorboard';
export const AppinsightsKey = '0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255';
Expand Down
17 changes: 16 additions & 1 deletion src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,22 @@ export interface IInterpreterPathService {
copyOldInterpreterStorageValuesToNew(resource: Resource): Promise<void>;
}

export type DefaultLSType = LanguageServerType.Jedi | LanguageServerType.Node;
/**
* If Pyrefly extension is installed, LS default should be `None`. But if Pyrefly language services are disabled,
* fall back to T.
*/
export type PyreflyOr<T extends LanguageServerType> = {
type: 'none or (if pyrefly language services disabled)',
languageServerType: T,
};

export type Always<T extends LanguageServerType> = {
type: 'always',
languageServerType: T,
};

type DefaultLSTypes = LanguageServerType.Jedi | LanguageServerType.Node;
export type DefaultLSType = Always<DefaultLSTypes> | PyreflyOr<DefaultLSTypes>;

/**
* Interface used to retrieve the default language server.
Expand Down
2 changes: 2 additions & 0 deletions src/client/languageServer/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ export class LanguageServerWatcher implements IExtensionActivationService, ILang
await this.refreshLanguageServer(resource);
} else if (event.affectsConfiguration(`python.analysis.pylanceLspClientEnabled`, resource)) {
await this.refreshLanguageServer(resource, /* forced */ true);
} else if (event.affectsConfiguration('python.pyrefly.languageServer', resource)) {
await this.refreshLanguageServer(resource);
}
});
}
Expand Down
23 changes: 20 additions & 3 deletions src/test/activation/defaultLanguageServer.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { anything, instance, mock, when, verify } from 'ts-mockito';
import { Extension } from 'vscode';
import { setDefaultLanguageServer } from '../../client/activation/common/defaultlanguageServer';
import { LanguageServerType } from '../../client/activation/types';
import { PYLANCE_EXTENSION_ID } from '../../client/common/constants';
import { PYLANCE_EXTENSION_ID, PYREFLY_EXTENSION_ID } from '../../client/common/constants';
import { IDefaultLanguageServer, IExtensions } from '../../client/common/types';
import { ServiceManager } from '../../client/ioc/serviceManager';
import { IServiceManager } from '../../client/ioc/types';
Expand Down Expand Up @@ -37,7 +37,7 @@ suite('Activation - setDefaultLanguageServer()', () => {

verify(extensions.getExtension(PYLANCE_EXTENSION_ID)).once();
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
expect(defaultServerType).to.equal(LanguageServerType.Jedi);
expect(defaultServerType).to.deep.equal({type: "always", languageServerType: LanguageServerType.Jedi});
});

test('Pylance installed', async () => {
Expand All @@ -54,6 +54,23 @@ suite('Activation - setDefaultLanguageServer()', () => {

verify(extensions.getExtension(PYLANCE_EXTENSION_ID)).once();
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
expect(defaultServerType).to.equal(LanguageServerType.Node);
expect(defaultServerType).to.deep.equal({type: "always", languageServerType: LanguageServerType.Node});
});

test('Pyrefly installed', async () => {
let defaultServerType;

when(extensions.getExtension(PYREFLY_EXTENSION_ID)).thenReturn(instance(extension));
when(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).thenCall(
(_symbol, value: IDefaultLanguageServer) => {
defaultServerType = value.defaultLSType;
},
);

await setDefaultLanguageServer(instance(extensions), instance(serviceManager));

verify(extensions.getExtension(PYREFLY_EXTENSION_ID)).once();
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
expect(defaultServerType).to.deep.equal({type: "none or (if pyrefly language services disabled)", languageServerType: LanguageServerType.Jedi});
});
});
Loading