python / python/cpython

Windows: Activating a venv from a MSYS shell spawned from a cmd shell borks your PATH

未關閉
#157,692 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

topic-venv type-bug
主要語言
Python
星號
77.2k
分支
35.9k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

I believe I have found an issue with the activate script installed as part of virtualenv creation. Under a specific set of circumstances (activating the venv from a Windows shell, then spawning a Bash shell, then activating the venv in Bash), it can break your PATH, causing your shell to be unusable until it is restarted.

To reproduce, do the following:

In cmd:

> rem Create and enter a venv normally
> python -m venv .venv
> .venv\Scripts\activate.bat
(.venv) > rem Now we will run Git Bash (which is a distribution of MSYS) from this shell.
(.venv) > "C:\Program Files\Git\git-bash.exe"

In the opened Git Bash terminal:

$ echo $PATH
/c/Users/jsmith/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/mingw64/bin:/usr/bin:/c/Users/jsmith/bin:/c/path/to/.venv/Scripts: <snip the rest of my Windows PATH>

# Note that the venv is already active, but it's not obvious that it is because there is no prompt
$ command -v python
/c/path/to/.venv/Scripts/python

# Now activate the venv
$ source .venv/Scripts/activate

# Uh oh! Our PATH is broken now
(.venv) $ find
bash: find: command not found

# Observe that PATH no longer includes the MinGW bin dirs (bad) and uses backslashes instead of forward slashes (also bad!)
(.venv) $ echo $PATH
C:\path\to\.venv/Scripts: <snip the rest of Windows path>

It looks like what happens here is that the deactivate function in the activate script sees the _OLD_VIRTUAL_PATH env var (which it inherited from the cmd process) and tries to restore it as the "old PATH". Except oops, this path is Windows-style and is different from what is needed inside Git Bash.

Note that I actually ran into this issue because it was happening in my IDE terminal (specifically CLion); it looks like CLion attempts to activate the venv before starting the terminal. But it's easier to understand and reproduce with cmd.

One possible fix would be to change activate.bat to use a different name for _OLD_VIRTUAL_PATH, so that the bash and cmd scripts won't ever try to use the same variable. Unfortunately, that does leave the door open for some issues, because unlike bash, variables in cmd are always exported to subprocesses (set foo=bar is equivalent to export foo=bar in bash), so this variable will always get inherited by a subprocess. So, you could still run into an issue where activating a venv "reverts" your PATH to the value used by a parent process when it last activated a venv. Oh well, I guess this is what us holdouts get for still using cmd...

CPython versions tested on:

3.11

Operating systems tested on:

Windows

Linked PRs
  • gh-157722

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

重現報告中的 Windows cmd 和 Git Bash 操作順序,然後檢查 Lib/venv/scripts/common/activate 以及 issue 中提到的 activate.bat 指令碼。比較每個指令碼如何處理 _OLD_VIRTUAL_PATH,並驗證從 MSYS 啟用時是否保留可用的 shell PATH;連結的 gh-157722 表示相關工作已經在進行中。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
cli, operating-systems
Issue 類型
缺陷
難度
3/5
預估耗時
1-2 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。