-
Notifications
You must be signed in to change notification settings - Fork 92
fix: use run.executable for interpreter identification instead of activatedRun.executable
#949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…reter identification getInterpreterDetails, getSettingsPythonPath, and getExecutableCommand need the actual Python binary path, not the activated run command. Using activatedRun.executable breaks when environment managers set it to a wrapper command (e.g. pixi run ... python). This unblocks managers like conda and pixi from using wrapper commands in activatedRun without breaking the debugger, while remaining backwards-compatible since the two values are currently identical for all existing managers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Updates interpreter identification in the debugger integration to consistently use execInfo.run.executable (the actual Python interpreter) rather than execInfo.activatedRun.executable (which may be a wrapper command), addressing activation/wrapper scenarios like pixi (vscode-python-environments#987 / vscode-python-debugger#872).
Changes:
- Use
execInfo.run.executablewhen selecting the debug adapter’s Python executable. - Use
execInfo.run.executablewhen computing interpreter details and settings-based Python path for debug configuration resolution.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/extension/debugger/adapter/factory.ts |
Ensures debug adapter launch uses run.executable only. |
src/extension/common/python.ts |
Ensures interpreter discovery/settings resolution uses run.executable only. |
Comments suppressed due to low confidence (2)
src/extension/common/python.ts:142
- Behavior change: getSettingsPythonPath now always returns execInfo.run (ignoring activatedRun). Please add/update a unit test where execInfo.activatedRun points to a wrapper command and execInfo.run points to the actual Python executable to verify the returned command uses run.* as intended.
This issue also appears on line 255 of the same file.
const runConfig = execInfo.run;
traceLog(
`getSettingsPythonPath: Using executable='${runConfig.executable}' args='${
runConfig.args?.join(' ') || ''
}'`,
);
return runConfig.args ? [runConfig.executable, ...runConfig.args] : [runConfig.executable];
src/extension/common/python.ts:265
- Behavior change: getInterpreterDetails now always reads resolvedEnv.execInfo.run.executable. Please add a unit test that simulates resolvedEnv.execInfo.activatedRun.executable being a wrapper command while run.executable is the true interpreter path, and assert that the returned IInterpreterDetails.path uses run.executable.
const env: PythonEnvironment | undefined = await api.getEnvironment(resource);
// resolve the environment to get full details
const resolvedEnv = env ? await api.resolveEnvironment(env?.environmentPath) : undefined;
const executablePath = resolvedEnv?.execInfo.run.executable;
const a: IInterpreterDetails = {
path: executablePath ? [executablePath] : undefined,
resource,
};
traceLog(`getInterpreterDetails: resource='${resource?.fsPath}' executable='${executablePath}'`);
return a;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private async getExecutableCommand(interpreter: PythonEnvironment | undefined): Promise<string[]> { | ||
| if (interpreter) { | ||
| const executablePath = interpreter.execInfo.activatedRun?.executable ?? interpreter.execInfo.run.executable; | ||
| const executablePath = interpreter.execInfo.run.executable; | ||
| const version = interpreter.version; | ||
|
|
||
| // Parse version string (e.g., "3.8.10" -> major: 3, minor: 8) |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Behavior change: this now always uses execInfo.run.executable and ignores activatedRun entirely. Please add/adjust a unit test covering an environment where activatedRun.executable is a wrapper command (e.g., 'pixi') while run.executable is the real Python binary, to ensure the debug adapter is launched with the real interpreter and to prevent regressions.
|
We have some conflicting documentation on this so let me confirm desired behavior and then make updates. This makes sense to me and I really appreciate you investigating in such detail!! |
|
Yep confirmed you have the right ideas here using run not activatedRun. Thanks for catching this. Will get this merged then add a PR with testing |
Fixes microsoft/vscode-python-environments#987
Hi @eleanorjboyd. I saw you merged test discovery 2.0 and was very excited to test it. I still have environment activation issues after that PR was merged, so I decided to investigate it a bit further. I'd appreciate it if you could review this PR.
The debugger reads
activatedRun.executablein three places to figure out which Python binary to use. This works today because every environment manager happens to setactivatedRun.executableto the actual Python path, but it breaks when a manager sets it to a wrapper command (likepixi run ... pythonor how conda used to doconda run ... pythonbefore microsoft/vscode-python-environments#860).I believe the three call sites (
getInterpreterDetails,getSettingsPythonPath,getExecutableCommand) aren't running Python, they're identifying the interpreter for things likeresolveEnvironment()and spawning the debug adapter. And I think that's whatrun.executableis for.activatedRunis for execution contexts likerunInBackgroundin vscode-python-environments.The change should be backwards compatible since
run.executableandactivatedRun.executableare currently the same value for all existing managers (venv, system, conda). It only matters when they differ, which is the case for pixi-code (see microsoft/vscode-python-environments#987 and #872).Debuggee activation is not affected, that still goes through
getActivatedEnvironmentVariables()and terminalenvVarCollection.This unblocks environment managers from setting
activatedRunto a wrapper command likepixi run ... python, which is needed to fix pytest discovery not activating the environment (microsoft/vscode-python-environments#987). Right nowrunInBackground(used by test discovery) relies onactivatedRunfor execution, but managers can't set it to anything other than the bare Python path without breaking the debugger.