Skip to content

Commit f9c7098

Browse files
jroimartinDonJayamanne
authored andcommitted
Fix issue #569 (#1040)
* Fix issue #569 - Split python interpreter search in paths and virtualenvs - Remove dupplicated venv path checks * Fix possible race condition on suggestionsFromKnownVenvs() * Minor changes
1 parent d65c9c3 commit f9c7098

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

src/client/providers/setInterpreterProvider.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ function getSearchPaths(): Promise<string[]> {
3636
if (localAppData) {
3737
lookupParentDirectories.push(path.join(appData, 'Programs'));
3838
}
39-
if (settings.PythonSettings.getInstance().venvPath) {
40-
lookupParentDirectories.push(settings.PythonSettings.getInstance().venvPath);
41-
}
4239
const dirPromises = lookupParentDirectories.map(rootDir => {
4340
if (!rootDir) {
4441
return Promise.resolve([]);
@@ -69,8 +66,7 @@ function getSearchPaths(): Promise<string[]> {
6966
return validPathsCollection.reduce((previousValue, currentValue) => previousValue.concat(currentValue), []);
7067
});
7168
} else {
72-
let paths = ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/sbin', '/Envs', '/.virtualenvs', '/.pyenv',
73-
'/.pyenv/versions'];
69+
let paths = ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/sbin'];
7470
paths.forEach(p => {
7571
paths.push(untildify('~' + p));
7672
});
@@ -79,12 +75,23 @@ function getSearchPaths(): Promise<string[]> {
7975
paths.push(path.join(process.env['HOME'], 'anaconda', 'bin'));
8076
paths.push(path.join(process.env['HOME'], 'python', 'bin'));
8177
}
82-
if (settings.PythonSettings.getInstance().venvPath) {
83-
paths.push(settings.PythonSettings.getInstance().venvPath);
84-
}
8578
return Promise.resolve(paths);
8679
}
8780
}
81+
function getSearchVenvs(): Promise<string[]> {
82+
let paths = [];
83+
if (!utils.IS_WINDOWS) {
84+
const defaultPaths = ['/Envs', '/.virtualenvs', '/.pyenv', '/.pyenv/versions'];
85+
defaultPaths.forEach(p => {
86+
paths.push(untildify('~' + p));
87+
});
88+
}
89+
const venvPath = settings.PythonSettings.getInstance().venvPath;
90+
if (venvPath) {
91+
paths.push(untildify(venvPath));
92+
}
93+
return Promise.resolve(paths);
94+
}
8895

8996
export function activateSetInterpreterProvider(): vscode.Disposable {
9097
return vscode.commands.registerCommand("python.setInterpreter", setInterpreter);
@@ -104,7 +111,7 @@ function lookForInterpretersInPath(pathToCheck: string): Promise<string[]> {
104111
});
105112
});
106113
}
107-
function lookForInterpretersInVirtualEnvs(pathToCheck: string): Promise<PythonPathSuggestion[]> {
114+
function lookForInterpretersInVenvs(pathToCheck: string): Promise<PythonPathSuggestion[]> {
108115
return new Promise<PythonPathSuggestion[]>(resolve => {
109116
// Now look for Interpreters in this directory
110117
fs.readdir(pathToCheck, (err, subDirs) => {
@@ -168,6 +175,21 @@ function suggestionsFromKnownPaths(): Promise<PythonPathSuggestion[]> {
168175
});
169176
});
170177
}
178+
function suggestionsFromKnownVenvs(): Promise<PythonPathSuggestion[]> {
179+
return getSearchVenvs().then(paths => {
180+
const promises = paths.map(p => {
181+
return lookForInterpretersInVenvs(p);
182+
});
183+
184+
return Promise.all<PythonPathSuggestion[]>(promises).then(listOfInterpreters => {
185+
let suggestions: PythonPathSuggestion[] = [];
186+
listOfInterpreters.forEach(s => {
187+
suggestions.push(...s);
188+
});
189+
return suggestions;
190+
});
191+
});
192+
}
171193
function suggestionsFromConda(): Promise<PythonPathSuggestion[]> {
172194
return new Promise((resolve, reject) => {
173195
// interrogate conda (if it's on the path) to find all environments
@@ -217,15 +239,10 @@ function suggestPythonPaths(): Promise<PythonPathQuickPickItem[]> {
217239
// For now we only interrogate conda for suggestions.
218240
const condaSuggestions = suggestionsFromConda();
219241
const knownPathSuggestions = suggestionsFromKnownPaths();
220-
const workspaceVirtualEnvSuggestions = lookForInterpretersInVirtualEnvs(vscode.workspace.rootPath);
221-
222-
const suggestionPromises = [condaSuggestions, knownPathSuggestions, workspaceVirtualEnvSuggestions];
223-
224-
if (settings.PythonSettings.getInstance().venvPath) {
225-
suggestionPromises.push(lookForInterpretersInVirtualEnvs(settings.PythonSettings.getInstance().venvPath));
226-
}
242+
const knownVenvSuggestions = suggestionsFromKnownVenvs();
243+
const workspaceVirtualEnvSuggestions = lookForInterpretersInVenvs(vscode.workspace.rootPath);
227244

228-
// Here we could also look for virtualenvs/default install locations...
245+
const suggestionPromises = [condaSuggestions, knownPathSuggestions, knownVenvSuggestions, workspaceVirtualEnvSuggestions];
229246

230247
return Promise.all<PythonPathSuggestion[]>(suggestionPromises).then(suggestions => {
231248
const quickPicks: PythonPathQuickPickItem[] = [];

0 commit comments

Comments
 (0)