Skip to content

Commit ec5d69d

Browse files
committed
#1147 check exitence of interpreters when listing them
1 parent b9f6d09 commit ec5d69d

20 files changed

Lines changed: 176 additions & 347 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,7 @@
14751475
"anser": "^1.1.0",
14761476
"copy-paste": "^1.3.0",
14771477
"diff-match-patch": "^1.0.0",
1478-
"fs-extra": "^0.30.0",
1478+
"fs-extra": "^4.0.2",
14791479
"fuzzy": "^0.1.3",
14801480
"line-by-line": "^0.1.5",
14811481
"lodash": "^4.17.4",
@@ -1501,6 +1501,7 @@
15011501
"xml2js": "^0.4.17"
15021502
},
15031503
"devDependencies": {
1504+
"@types/fs-extra": "^4.0.2",
15041505
"@types/jquery": "^1.10.31",
15051506
"@types/lodash": "^4.14.74",
15061507
"@types/mocha": "^2.2.32",

src/client/interpreter/sources/providers/condaEnvProvider.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"use strict";
22
import * as child_process from 'child_process';
3+
import * as fs from 'fs-extra';
34
import * as path from 'path';
45
import { IInterpreterProvider, PythonInterpreter } from '../contracts';
5-
import { IS_WINDOWS, fsExistsAsync } from "../../../common/utils";
6+
import { IS_WINDOWS } from "../../../common/utils";
67
import { VersionUtils } from "../../../common/versionUtils";
78

89
// where to find the Python binary within a conda env
@@ -11,9 +12,9 @@ const AnacondaCompanyName = 'Continuum Analytics, Inc.';
1112
const AnacondaDisplayName = 'Anaconda';
1213

1314
type CondaInfo = {
14-
envs: string[];
15-
"sys.version": string;
16-
default_prefix: string;
15+
envs?: string[];
16+
"sys.version"?: string;
17+
default_prefix?: string;
1718
}
1819
export class CondaEnvProvider implements IInterpreterProvider {
1920
constructor(private registryLookupForConda?: IInterpreterProvider) {
@@ -53,10 +54,10 @@ export class CondaEnvProvider implements IInterpreterProvider {
5354
.then(interpreters => interpreters.filter(this.isCondaEnvironment))
5455
.then(condaInterpreters => this.getLatestVersion(condaInterpreters))
5556
.then(condaInterpreter => {
56-
return condaInterpreter ? path.join(path.dirname(condaInterpreter.path), 'Scripts', 'conda.exe') : 'conda';
57+
return condaInterpreter ? path.join(path.dirname(condaInterpreter.path), 'conda.exe') : 'conda';
5758
})
5859
.then(condaPath => {
59-
return fsExistsAsync(condaPath).then(exists => exists ? condaPath : 'conda');
60+
return fs.pathExists(condaPath).then(exists => exists ? condaPath : 'conda');
6061
});
6162
}
6263
return Promise.resolve('conda');
@@ -74,27 +75,31 @@ export class CondaEnvProvider implements IInterpreterProvider {
7475
}
7576
public async parseCondaInfo(info: CondaInfo) {
7677
// "sys.version": "3.6.1 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]",
77-
const displayName = this.getDisplayNameFromVersionInfo(info['sys.version']);
78+
const displayName = this.getDisplayNameFromVersionInfo(info['sys.version'] || '');
7879

7980
// The root of the conda environment is itself a Python interpreter
8081
// envs reported as e.g.: /Users/bob/miniconda3/envs/someEnv
81-
const envs = info.envs || [];
82+
const envs = Array.isArray(info.envs) ? info.envs : [];
8283
if (info.default_prefix && info.default_prefix.length > 0) {
8384
envs.push(info.default_prefix);
8485
}
8586

86-
return envs.map(env => {
87-
const interpreter: PythonInterpreter = { path: path.join(env, ...CONDA_RELATIVE_PY_PATH) };
88-
if (env === info.default_prefix) {
89-
interpreter.displayName = displayName;
90-
}
91-
else {
92-
// This is an environment, hence suffix with env name
93-
interpreter.displayName = `${displayName} (${path.basename(env)})`; // e.g. someEnv, miniconda3
94-
}
95-
interpreter.companyDisplayName = AnacondaCompanyName;
96-
return interpreter;
97-
});
87+
const promises = envs
88+
.map(env => {
89+
// If it is an environment, hence suffix with env name
90+
const interpreterDisplayName = env === info.default_prefix ? displayName : `${displayName} (${path.basename(env)})`;
91+
const interpreter: PythonInterpreter = {
92+
path: path.join(env, ...CONDA_RELATIVE_PY_PATH),
93+
displayName: interpreterDisplayName,
94+
companyDisplayName: AnacondaCompanyName
95+
};
96+
return interpreter;
97+
})
98+
.map(env => fs.pathExists(env.path).then(exists => exists ? env : null));
99+
100+
return Promise.all(promises)
101+
.then(interpreters => interpreters.filter(interpreter => interpreter !== null && interpreter !== undefined))
102+
.then(interpreters => interpreters.map(interpreter => interpreter!));
98103
}
99104
private getDisplayNameFromVersionInfo(versionInfo: string = '') {
100105
if (!versionInfo) {

src/client/interpreter/sources/providers/windowsRegistryProvider.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { Architecture, Hive, IRegistry } from '../../../common/registry';
2-
import { IInterpreterProvider } from '../contracts';
31
import * as path from 'path';
42
import * as _ from 'lodash';
3+
import * as fs from 'fs-extra';
4+
import { Architecture, Hive, IRegistry } from '../../../common/registry';
5+
import { IInterpreterProvider } from '../contracts';
56
import { PythonInterpreter } from '../index';
67

78
const DefaultPythonExecutable = 'python.exe';
@@ -108,6 +109,7 @@ export class WindowsRegistryProvider implements IInterpreterProvider {
108109
companyDisplayName: interpreterInfo.companyDisplayName
109110
} as PythonInterpreter;
110111
})
112+
.then(interpreter => interpreter ? fs.pathExists(interpreter.path).then(exists => exists ? interpreter : null) : null)
111113
.catch(error => {
112114
console.error(`Failed to retrieve interpreter details for company ${companyKey},tag: ${tagKey}, hive: ${hive}, arch: ${arch}`);
113115
console.error(error);

0 commit comments

Comments
 (0)