Skip to content

Commit a1d812e

Browse files
authored
Fix: Validate existence of pipenv, poetry, and pyenv paths before usage (#1004)
Fixes the problem where we show Poetry even though poetry is not installed: <img width="386" height="249" alt="image" src="https://github.com/user-attachments/assets/6cca6e64-a8c0-4903-900b-588493dddbad" />
1 parent 889a2c2 commit a1d812e

File tree

3 files changed

+49
-23
lines changed

3 files changed

+49
-23
lines changed

src/managers/pipenv/pipenvUtils.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Utility functions for Pipenv environment management
22

3+
import * as fs from 'fs-extra';
34
import * as path from 'path';
45
import { Uri } from 'vscode';
56
import which from 'which';
@@ -13,6 +14,7 @@ import {
1314
import { ENVS_EXTENSION_ID } from '../../common/constants';
1415
import { traceError, traceInfo } from '../../common/logging';
1516
import { getWorkspacePersistentState } from '../../common/persistentState';
17+
import { untildify } from '../../common/utils/pathUtils';
1618
import { getSettingWorkspaceScope } from '../../features/settings/settingHelpers';
1719
import {
1820
isNativeEnvInfo,
@@ -54,22 +56,32 @@ function getPipenvPathFromSettings(): string | undefined {
5456

5557
export async function getPipenv(native?: NativePythonFinder): Promise<string | undefined> {
5658
if (pipenvPath) {
57-
return pipenvPath;
59+
if (await fs.exists(untildify(pipenvPath))) {
60+
return untildify(pipenvPath);
61+
}
62+
pipenvPath = undefined;
5863
}
5964

6065
const state = await getWorkspacePersistentState();
61-
pipenvPath = await state.get<string>(PIPENV_PATH_KEY);
62-
if (pipenvPath) {
63-
traceInfo(`Using pipenv from persistent state: ${pipenvPath}`);
64-
return pipenvPath;
66+
const storedPath = await state.get<string>(PIPENV_PATH_KEY);
67+
if (storedPath) {
68+
if (await fs.exists(untildify(storedPath))) {
69+
pipenvPath = storedPath;
70+
traceInfo(`Using pipenv from persistent state: ${pipenvPath}`);
71+
return untildify(pipenvPath);
72+
}
73+
await state.set(PIPENV_PATH_KEY, undefined);
6574
}
6675

6776
// try to get from settings
6877
const settingPath = getPipenvPathFromSettings();
6978
if (settingPath) {
70-
pipenvPath = settingPath;
71-
traceInfo(`Using pipenv from settings: ${settingPath}`);
72-
return pipenvPath;
79+
if (await fs.exists(untildify(settingPath))) {
80+
pipenvPath = settingPath;
81+
traceInfo(`Using pipenv from settings: ${settingPath}`);
82+
return untildify(pipenvPath);
83+
}
84+
traceInfo(`Pipenv path from settings does not exist: ${settingPath}`);
7385
}
7486

7587
// Try to find pipenv in PATH

src/managers/poetry/poetryUtils.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,27 @@ export async function setPoetryForWorkspaces(fsPath: string[], envPath: string |
9999

100100
export async function getPoetry(native?: NativePythonFinder): Promise<string | undefined> {
101101
if (poetryPath) {
102-
return poetryPath;
102+
if (await fs.exists(untildify(poetryPath))) {
103+
return untildify(poetryPath);
104+
}
105+
poetryPath = undefined;
103106
}
104107

105108
const state = await getWorkspacePersistentState();
106-
poetryPath = await state.get<string>(POETRY_PATH_KEY);
107-
if (poetryPath) {
108-
traceInfo(`Using poetry from persistent state: ${poetryPath}`);
109-
// Also retrieve the virtualenvs path if we haven't already
110-
if (!poetryVirtualenvsPath) {
111-
getPoetryVirtualenvsPath(untildify(poetryPath)).catch((e) =>
112-
traceError(`Error getting Poetry virtualenvs path: ${e}`),
113-
);
109+
const storedPath = await state.get<string>(POETRY_PATH_KEY);
110+
if (storedPath) {
111+
if (await fs.exists(untildify(storedPath))) {
112+
poetryPath = storedPath;
113+
traceInfo(`Using poetry from persistent state: ${poetryPath}`);
114+
// Also retrieve the virtualenvs path if we haven't already
115+
if (!poetryVirtualenvsPath) {
116+
getPoetryVirtualenvsPath(untildify(poetryPath)).catch((e) =>
117+
traceError(`Error getting Poetry virtualenvs path: ${e}`),
118+
);
119+
}
120+
return untildify(poetryPath);
114121
}
115-
return untildify(poetryPath);
122+
await state.set(POETRY_PATH_KEY, undefined);
116123
}
117124

118125
// Check in standard PATH locations

src/managers/pyenv/pyenvUtils.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,21 @@ export async function setPyenvForWorkspaces(fsPath: string[], envPath: string |
9898

9999
export async function getPyenv(native?: NativePythonFinder): Promise<string | undefined> {
100100
if (pyenvPath) {
101-
return pyenvPath;
101+
if (await fs.exists(untildify(pyenvPath))) {
102+
return untildify(pyenvPath);
103+
}
104+
pyenvPath = undefined;
102105
}
103106

104107
const state = await getWorkspacePersistentState();
105-
pyenvPath = await state.get<string>(PYENV_PATH_KEY);
106-
if (pyenvPath) {
107-
traceInfo(`Using pyenv from persistent state: ${pyenvPath}`);
108-
return untildify(pyenvPath);
108+
const storedPath = await state.get<string>(PYENV_PATH_KEY);
109+
if (storedPath) {
110+
if (await fs.exists(untildify(storedPath))) {
111+
pyenvPath = storedPath;
112+
traceInfo(`Using pyenv from persistent state: ${pyenvPath}`);
113+
return untildify(pyenvPath);
114+
}
115+
await state.set(PYENV_PATH_KEY, undefined);
109116
}
110117

111118
const pyenvBin = isWindows() ? 'pyenv.exe' : 'pyenv';

0 commit comments

Comments
 (0)