Virtualenv: activate pode falhar devido a variáveis ​​não associadas quando executado com set -eu

Criado em 17 mar. 2017  ·  26Comentários  ·  Fonte: pypa/virtualenv

Parece que um bug antigo ainda está aqui: PS1: unbound variable quando chamado com o modo estrito bash.

Claramente, o virtualenv precisa de um teste usando o modo estrito bash e um conjunto quase vazio de variáveis ​​de ambiente, portanto, evitamos regressões futuras nisso.

Observe que este bug se reproduz com QUALQUER shell Unix compatível, não apenas bash , incluindo ksh e zsh .

Esta é uma maneira simples de replicar o bug:

#!/bin/bash
# same applies to any other bourne compatible shells (is not bash specific)
set -euox pipefail
pip install -U virtualenv
virtualenv xxx
unset PS1
source xxx/bin/activate

A solução alternativa, embora feia, é acrescentar PS=${PS:-} à linha de ativação, que define PS como string vazia quando ainda não está definida, ou mantém seu valor quando está definida.

O mesmo tipo de bug se aplica à versão Python do venv e também existe um PR

Não adie / atrase a implementação de uma correção apenas porque o mesmo tipo de bug existe em outros lugares. Observe que a sintaxe padrão da variável de expansão é compatível com POSIX e não algo novo ou extravagante, o fato de que isso não era conhecido do autor original não deve ser uma desculpa para não usá-lo.

Comentários muito úteis

Eu também fui mordido por isso, ao trabalhar no script de construção para uma solução de processamento de imagem baseada em lambda da AWS: https://github.com/awslabs/serverless-image-handler/blob/master/deployment/build-s3 -dist.sh

Usei a solução alternativa VIRTUAL_ENV_DISABLE_PROMPT=true source env/bin/activate .

Todos 26 comentários

