python / python/cpython

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

Aberta
#157,692 0 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

topic-venv type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
35.9k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

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

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Reproduza a sequência do Windows cmd e do Git Bash descrita no relatório e, em seguida, inspecione Lib/venv/scripts/common/activate e o script activate.bat mencionado na issue. Compare como cada script lida com _OLD_VIRTUAL_PATH e verifique se a ativação a partir do MSYS preserva o PATH utilizável do shell; o gh-157722 vinculado indica que o trabalho já está em andamento.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
cli, operating-systems
Tipo de issue
Bug
Dificuldade
3/5
Tempo estimado
1-2 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.