Skip to content

Commit 02d713a

Browse files
Fix select interpreter (#601)
This PR enhances the "Select Interpreter" dropdown in the Python Environments extension by including the full path to each interpreter in the description text, making it easier for users to identify and distinguish between different Python environments. (copilot did this via eleanorjboyd#1 but the PR was created wrong) fixes #593 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent ba660ad commit 02d713a

2 files changed

Lines changed: 111 additions & 8 deletions

File tree

src/common/pickers/environments.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,20 @@ export async function pickEnvironment(
157157
];
158158

159159
if (options?.recommended) {
160+
const pathDescription = options.recommended.displayPath;
161+
const description =
162+
options.recommended.description && options.recommended.description.trim()
163+
? `${options.recommended.description} (${pathDescription})`
164+
: pathDescription;
165+
160166
items.push(
161167
{
162168
label: Common.recommended,
163169
kind: QuickPickItemKind.Separator,
164170
},
165171
{
166172
label: options.recommended.displayName,
167-
description: options.recommended.description,
173+
description: description,
168174
result: options.recommended,
169175
iconPath: getIconPath(options.recommended.iconPath),
170176
},
@@ -179,9 +185,13 @@ export async function pickEnvironment(
179185
const envs = await manager.getEnvironments('all');
180186
items.push(
181187
...envs.map((e) => {
188+
const pathDescription = e.displayPath;
189+
const description =
190+
e.description && e.description.trim() ? `${e.description} (${pathDescription})` : pathDescription;
191+
182192
return {
183193
label: e.displayName ?? e.name,
184-
description: e.description,
194+
description: description,
185195
result: e,
186196
manager: manager,
187197
iconPath: getIconPath(e.iconPath),
@@ -194,12 +204,18 @@ export async function pickEnvironment(
194204
}
195205

196206
export async function pickEnvironmentFrom(environments: PythonEnvironment[]): Promise<PythonEnvironment | undefined> {
197-
const items = environments.map((e) => ({
198-
label: e.displayName ?? e.name,
199-
description: e.description,
200-
e: e,
201-
iconPath: getIconPath(e.iconPath),
202-
}));
207+
const items = environments.map((e) => {
208+
const pathDescription = e.displayPath;
209+
const description =
210+
e.description && e.description.trim() ? `${e.description} (${pathDescription})` : pathDescription;
211+
212+
return {
213+
label: e.displayName ?? e.name,
214+
description: description,
215+
e: e,
216+
iconPath: getIconPath(e.iconPath),
217+
};
218+
});
203219
const selected = await showQuickPick(items, {
204220
placeHolder: Pickers.Environments.selectEnvironment,
205221
ignoreFocusOut: true,
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import assert from 'node:assert';
5+
import { Uri } from 'vscode';
6+
import { PythonEnvironment } from '../../api';
7+
8+
/**
9+
* Test the logic used in environment pickers to include interpreter paths in descriptions
10+
*/
11+
suite('Environment Picker Description Logic', () => {
12+
const createMockEnvironment = (
13+
displayPath: string,
14+
description?: string,
15+
name: string = 'Python 3.9.0',
16+
): PythonEnvironment => ({
17+
envId: { id: 'test', managerId: 'test-manager' },
18+
name,
19+
displayName: name,
20+
displayPath,
21+
version: '3.9.0',
22+
environmentPath: Uri.file(displayPath),
23+
description,
24+
sysPrefix: '/path/to/prefix',
25+
execInfo: { run: { executable: displayPath } },
26+
});
27+
28+
suite('Description formatting with interpreter path', () => {
29+
test('should use displayPath as description when no original description exists', () => {
30+
const env = createMockEnvironment('/usr/local/bin/python');
31+
32+
// This is the logic from our updated picker
33+
const pathDescription = env.displayPath;
34+
const description =
35+
env.description && env.description.trim() ? `${env.description} (${pathDescription})` : pathDescription;
36+
37+
assert.strictEqual(description, '/usr/local/bin/python');
38+
});
39+
40+
test('should append displayPath to existing description in parentheses', () => {
41+
const env = createMockEnvironment('/home/user/.venv/bin/python', 'Virtual Environment');
42+
43+
// This is the logic from our updated picker
44+
const pathDescription = env.displayPath;
45+
const description =
46+
env.description && env.description.trim() ? `${env.description} (${pathDescription})` : pathDescription;
47+
48+
assert.strictEqual(description, 'Virtual Environment (/home/user/.venv/bin/python)');
49+
});
50+
51+
test('should handle complex paths correctly', () => {
52+
const complexPath = '/usr/local/anaconda3/envs/my-project-env/bin/python';
53+
const env = createMockEnvironment(complexPath, 'Conda Environment');
54+
55+
// This is the logic from our updated picker
56+
const pathDescription = env.displayPath;
57+
const description =
58+
env.description && env.description.trim() ? `${env.description} (${pathDescription})` : pathDescription;
59+
60+
assert.strictEqual(description, `Conda Environment (${complexPath})`);
61+
});
62+
63+
test('should handle empty description correctly', () => {
64+
const env = createMockEnvironment('/opt/python/bin/python', '');
65+
66+
// This is the logic from our updated picker
67+
const pathDescription = env.displayPath;
68+
const description =
69+
env.description && env.description.trim() ? `${env.description} (${pathDescription})` : pathDescription;
70+
71+
// Empty string should be treated like no description, so just use path
72+
assert.strictEqual(description, '/opt/python/bin/python');
73+
});
74+
75+
test('should handle Windows paths correctly', () => {
76+
const windowsPath = 'C:\\Python39\\python.exe';
77+
const env = createMockEnvironment(windowsPath, 'System Python');
78+
79+
// This is the logic from our updated picker
80+
const pathDescription = env.displayPath;
81+
const description =
82+
env.description && env.description.trim() ? `${env.description} (${pathDescription})` : pathDescription;
83+
84+
assert.strictEqual(description, 'System Python (C:\\Python39\\python.exe)');
85+
});
86+
});
87+
});

0 commit comments

Comments
 (0)