Também estou descobrindo isso, executando o virtualenv 15.1.0. Estou usando um ambiente dentro de um pipeline Nextflow, e Nextflow é executado no modo estrito por padrão (https://github.com/nextflow-io/nextflow/issues/302). Embora o Nextflow possa ser reconfigurado para ser executado sem o modo estrito, concordo com o desenvolvedor do Nextflow que seria preferível evitar o uso de variáveis ​​não associadas, se possível.

Não sei exatamente como o script activate é criado, mas se vier de activate.sh , a correção pode ser tão simples quanto alterar $PS1 nas linhas 57, 59 e 61 para ${PS1-} . (Esta sintaxe usará o valor de PS1 se disponível, e a string vazia caso contrário. Ela não altera o valor de PS1 . Documentação ). Pelo menos, se eu modificar o script activate gerado em meu ambiente assim, a mensagem de erro desaparecerá.

Eu estou me perguntando quantos anos levaria para aprender a escrever código bash .... os bugs de variáveis ​​não associadas no virtualenv são muito antigos e são tão fáceis de corrigir e também EVITÁ-los no futuro apenas adicionando uma linha simples ao testes virtuais: set -euox pipefail .

Sem mencionar quantos anos levará para que a correção alcance todas as distros do virtualenv por lá, já que geralmente é empacotado no debian, ubuntu, centos, rhel, fedora, .... :( :( :(

os mantenedores do projeto reconhecerão que esse problema existe?

Não sei, mas considerando que também temos um PR que já tem quase duas semanas. A resposta mais provável é que eles não dão uma ... submissão.

Vou tentar fazer barulho no irc, twitter, talvez até na lista de e-mails. Talvez possamos mesclar as correções.

O virtualenv é a única coisa que me impede de tornar o modo estrito bash padrão em trabalhos de CI.

+1

Acho que apenas desabilitar nounset no início do script e restaurá-lo no final pode ser mais robusto em vez de tentar ensinar aos desenvolvedores de python como fazer bash :)

@ jakub-bochenski talvez você também possa ajudar com alguns comentários no irc. Vamos ver se conseguimos usuários suficientes para ativar um dev core virtualenv.

@ssbarnea não tenho certeza sobre isso, eu não

suspirar...

+1

Enviei um e-mail para pypa-dev 7 dias atrás e não recebi nenhuma resposta. Também ontem alguém postou que o binário win32 instalado contém um trojan, novamente sem resposta. Só espero que o cavalo de Tróia não goste muito da distro, não que isso vá me afetar.

Consulte https://groups.google.com/forum/#!forum/pypa -dev

Corri para isso hoje, percebi que era um bug em algum lugar no meu código.
: +1: para incluir set -euo pipefail nos testes de unidade.

para referência, o link direto para a discussão mencionada acima é: https://groups.google.com/d/topic/pypa-dev/8iVHDOqsj9M/discussion

@pfmoore escreveu

Já respondi com muito mais detalhes sobre a lista de usuários do virtualenv,

.. que acabou sendo a lista python-virtualenv; https://groups.google.com/d/topic/python-virtualenv/5xKG8KoBl6g/discussion

FWIW, a solução que estou usando no .devkit é definir VIRTUAL_ENV_DISABLE_PROMPT=true na linha source . Funciona melhor para o meu caso de uso do que definir PS1 , porque desativa completamente o comportamento de configuração de prompt.

@pjeby @ jakub-bochenski @jpuskar @ axd1967 Por favor, note que já temos uma correção de bug para isso, mas para mesclá-lo, precisamos revisar e mesclar dois outros PRs, isso é apenas porque queremos e precisamos melhorar o teste de ativação- suíte.

  1. https://github.com/pypa/virtualenv/pull/1089 - ativar o teste de CI em py36 e eliminar py33
  2. https://github.com/pypa/virtualenv/pull/1087 - habilitar o uso do script test_activate.sh no CI
  3. https://github.com/pypa/virtualenv/pull/1078 - correção PS1 não ligada para ativar

Provavelmente você verá que os dois últimos não estão passando nos testes de CI, por isso precisamos que os outros sejam mesclados primeiro.

Revise / comente sobre eles, é mais importante do que em outro projeto porque o virtualenv carece de algum poder de revisão, sendo este um dos motivos pelos quais pedi para me tornar um mantenedor em https://groups.google.com/d/msg/pypa -dev / SgK9vlu93BY / F2_8OoKAAgAJ - mesmo assim, parece que precisaremos de mais de um, pois eu não seria capaz de revisar minhas próprias alterações.

mesmo assim, parece que precisaremos de mais de um, pois não poderei revisar minhas próprias alterações.

@ssbarnea, você está nos pedindo para obter permissões de revisor ou apenas fazer uma revisão e deixar um + 1 / comentários?

EDITAR: não importa, aparentemente qualquer um pode avaliar um PR

1 fiz mais 2 para ir :)

Podemos obter um HEC sobre quando será mesclado e disponibilizado publicamente?

Edit: Ainda estou tendo esse problema, e acabou de derrubar uma compilação esta manhã.

Eu também fui mordido por isso, ao trabalhar no script de construção para uma solução de processamento de imagem baseada em lambda da AWS: https://github.com/awslabs/serverless-image-handler/blob/master/deployment/build-s3 -dist.sh

Usei a solução alternativa VIRTUAL_ENV_DISABLE_PROMPT=true source env/bin/activate .

@duaneking @robinbowes Há uma falta de energia de manutenção em torno do virtualenv e se você quiser ajudar a resolver esse problema, leia e comente https://groups.google.com/forum/#!topic/pypa -dev / SgK9vlu93BY

Minha impressão é que a equipe PYPA reagirá a isso apenas se receber feedback suficiente da comunidade.

FTR, ainda estamos aguardando a fusão no # 1087

Adivinhe qual é o primeiro exemplo de Usar o modo estrito Bash não oficial |

Sim, é python 2 virtualenv.

Ubuntu 16.04

Observe que o uso de bogdando / tripleo-ci @ 318d17a sobrescreverá o modo para -u mesmo que não estivesse ativo antes. Não é exatamente uma construção de prática recomendada.

Isso preservará o estado anterior:

old_setting=${-//[^u]/}
...
if [[ -n "$old_setting" ]]; then set -u; fi

agora eu sugiro usar patch (use bash ou mude de acordo com suas necessidades)
ele começará a falhar (interromper a execução) assim que os autores finalmente conseguirem postar esta correção, dando a você uma indicação clara da mudança sendo feita

set +H -euo pipefail
pushd "${envdir}"
patch -p0 <<< '
--- bin/activate 2018-10-12 09:08:16.991113929 +0200
+++ bin/activate 2018-10-12 09:27:51.505054528 +0200
@@ -54,11 +54,11 @@
 fi

 if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then
-    _OLD_VIRTUAL_PS1="$PS1"
+    _OLD_VIRTUAL_PS1="${PS1:-}"
     if [ "x" != x ] ; then
         PS1="$PS1"
     else
-        PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1"
+        PS1="(`basename \"$VIRTUAL_ENV\"`) ${PS1:-}"
     fi
     export PS1
 fi
'
popd
. "${envdir}/bin/activate"
Esta página foi útil?
0 / 5 - 0 avaliações