Skip to content

Commit

Permalink
Fix issue #569 (#1040)
Browse files Browse the repository at this point in the history
* Fix issue #569

- Split python interpreter search in paths and virtualenvs
- Remove dupplicated venv path checks

* Fix possible race condition on suggestionsFromKnownVenvs()

* Minor changes
  • Loading branch information
jroimartin authored and DonJayamanne committed Jun 26, 2017
1 parent d65c9c3 commit f9c7098
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions src/client/providers/setInterpreterProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ function getSearchPaths(): Promise<string[]> {
if (localAppData) {
lookupParentDirectories.push(path.join(appData, 'Programs'));
}
if (settings.PythonSettings.getInstance().venvPath) {
lookupParentDirectories.push(settings.PythonSettings.getInstance().venvPath);
}
const dirPromises = lookupParentDirectories.map(rootDir => {
if (!rootDir) {
return Promise.resolve([]);
Expand Down Expand Up @@ -69,8 +66,7 @@ function getSearchPaths(): Promise<string[]> {
return validPathsCollection.reduce((previousValue, currentValue) => previousValue.concat(currentValue), []);
});
} else {
let paths = ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/sbin', '/Envs', '/.virtualenvs', '/.pyenv',
'/.pyenv/versions'];
let paths = ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/sbin'];
paths.forEach(p => {
paths.push(untildify('~' + p));
});
Expand All @@ -79,12 +75,23 @@ function getSearchPaths(): Promise<string[]> {
paths.push(path.join(process.env['HOME'], 'anaconda', 'bin'));
paths.push(path.join(process.env['HOME'], 'python', 'bin'));
}
if (settings.PythonSettings.getInstance().venvPath) {
paths.push(settings.PythonSettings.getInstance().venvPath);
}
return Promise.resolve(paths);
}
}
function getSearchVenvs(): Promise<string[]> {
let paths = [];
if (!utils.IS_WINDOWS) {
const defaultPaths = ['/Envs', '/.virtualenvs', '/.pyenv', '/.pyenv/versions'];
defaultPaths.forEach(p => {
paths.push(untildify('~' + p));
});
}
const venvPath = settings.PythonSettings.getInstance().venvPath;
if (venvPath) {
paths.push(untildify(venvPath));
}
return Promise.resolve(paths);
}

export function activateSetInterpreterProvider(): vscode.Disposable {
return vscode.commands.registerCommand("python.setInterpreter", setInterpreter);
Expand All @@ -104,7 +111,7 @@ function lookForInterpretersInPath(pathToCheck: string): Promise<string[]> {
});
});
}
function lookForInterpretersInVirtualEnvs(pathToCheck: string): Promise<PythonPathSuggestion[]> {
function lookForInterpretersInVenvs(pathToCheck: string): Promise<PythonPathSuggestion[]> {
return new Promise<PythonPathSuggestion[]>(resolve => {
// Now look for Interpreters in this directory
fs.readdir(pathToCheck, (err, subDirs) => {
Expand Down Expand Up @@ -168,6 +175,21 @@ function suggestionsFromKnownPaths(): Promise<PythonPathSuggestion[]> {
});
});
}
function suggestionsFromKnownVenvs(): Promise<PythonPathSuggestion[]> {
return getSearchVenvs().then(paths => {
const promises = paths.map(p => {
return lookForInterpretersInVenvs(p);
});

return Promise.all<PythonPathSuggestion[]>(promises).then(listOfInterpreters => {
let suggestions: PythonPathSuggestion[] = [];
listOfInterpreters.forEach(s => {
suggestions.push(...s);
});
return suggestions;
});
});
}
function suggestionsFromConda(): Promise<PythonPathSuggestion[]> {
return new Promise((resolve, reject) => {
// interrogate conda (if it's on the path) to find all environments
Expand Down Expand Up @@ -217,15 +239,10 @@ function suggestPythonPaths(): Promise<PythonPathQuickPickItem[]> {
// For now we only interrogate conda for suggestions.
const condaSuggestions = suggestionsFromConda();
const knownPathSuggestions = suggestionsFromKnownPaths();
const workspaceVirtualEnvSuggestions = lookForInterpretersInVirtualEnvs(vscode.workspace.rootPath);

const suggestionPromises = [condaSuggestions, knownPathSuggestions, workspaceVirtualEnvSuggestions];

if (settings.PythonSettings.getInstance().venvPath) {
suggestionPromises.push(lookForInterpretersInVirtualEnvs(settings.PythonSettings.getInstance().venvPath));
}
const knownVenvSuggestions = suggestionsFromKnownVenvs();
const workspaceVirtualEnvSuggestions = lookForInterpretersInVenvs(vscode.workspace.rootPath);

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

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

0 comments on commit f9c7098

Please sign in to comment.