Terminal activation emits `source <prefix>/bin/activate` for uv-managed toolchains that have no activate script

Aperta
#1,775 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python, typescript, vscode

Direzione di ricerca

Inizia individuando getShellActivationCommands e isActivatableEnvironment, quindi segui la chiamata dirname(executable) per gli interpreti gestiti da uv. Riproduci il problema con una toolchain uv python install e verifica che gli ambienti privi di bin/activate non emettano alcun comando di attivazione, mentre i veri ambienti virtuali continuino ad attivarsi correttamente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

triage-needed

Environment

Extension ms-python.vscode-python-envs 1.36.0 (also present in 1.37.2026090401, published 2026-09-04)
VS Code 1.137.0
OS macOS 15.6 (arm64)
Shell zsh
Environment manager uv (plus ms-python.python:system for comparison)

Steps to reproduce

  1. uv python install 3.13 — installs a toolchain to ~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/.
  2. Open a folder in VS Code whose selected interpreter is that toolchain:
    Ctrl/Cmd+Shift+PPython: Select InterpreterEnter interpreter path…
    ~/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/python
  3. Open an integrated terminal.

Actual behavior

source /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/activate
source: no such file or directory: /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/activate

The toolchain's bin/ contains python3.13, python, pip, idle3 — there is no activate.
A uv python install toolchain is a base interpreter, not a virtual environment, so the failure
is not a broken install: the activation command itself should never have been emitted.

Once persisted, the same command is emitted on every new terminal in that folder and
survives restarts — this is not a one-off.

Python Environments log for the same window:

[interpreterSelection] deven367: cpython-3.13.9-macos-aarch64-none (3.13.9) (source: autoDiscovery)
Terminal is activated: /Users/<user>/.local/share/uv/python/cpython-3.13.9-macos-aarch64-none/bin/python

(The extension also auto-discovered and selected this toolchain for a folder with no
environment at all, with no user selection — same outcome.)

Expected behavior

No activation command is emitted for an environment that cannot be activated; either the
toolchain is reported as non-activatable (like system environments, which correctly emit
nothing), or the activation command is gated on the activation script existing.

Cause

getShellActivationCommands(dir) sets the sh/bash/zsh/gitbash (and "unknown") activation
entries unconditionally, while fish/csh/xsh/nu are gated on pathExists:

t.getShellActivationCommands = async function (e) {
  const t = new Map(), n = new Map();
  return isWindows()
    ? t.set("unknown", [{ executable: join(e, "activate") }])
    : t.set("unknown", [{ executable: "source", args: [join(e, "activate")] }]),   // no pathExists
  t.set(SH,      [{ executable: "source", args: [join(e, "activate")] }]),         // no pathExists
  t.set(BASH,    [{ executable: "source", args: [join(e, "activate")] }]),         // no pathExists
  t.set(GITBASH, [{ executable: "source", args: [v(join(e, "activate"))] }]),      // no pathExists
  t.set(ZSH,     [{ executable: "source", args: [join(e, "activate")] }]),         // no pathExists
  ...
  await pathExists(join(e, "activate.csh")) && t.set(CSH, ...);                    // gated
  await pathExists(join(e, "activate.fish")) && t.set(FISH, ...);                  // gated
  await pathExists(join(e, "activate.xsh"))  && t.set(XSH, ...);                   // gated
  await pathExists(join(e, "activate.nu"))   && t.set(NU, ...);                    // gated
  return { shellActivation: t, shellDeactivation: n };
};

It is called with dirname(executable), i.e. <prefix>/bin:

const a = dirname(e.executable),
      { shellActivation: o, shellDeactivation: s } = await getShellActivationCommands(a);

So for any prefix without bin/activate, a failing command is produced instead of an
environment with no activation. isActivatableEnvironment() then returns true, because it
only checks that shellActivation is non-empty:

t.isActivatableEnvironment = function (e) {
  return !!e.execInfo?.activation || !!e.execInfo?.shellActivation;
};

The uv manager registers these toolchains through the venv path — the log shows
Found venv environment: cpython-3.13.9-macos-aarch64-none (3.13.9) for a directory that has
no pyvenv.cfg and no activate. system environments, which carry no shellActivation,
behave correctly and emit nothing.

Suggested fix

  • Gate the sh/bash/zsh/gitbash/unknown entries on pathExists(join(dir, "activate")), matching
    the existing fish/csh/xsh/nu checks, so a prefix without an activation script yields an
    effectively non-activatable environment.
  • Optionally, additionally report uv python install toolchains as non-activatable (they have
    no pyvenv.cfg), so they are not offered as activatable venv environments.

Workaround

Pin the folder to the system manager, which emits no activation command:

"python-envs.pythonProjects": [
  { "path": "<folder>", "envManager": "ms-python.python:system" }
]

or select a real .venv / system interpreter instead of the uv toolchain.

Additional context

Reproduced by selecting the interpreter through Python: Select Interpreter → Enter interpreter
path…
in the GUI, and independently by restoring the persisted
ms-python.vscode-python-envs:venv:WORKSPACE_SELECTED entry the picker writes.

Unrelated observation from the same session, in case it is useful: activating the extension
wrote "python-envs.defaultEnvManager": "ms-python.python:venv" into the workspace
settings.json (~/.vscode/settings.json) by itself.

Lingua principale
TypeScript
Stelle
140
Fork
63
Merge medio
1g 4h
PR unite (30g)
35

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/vscode-python-environments

Tutte le issue di microsoft/vscode-python-environments

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.