Skip to content

Commit 796e8cb

Browse files
Fix conda copy interpreter path to use actual Python executable instead of conda run command (#721)
When clicking the "Copy Environment Path" button on conda environments, the extension was incorrectly copying the conda run command instead of the actual Python interpreter path. ``` # What was being copied (incorrect): conda run --name base python # What users expected (correct): /opt/conda/envs/base/bin/python ``` ## Solution Modified the `copyPathToClipboard` function to use `run.executable` directly, which provides the actual Python interpreter path instead of constructing a command from `activatedRun Fixes #720. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com>
1 parent 46c01ec commit 796e8cb

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

src/features/envCommands.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
} from '../common/pickers/managers';
3131
import { pickProject, pickProjectMany } from '../common/pickers/projects';
3232
import { activeTextEditor, showErrorMessage, showInformationMessage } from '../common/window.apis';
33-
import { quoteArgs } from './execution/execUtils';
3433
import { runAsTask } from './execution/runAsTask';
3534
import { runInTerminal } from './terminal/runInTerminal';
3635
import { TerminalManager } from './terminal/terminalManager';
@@ -638,8 +637,8 @@ export async function copyPathToClipboard(item: unknown): Promise<void> {
638637
await clipboardWriteText(projectPath);
639638
traceInfo(`Copied project path to clipboard: ${projectPath}`);
640639
} else if (item instanceof ProjectEnvironment || item instanceof PythonEnvTreeItem) {
641-
const run = item.environment.execInfo.activatedRun ?? item.environment.execInfo.run;
642-
const envPath = quoteArgs([run.executable, ...(run.args ?? [])]).join(' ');
640+
const run = item.environment.execInfo.run;
641+
const envPath = run.executable;
643642
await clipboardWriteText(envPath);
644643
traceInfo(`Copied environment path to clipboard: ${envPath}`);
645644
} else {

src/test/features/commands/copyPathToClipboard.unit.test.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as sinon from 'sinon';
2+
import { Uri } from 'vscode';
3+
import { PythonEnvironment } from '../../../api';
24
import * as envApis from '../../../common/env.apis';
35
import { copyPathToClipboard } from '../../../features/envCommands';
46
import {
5-
ProjectItem,
7+
EnvManagerTreeItem,
68
ProjectEnvironment,
9+
ProjectItem,
710
PythonEnvTreeItem,
8-
EnvManagerTreeItem,
911
} from '../../../features/views/treeViewItems';
10-
import { Uri } from 'vscode';
11-
import { PythonEnvironment } from '../../../api';
1212
import { InternalEnvironmentManager } from '../../../internal.api';
1313

1414
suite('Copy Path To Clipboard', () => {
@@ -45,7 +45,7 @@ suite('Copy Path To Clipboard', () => {
4545
await copyPathToClipboard(item);
4646

4747
sinon.assert.calledOnce(clipboardWriteTextStub);
48-
sinon.assert.calledWith(clipboardWriteTextStub, '/test-env/bin/test -m env');
48+
sinon.assert.calledWith(clipboardWriteTextStub, '/test-env/bin/test');
4949
});
5050

5151
test('Copy env path to clipboard: env manager view', async () => {
@@ -63,6 +63,56 @@ suite('Copy Path To Clipboard', () => {
6363
await copyPathToClipboard(item);
6464

6565
sinon.assert.calledOnce(clipboardWriteTextStub);
66-
sinon.assert.calledWith(clipboardWriteTextStub, '/test-env/bin/test -m env');
66+
sinon.assert.calledWith(clipboardWriteTextStub, '/test-env/bin/test');
67+
});
68+
69+
test('Copy conda env path to clipboard: should copy interpreter path not conda run command', async () => {
70+
const item = new PythonEnvTreeItem(
71+
{
72+
envId: { managerId: 'conda', id: 'base' },
73+
name: 'base',
74+
displayName: 'base (3.12.2)',
75+
displayPath: '/opt/conda/envs/base',
76+
execInfo: {
77+
run: { executable: '/opt/conda/envs/base/bin/python' },
78+
activatedRun: {
79+
executable: 'conda',
80+
args: ['run', '--name', 'base', 'python'],
81+
},
82+
},
83+
} as PythonEnvironment,
84+
new EnvManagerTreeItem({ name: 'conda', id: 'conda' } as InternalEnvironmentManager),
85+
);
86+
87+
await copyPathToClipboard(item);
88+
89+
sinon.assert.calledOnce(clipboardWriteTextStub);
90+
// Should copy the actual interpreter path, not the conda run command
91+
sinon.assert.calledWith(clipboardWriteTextStub, '/opt/conda/envs/base/bin/python');
92+
});
93+
94+
test('Copy conda prefix env path to clipboard: should copy interpreter path not conda run command', async () => {
95+
const item = new PythonEnvTreeItem(
96+
{
97+
envId: { managerId: 'conda', id: 'myenv' },
98+
name: 'myenv',
99+
displayName: 'myenv (3.11.5)',
100+
displayPath: '/opt/conda/envs/myenv',
101+
execInfo: {
102+
run: { executable: '/opt/conda/envs/myenv/bin/python' },
103+
activatedRun: {
104+
executable: 'conda',
105+
args: ['run', '--prefix', '/opt/conda/envs/myenv', 'python'],
106+
},
107+
},
108+
} as PythonEnvironment,
109+
new EnvManagerTreeItem({ name: 'conda', id: 'conda' } as InternalEnvironmentManager),
110+
);
111+
112+
await copyPathToClipboard(item);
113+
114+
sinon.assert.calledOnce(clipboardWriteTextStub);
115+
// Should copy the actual interpreter path, not the conda run command
116+
sinon.assert.calledWith(clipboardWriteTextStub, '/opt/conda/envs/myenv/bin/python');
67117
});
68118
});

0 commit comments

Comments
 (0)