From dfe53b3eee752fbacad4c0cb43b5912b432136b3 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 30 Oct 2023 18:18:34 +0000 Subject: [PATCH 1/4] Do not compare global interpreters using their kind when auto-selecting --- .../configuration/environmentTypeComparer.ts | 4 ++++ .../environmentTypeComparer.unit.test.ts | 23 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/client/interpreter/configuration/environmentTypeComparer.ts b/src/client/interpreter/configuration/environmentTypeComparer.ts index 0631bb594bfd..2b1c57c45310 100644 --- a/src/client/interpreter/configuration/environmentTypeComparer.ts +++ b/src/client/interpreter/configuration/environmentTypeComparer.ts @@ -234,6 +234,10 @@ export function getEnvLocationHeuristic(environment: PythonEnvironment, workspac * Compare 2 environment types: return 0 if they are the same, -1 if a comes before b, 1 otherwise. */ function compareEnvironmentType(a: PythonEnvironment, b: PythonEnvironment): number { + if (!a.type && !b.type) { + // Return 0 if two global interpreters are being compared. + return 0; + } const envTypeByPriority = getPrioritizedEnvironmentType(); return Math.sign(envTypeByPriority.indexOf(a.envType) - envTypeByPriority.indexOf(b.envType)); } diff --git a/src/test/configuration/environmentTypeComparer.unit.test.ts b/src/test/configuration/environmentTypeComparer.unit.test.ts index 62c5d2d66b96..019a0d4d87cb 100644 --- a/src/test/configuration/environmentTypeComparer.unit.test.ts +++ b/src/test/configuration/environmentTypeComparer.unit.test.ts @@ -11,6 +11,7 @@ import { getEnvLocationHeuristic, } from '../../client/interpreter/configuration/environmentTypeComparer'; import { IInterpreterHelper } from '../../client/interpreter/contracts'; +import { PythonEnvType } from '../../client/pythonEnvironments/base/info'; import { EnvironmentType, PythonEnvironment } from '../../client/pythonEnvironments/info'; suite('Environment sorting', () => { @@ -45,6 +46,7 @@ suite('Environment sorting', () => { title: 'Local virtual environment should come first', envA: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.venv'), version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -58,11 +60,13 @@ suite('Environment sorting', () => { title: "Non-local virtual environment should not come first when there's a local env", envA: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join('path', 'to', 'other', 'workspace', '.venv'), version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.venv'), version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -72,10 +76,12 @@ suite('Environment sorting', () => { title: "Conda environment should not come first when there's a local env", envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.venv'), version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -85,11 +91,13 @@ suite('Environment sorting', () => { title: 'Conda base environment should come after any other conda env', envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'base', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'random-name', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -99,6 +107,7 @@ suite('Environment sorting', () => { title: 'Pipenv environment should come before any other conda env', envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'conda-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -118,19 +127,21 @@ suite('Environment sorting', () => { } as PythonEnvironment, envB: { envType: EnvironmentType.Poetry, + type: PythonEnvType.Virtual, envName: 'poetry-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, expected: 1, }, { - title: 'Pyenv environment should not come first when there are global envs', + title: 'Pyenv interpreter should not come first when there are global envs', envA: { envType: EnvironmentType.Pyenv, version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Pipenv, + type: PythonEnvType.Virtual, envName: 'pipenv-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -144,6 +155,7 @@ suite('Environment sorting', () => { } as PythonEnvironment, envB: { envType: EnvironmentType.Poetry, + type: PythonEnvType.Virtual, envName: 'poetry-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -157,6 +169,7 @@ suite('Environment sorting', () => { } as PythonEnvironment, envB: { envType: EnvironmentType.VirtualEnv, + type: PythonEnvType.Virtual, envName: 'virtualenv-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -170,6 +183,7 @@ suite('Environment sorting', () => { } as PythonEnvironment, envB: { envType: EnvironmentType.Pipenv, + type: PythonEnvType.Virtual, envName: 'pipenv-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -179,11 +193,13 @@ suite('Environment sorting', () => { title: 'If 2 environments are of the same type, the most recent Python version comes first', envA: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.old-venv'), version: { major: 3, minor: 7, patch: 5, raw: '3.7.5' }, } as PythonEnvironment, envB: { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.venv'), version: { major: 3, minor: 10, patch: 2, raw: '3.10.2' }, } as PythonEnvironment, @@ -194,11 +210,13 @@ suite('Environment sorting', () => { "If 2 global environments have the same Python version and there's a Conda one, the Conda env should not come first", envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'conda-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Pipenv, + type: PythonEnvType.Virtual, envName: 'pipenv-env', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -209,11 +227,13 @@ suite('Environment sorting', () => { 'If 2 global environments are of the same type and have the same Python version, they should be sorted by name', envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'conda-foo', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, envB: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envName: 'conda-bar', version: { major: 3, minor: 10, patch: 2 }, } as PythonEnvironment, @@ -237,6 +257,7 @@ suite('Environment sorting', () => { title: 'Problematic environments should come last', envA: { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envPath: path.join(workspacePath, '.venv'), path: 'python', } as PythonEnvironment, From e7265b05cafcc9a21958fecd004ab60a40b7c3f2 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 30 Oct 2023 18:30:03 +0000 Subject: [PATCH 2/4] Do not prefer Microsoft store interpreter over other global interpreters when auto-selecting --- .../configuration/environmentTypeComparer.ts | 1 + .../environmentTypeComparer.unit.test.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/client/interpreter/configuration/environmentTypeComparer.ts b/src/client/interpreter/configuration/environmentTypeComparer.ts index 2b1c57c45310..7bda1ef4b223 100644 --- a/src/client/interpreter/configuration/environmentTypeComparer.ts +++ b/src/client/interpreter/configuration/environmentTypeComparer.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { injectable, inject } from 'inversify'; +import { isTestExecution } from '../../common/constants'; import { Resource } from '../../common/types'; import { Architecture } from '../../common/utils/platform'; import { isActiveStateEnvironmentForWorkspace } from '../../pythonEnvironments/common/environmentManagers/activestate'; diff --git a/src/test/configuration/environmentTypeComparer.unit.test.ts b/src/test/configuration/environmentTypeComparer.unit.test.ts index 019a0d4d87cb..b7a4b82dc944 100644 --- a/src/test/configuration/environmentTypeComparer.unit.test.ts +++ b/src/test/configuration/environmentTypeComparer.unit.test.ts @@ -175,6 +175,19 @@ suite('Environment sorting', () => { } as PythonEnvironment, expected: 1, }, + { + title: + 'Microsoft Store interpreter should not come first when there are global interpreters with higher version', + envA: { + envType: EnvironmentType.MicrosoftStore, + version: { major: 3, minor: 10, patch: 2, raw: '3.10.2' }, + } as PythonEnvironment, + envB: { + envType: EnvironmentType.Global, + version: { major: 3, minor: 11, patch: 2, raw: '3.11.2' }, + } as PythonEnvironment, + expected: 1, + }, { title: 'Unknown environment should not come first when there are global envs', envA: { From d8897e205b3d7a1ba233efdff306f0f67e720811 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 30 Oct 2023 18:35:41 +0000 Subject: [PATCH 3/4] lint --- src/client/interpreter/configuration/environmentTypeComparer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/interpreter/configuration/environmentTypeComparer.ts b/src/client/interpreter/configuration/environmentTypeComparer.ts index 7bda1ef4b223..2b1c57c45310 100644 --- a/src/client/interpreter/configuration/environmentTypeComparer.ts +++ b/src/client/interpreter/configuration/environmentTypeComparer.ts @@ -2,7 +2,6 @@ // Licensed under the MIT License. import { injectable, inject } from 'inversify'; -import { isTestExecution } from '../../common/constants'; import { Resource } from '../../common/types'; import { Architecture } from '../../common/utils/platform'; import { isActiveStateEnvironmentForWorkspace } from '../../pythonEnvironments/common/environmentManagers/activestate'; From aa85e2ae0a1bce2525fc4e49f482c4edc0ba5f80 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 30 Oct 2023 18:46:07 +0000 Subject: [PATCH 4/4] Fix tests --- .../interpreterSelector/interpreterSelector.unit.test.ts | 4 ++++ src/test/interpreters/autoSelection/index.unit.test.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/test/configuration/interpreterSelector/interpreterSelector.unit.test.ts b/src/test/configuration/interpreterSelector/interpreterSelector.unit.test.ts index 32ba68e03c70..2ec20be66990 100644 --- a/src/test/configuration/interpreterSelector/interpreterSelector.unit.test.ts +++ b/src/test/configuration/interpreterSelector/interpreterSelector.unit.test.ts @@ -14,6 +14,7 @@ import { EnvironmentTypeComparer } from '../../../client/interpreter/configurati import { InterpreterSelector } from '../../../client/interpreter/configuration/interpreterSelector/interpreterSelector'; import { IInterpreterComparer, IInterpreterQuickPickItem } from '../../../client/interpreter/configuration/types'; import { IInterpreterHelper, IInterpreterService, WorkspacePythonPath } from '../../../client/interpreter/contracts'; +import { PythonEnvType } from '../../../client/pythonEnvironments/base/info'; import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnvironments/info'; import { getOSType, OSType } from '../../common'; @@ -139,12 +140,14 @@ suite('Interpreters - selector', () => { envPath: path.join('path', 'to', 'another', 'workspace', '.venv'), path: path.join('path', 'to', 'another', 'workspace', '.venv', 'bin', 'python'), envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, }, { displayName: 'two', envPath: path.join(workspacePath, '.venv'), path: path.join(workspacePath, '.venv', 'bin', 'python'), envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, }, { displayName: 'three', @@ -158,6 +161,7 @@ suite('Interpreters - selector', () => { path: path.join('a', 'conda', 'environment'), envName: 'conda-env', envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, }, ].map((item) => ({ ...info, ...item })); diff --git a/src/test/interpreters/autoSelection/index.unit.test.ts b/src/test/interpreters/autoSelection/index.unit.test.ts index f9c57f867085..d96d590628e0 100644 --- a/src/test/interpreters/autoSelection/index.unit.test.ts +++ b/src/test/interpreters/autoSelection/index.unit.test.ts @@ -23,6 +23,7 @@ import { EnvironmentTypeComparer } from '../../../client/interpreter/configurati import { IInterpreterHelper, IInterpreterService, WorkspacePythonPath } from '../../../client/interpreter/contracts'; import { InterpreterHelper } from '../../../client/interpreter/helpers'; import { InterpreterService } from '../../../client/interpreter/interpreterService'; +import { PythonEnvType } from '../../../client/pythonEnvironments/base/info'; import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnvironments/info'; import * as Telemetry from '../../../client/telemetry'; import { EventName } from '../../../client/telemetry/constants'; @@ -150,6 +151,7 @@ suite('Interpreters - Auto Selection', () => { test('If there is a local environment select it', async () => { const localEnv = { envType: EnvironmentType.Venv, + type: PythonEnvType.Virtual, envPath: path.join(workspacePath, '.venv'), version: { major: 3, minor: 10, patch: 0 }, } as PythonEnvironment; @@ -157,6 +159,7 @@ suite('Interpreters - Auto Selection', () => { when(interpreterService.getInterpreters(resource)).thenCall((_) => [ { envType: EnvironmentType.Conda, + type: PythonEnvType.Conda, envPath: path.join('some', 'conda', 'env'), version: { major: 3, minor: 7, patch: 2 }, } as PythonEnvironment,