Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/* eslint-disable max-classes-per-file */

import { Event, EventEmitter } from 'vscode';
import { traceError } from '../../../../common/logger';
import { DirEntry } from '../../../../common/utils/filesystem';
import { iterPythonExecutablesInDir } from '../../../common/commonUtils';
import { resolvePath } from '../../../common/externalDependencies';
Expand Down Expand Up @@ -65,7 +66,11 @@ async function* iterMinimalEnvsFromExecutables(
for await (const executable of executables) {
const filename = typeof executable === 'string' ? executable : executable.filename;
const normFile = resolvePath(filename);
yield getFastEnvInfo(defaultKind, normFile);
try {
yield getFastEnvInfo(defaultKind, normFile);
} catch (ex) {
traceError(`Failed to process environment: ${normFile}`, ex);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { uniq } from 'lodash';
import * as path from 'path';
import { Uri } from 'vscode';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { chain, iterable } from '../../../../common/utils/async';
import {
findInterpretersInDir,
Expand Down Expand Up @@ -126,8 +126,12 @@ export class WorkspaceVirtualEnvironmentLocator extends FSWatchingLocator {
// We don't know the environment type so skip this one.
traceVerbose(`Workspace Virtual Environment: [skipped] ${filename}`);
} else {
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Workspace Virtual Environment: [added] ${filename}`);
try {
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Workspace Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
}
}
} else {
traceVerbose(`Workspace Virtual Environment: [skipped] ${filename}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { IPythonEnvsIterator, Locator } from '../../../base/locator';
import { getInterpreterPathFromDir, getPythonVersionFromPath } from '../../../common/commonUtils';
import { AnacondaCompanyName, Conda } from './conda';
import { resolveEnvFromIterator } from '../../../base/locatorUtils';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';

export class CondaEnvironmentLocator extends Locator {
// Locating conda binary is expensive, since it potentially involves spawning or
Expand Down Expand Up @@ -54,8 +54,12 @@ export class CondaEnvironmentLocator extends Locator {
if (name) {
info.name = name;
}
traceVerbose(`Found conda environment: ${info}`);
yield info;
traceVerbose(`Found conda environment: ${executable}`);
try {
yield info;
} catch (ex) {
traceError(`Failed to process environment: ${executable}`, ex);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { uniq } from 'lodash';
import * as path from 'path';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { chain, iterable } from '../../../../common/utils/async';
import { getUserHomeDir } from '../../../../common/utils/platform';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource } from '../../../base/info';
Expand Down Expand Up @@ -134,12 +134,16 @@ export class CustomVirtualEnvironmentLocator extends FSWatchingLocator {
// python.exe or python in the same directory in the case of virtual
// environments.
if (await looksLikeBasicVirtualPython(entry)) {
// We should extract the kind here to avoid doing is*Environment()
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
const kind = await getVirtualEnvKind(filename);
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Custom Virtual Environment: [added] ${filename}`);
try {
// We should extract the kind here to avoid doing is*Environment()
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
const kind = await getVirtualEnvKind(filename);
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Custom Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
}
} else {
traceVerbose(`Custom Virtual Environment: [skipped] ${filename}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { uniq } from 'lodash';
import * as path from 'path';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { chain, iterable } from '../../../../common/utils/async';
import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource } from '../../../base/info';
Expand Down Expand Up @@ -138,8 +138,12 @@ export class GlobalVirtualEnvironmentLocator extends FSWatchingLocator {
// We don't know the environment type so skip this one.
traceVerbose(`Global Virtual Environment: [skipped] ${filename}`);
} else {
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Global Virtual Environment: [added] ${filename}`);
try {
yield buildSimpleVirtualEnvInfo(filename, kind);
traceVerbose(`Global Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
}
}
} else {
traceVerbose(`Global Virtual Environment: [skipped] ${filename}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { uniq } from 'lodash';
import * as path from 'path';
import { Uri } from 'vscode';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { chain, iterable } from '../../../../common/utils/async';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource } from '../../../base/info';
import { buildEnvInfo } from '../../../base/info/env';
Expand Down Expand Up @@ -118,11 +118,15 @@ export class PoetryLocator extends FSWatchingLocator {
`Poetry Virtual Environment: [skipped] ${filename} (reason: Not poetry environment)`,
);
} else {
// We should extract the kind here to avoid doing is*Environment()
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
yield buildVirtualEnvInfo(filename, kind, undefined, isLocal);
traceVerbose(`Poetry Virtual Environment: [added] ${filename}`);
try {
// We should extract the kind here to avoid doing is*Environment()
// check multiple times. Those checks are file system heavy and
// we can use the kind to determine this anyway.
yield buildVirtualEnvInfo(filename, kind, undefined, isLocal);
traceVerbose(`Poetry Virtual Environment: [added] ${filename}`);
} catch (ex) {
traceError(`Failed to process environment: ${filename}`, ex);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as path from 'path';
import { traceError } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { Architecture } from '../../../../common/utils/platform';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource, PythonReleaseLevel, PythonVersion } from '../../../base/info';
import { buildEnvInfo } from '../../../base/info/env';
Expand All @@ -22,8 +22,14 @@ export class PosixKnownPathsLocator extends Locator {
// the binaries specified in .python-version file in the cwd. We should not be reporting
// those binaries as environments.
const knownDirs = (await commonPosixBinPaths()).filter((dirname) => !isPyenvShimDir(dirname));
const exes = await getPythonBinFromPosixPaths(knownDirs);
yield* exes.map(buildPathEnvInfo);
const pythonBinaries = await getPythonBinFromPosixPaths(knownDirs);
for (const bin of pythonBinaries) {
try {
yield buildPathEnvInfo(bin);
} catch (ex) {
traceError(`Failed to process environment: ${bin}`, ex);
}
}
};
return iterator();
}
Expand All @@ -38,7 +44,7 @@ export class PosixKnownPathsLocator extends Locator {
try {
version = parseVersion(path.basename(bin));
} catch (ex) {
traceError(`Failed to parse version from path: ${bin}`, ex);
traceVerbose(`Failed to parse version from path: ${bin}`, ex);
version = {
major: -1,
minor: -1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { uniq } from 'lodash';
import * as path from 'path';
import { traceError } from '../../../../common/logger';
import { getEnvironmentVariable, getOSType, getUserHomeDir, OSType } from '../../../../common/utils/platform';
import { PythonEnvInfo, PythonEnvKind, PythonEnvSource } from '../../../base/info';
import { buildEnvInfo } from '../../../base/info/env';
Expand Down Expand Up @@ -266,50 +267,53 @@ async function* getPyenvEnvironments(): AsyncIterableIterator<PythonEnvInfo> {
const interpreterPath = await getInterpreterPathFromDir(subDirPath);

if (interpreterPath) {
// The sub-directory name sometimes can contain distro and python versions.
// here we attempt to extract the texts out of the name.
const versionStrings = await parsePyenvVersion(envDirName);

// Here we look for near by files, or config files to see if we can get python version info
// without running python itself.
const pythonVersion = await getPythonVersionFromPath(interpreterPath, versionStrings?.pythonVer);

// Pyenv environments can fall in to these three categories:
// 1. Global Installs : These are environments that are created when you install
// a supported python distribution using `pyenv install <distro>` command.
// These behave similar to globally installed version of python or distribution.
//
// 2. Virtual Envs : These are environments that are created when you use
// `pyenv virtualenv <distro> <env-name>`. These are similar to environments
// created using `python -m venv <env-name>`.
//
// 3. Conda Envs : These are environments that are created when you use
// `pyenv virtualenv <miniconda|anaconda> <env-name>`. These are similar to
// environments created using `conda create -n <env-name>.
//
// All these environments are fully handled by `pyenv` and should be activated using
// `pyenv local|global <env-name>` or `pyenv shell <env-name>`
//
// For the display name we are going to treat these as `pyenv` environments.
const display = `${envDirName}:pyenv`;

const org = versionStrings && versionStrings.distro ? versionStrings.distro : '';

const fileInfo = await getFileInfo(interpreterPath);

const envInfo = buildEnvInfo({
kind: PythonEnvKind.Pyenv,
executable: interpreterPath,
location: subDirPath,
version: pythonVersion,
source: [PythonEnvSource.Pyenv],
display,
org,
fileInfo,
});
envInfo.name = envDirName;

yield envInfo;
try {
// The sub-directory name sometimes can contain distro and python versions.
// here we attempt to extract the texts out of the name.
const versionStrings = await parsePyenvVersion(envDirName);

// Here we look for near by files, or config files to see if we can get python version info
// without running python itself.
const pythonVersion = await getPythonVersionFromPath(interpreterPath, versionStrings?.pythonVer);

// Pyenv environments can fall in to these three categories:
// 1. Global Installs : These are environments that are created when you install
// a supported python distribution using `pyenv install <distro>` command.
// These behave similar to globally installed version of python or distribution.
//
// 2. Virtual Envs : These are environments that are created when you use
// `pyenv virtualenv <distro> <env-name>`. These are similar to environments
// created using `python -m venv <env-name>`.
//
// 3. Conda Envs : These are environments that are created when you use
// `pyenv virtualenv <miniconda|anaconda> <env-name>`. These are similar to
// environments created using `conda create -n <env-name>.
//
// All these environments are fully handled by `pyenv` and should be activated using
// `pyenv local|global <env-name>` or `pyenv shell <env-name>`
//
// For the display name we are going to treat these as `pyenv` environments.
const display = `${envDirName}:pyenv`;

const org = versionStrings && versionStrings.distro ? versionStrings.distro : '';

const fileInfo = await getFileInfo(interpreterPath);

const envInfo = buildEnvInfo({
kind: PythonEnvKind.Pyenv,
executable: interpreterPath,
location: subDirPath,
version: pythonVersion,
source: [PythonEnvSource.Pyenv],
display,
org,
fileInfo,
});
envInfo.name = envDirName;
yield envInfo;
} catch (ex) {
traceError(`Failed to process environment: ${interpreterPath}`, ex);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import { uniq } from 'lodash';
import { traceVerbose } from '../../../../common/logger';
import { traceError, traceVerbose } from '../../../../common/logger';
import { Architecture } from '../../../../common/utils/platform';
import {
PythonEnvInfo,
Expand Down Expand Up @@ -32,7 +32,13 @@ export class WindowsRegistryLocator extends Locator {
const buildRegistryEnvInfo = (data: IRegistryInterpreterData) => this.buildRegistryEnvInfo(data);
const iterator = async function* () {
const interpreters = await getRegistryInterpreters();
yield* interpreters.map(buildRegistryEnvInfo);
for (const interpreter of interpreters) {
try {
yield buildRegistryEnvInfo(interpreter);
} catch (ex) {
traceError(`Failed to process environment: ${interpreter}`, ex);
}
}
};
return iterator();
}
Expand Down