Skip to content

Add type info which can be used to differentiate Pyenv global installs from Pyenv virtualenvs #19862

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 2 commits into from
Sep 20, 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
6 changes: 6 additions & 0 deletions src/client/pythonEnvironments/base/info/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
PythonEnvInfo,
PythonEnvKind,
PythonEnvSource,
PythonEnvType,
PythonReleaseLevel,
PythonVersion,
virtualEnvKinds,
Expand All @@ -40,6 +41,7 @@ export function buildEnvInfo(init?: {
display?: string;
sysPrefix?: string;
searchLocation?: Uri;
type?: PythonEnvType;
}): PythonEnvInfo {
const env: PythonEnvInfo = {
name: init?.name ?? '',
Expand Down Expand Up @@ -103,6 +105,7 @@ function updateEnv(
location?: string;
version?: PythonVersion;
searchLocation?: Uri;
type?: PythonEnvType;
},
): void {
if (updates.kind !== undefined) {
Expand All @@ -120,6 +123,9 @@ function updateEnv(
if (updates.searchLocation !== undefined) {
env.searchLocation = updates.searchLocation;
}
if (updates.type !== undefined) {
env.type = updates.type;
}
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/client/pythonEnvironments/base/info/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export enum PythonEnvKind {
OtherVirtual = 'virt-other',
}

export enum PythonEnvType {
Conda = 'Conda',
Virtual = 'Virtual',
}

export interface EnvPathType {
/**
* Path to environment folder or path to interpreter that uniquely identifies an environment.
Expand Down Expand Up @@ -105,6 +110,7 @@ export enum PythonEnvSource {
type PythonEnvBaseInfo = {
id?: string;
kind: PythonEnvKind;
type?: PythonEnvType;
executable: PythonExecutableInfo;
// One of (name, location) must be non-empty.
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
import * as path from 'path';
import { Uri } from 'vscode';
import { uniq } from 'lodash';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource, UNKNOWN_PYTHON_VERSION, virtualEnvKinds } from '../../info';
import {
PythonEnvInfo,
PythonEnvKind,
PythonEnvSource,
PythonEnvType,
UNKNOWN_PYTHON_VERSION,
virtualEnvKinds,
} from '../../info';
import {
buildEnvInfo,
comparePythonVersionSpecificity,
Expand All @@ -26,6 +33,7 @@ import { getRegistryInterpreters, getRegistryInterpretersSync } from '../../../c
import { BasicEnvInfo } from '../../locator';
import { parseVersionFromExecutable } from '../../info/executable';
import { traceError, traceWarn } from '../../../../logging';
import { isVirtualEnvironment } from '../../../common/environmentManagers/simplevirtualenvs';

function getResolvers(): Map<PythonEnvKind, (env: BasicEnvInfo, useCache?: boolean) => Promise<PythonEnvInfo>> {
const resolvers = new Map<PythonEnvKind, (_: BasicEnvInfo, useCache?: boolean) => Promise<PythonEnvInfo>>();
Expand Down Expand Up @@ -62,9 +70,26 @@ export async function resolveBasicEnv(env: BasicEnvInfo, useCache = false): Prom
const { ctime, mtime } = await getFileInfo(resolvedEnv.executable.filename);
resolvedEnv.executable.ctime = ctime;
resolvedEnv.executable.mtime = mtime;
const type = await getEnvType(resolvedEnv);
if (type) {
resolvedEnv.type = type;
}
return resolvedEnv;
}

async function getEnvType(env: PythonEnvInfo) {
if (env.type) {
return env.type;
}
if (await isVirtualEnvironment(env.executable.filename)) {
return PythonEnvType.Virtual;
}
if (await isCondaEnvironment(env.executable.filename)) {
return PythonEnvType.Conda;
}
return undefined;
}

function getSearchLocation(env: PythonEnvInfo): Uri | undefined {
const folders = getWorkspaceFolders();
const isRootedEnv = folders.some((f) => isParentPath(env.executable.filename, f) || isParentPath(env.location, f));
Expand Down Expand Up @@ -131,6 +156,7 @@ async function resolveSimpleEnv(env: BasicEnvInfo): Promise<PythonEnvInfo> {
kind,
version: await getPythonVersionFromPath(executablePath),
executable: executablePath,
type: PythonEnvType.Virtual,
});
const location = getEnvironmentDirFromPath(executablePath);
envInfo.location = location;
Expand Down Expand Up @@ -161,6 +187,7 @@ async function resolveCondaEnv(env: BasicEnvInfo, useCache?: boolean): Promise<P
location: prefix,
source: [],
version: executable ? await getPythonVersionFromPath(executable) : undefined,
type: PythonEnvType.Conda,
});
if (name) {
info.name = name;
Expand All @@ -175,7 +202,9 @@ async function resolveCondaEnv(env: BasicEnvInfo, useCache?: boolean): Promise<P
);
// Environment could still be valid, resolve as a simple env.
env.kind = PythonEnvKind.Unknown;
return resolveSimpleEnv(env);
const envInfo = await resolveSimpleEnv(env);
envInfo.type = PythonEnvType.Conda;
return envInfo;
}

async function resolvePyenvEnv(env: BasicEnvInfo): Promise<PythonEnvInfo> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ function getPyvenvConfigPathsFrom(interpreterPath: string): string[] {
return [venvPath1, venvPath2];
}

/**
* Checks if the given interpreter is a virtual environment.
* @param {string} interpreterPath: Absolute path to the python interpreter.
* @returns {boolean} : Returns true if the interpreter belongs to a venv environment.
*/
export async function isVirtualEnvironment(interpreterPath: string): Promise<boolean> {
return isVenvEnvironment(interpreterPath);
}

/**
* Checks if the given interpreter belongs to a venv based environment.
* @param {string} interpreterPath: Absolute path to the python interpreter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as platformApis from '../../../../../client/common/utils/platform';
import {
PythonEnvInfo,
PythonEnvKind,
PythonEnvType,
PythonVersion,
UNKNOWN_PYTHON_VERSION,
} from '../../../../../client/pythonEnvironments/base/info';
Expand Down Expand Up @@ -66,6 +67,9 @@ suite('Python envs locator - Environments Resolver', () => {
updatedEnv.arch = Architecture.x64;
updatedEnv.display = expectedDisplay;
updatedEnv.detailedDisplayName = expectedDisplay;
if (env.kind === PythonEnvKind.Conda) {
env.type = PythonEnvType.Conda;
}
return updatedEnv;
}

Expand All @@ -76,6 +80,7 @@ suite('Python envs locator - Environments Resolver', () => {
name = '',
location = '',
display: string | undefined = undefined,
type?: PythonEnvType,
): PythonEnvInfo {
return {
name,
Expand All @@ -94,6 +99,7 @@ suite('Python envs locator - Environments Resolver', () => {
distro: { org: '' },
searchLocation: Uri.file(location),
source: [],
type,
};
}
suite('iterEnvs()', () => {
Expand Down Expand Up @@ -128,6 +134,7 @@ suite('Python envs locator - Environments Resolver', () => {
'win1',
path.join(testVirtualHomeDir, '.venvs', 'win1'),
"Python ('win1': venv)",
PythonEnvType.Virtual,
);
const envsReturnedByParentLocator = [env1];
const parentLocator = new SimpleLocator<BasicEnvInfo>(envsReturnedByParentLocator);
Expand All @@ -151,6 +158,8 @@ suite('Python envs locator - Environments Resolver', () => {
undefined,
'win1',
path.join(testVirtualHomeDir, '.venvs', 'win1'),
undefined,
PythonEnvType.Virtual,
);
const envsReturnedByParentLocator = [env1];
const parentLocator = new SimpleLocator<BasicEnvInfo>(envsReturnedByParentLocator);
Expand Down Expand Up @@ -206,6 +215,8 @@ suite('Python envs locator - Environments Resolver', () => {
undefined,
'win1',
path.join(testVirtualHomeDir, '.venvs', 'win1'),
undefined,
PythonEnvType.Virtual,
);
const envsReturnedByParentLocator = [env];
const didUpdate = new EventEmitter<PythonEnvUpdatedEvent<BasicEnvInfo> | ProgressNotificationEvent>();
Expand Down Expand Up @@ -355,6 +366,8 @@ suite('Python envs locator - Environments Resolver', () => {
undefined,
'win1',
path.join(testVirtualHomeDir, '.venvs', 'win1'),
undefined,
PythonEnvType.Virtual,
);
const parentLocator = new SimpleLocator([]);
const resolver = new PythonEnvsResolver(parentLocator, envInfoService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
PythonEnvInfo,
PythonEnvKind,
PythonEnvSource,
PythonEnvType,
PythonVersion,
UNKNOWN_PYTHON_VERSION,
} from '../../../../../client/pythonEnvironments/base/info';
Expand Down Expand Up @@ -76,6 +77,7 @@ suite('Resolver Utils', () => {
},
source: [],
org: 'miniconda3',
type: PythonEnvType.Conda,
});
envInfo.location = path.join(testPyenvVersionsDir, 'miniconda3-4.7.12');
envInfo.name = 'base';
Expand Down Expand Up @@ -209,6 +211,7 @@ suite('Resolver Utils', () => {
version: UNKNOWN_PYTHON_VERSION,
fileInfo: undefined,
name: 'base',
type: PythonEnvType.Conda,
});
setEnvDisplayString(info);
return info;
Expand Down Expand Up @@ -237,6 +240,7 @@ suite('Resolver Utils', () => {
searchLocation: undefined,
source: [],
};
info.type = PythonEnvType.Conda;
setEnvDisplayString(info);
return info;
}
Expand Down Expand Up @@ -333,6 +337,7 @@ suite('Resolver Utils', () => {
distro: { org: '' },
searchLocation: Uri.file(location),
source: [],
type: PythonEnvType.Virtual,
};
setEnvDisplayString(info);
return info;
Expand Down Expand Up @@ -623,6 +628,7 @@ suite('Resolver Utils', () => {
org: 'ContinuumAnalytics', // Provided by registry
name: 'conda3',
source: [PythonEnvSource.WindowsRegistry],
type: PythonEnvType.Conda,
});
setEnvDisplayString(expected);
expected.distro.defaultDisplayName = 'Anaconda py38_4.8.3';
Expand Down