Renomeando uma pasta virtualenv sem quebrá-la

162

Eu criei uma pasta e inicializei uma instância virtualenv nela.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Quando executo (env)$ pip freeze, ele mostra os pacotes instalados como deveria.

Agora eu quero mudar o nome myproject/para project/.

$ mv myproject/ project/

No entanto, agora quando corro

$ . env/bin/activate
(env)$ pip freeze

diz pip não está instalado. Como renomear a pasta do projeto sem interromper o ambiente?

Riley Watkins
fonte
1
Esta pergunta é antiga e já tem uma resposta, mas tenho que me perguntar: por que o OP não pôde simplesmente mover o virtualenv de volta para onde estava? Obviamente, isso não resolve o desejo de mudar / renomear, mas isso não restauraria um virtualenv funcional ou já está irremediavelmente quebrado?
Malik A. Rumi
2
Sim, você está certo, ele repararia o ambiente virtual, mas não resolveria o problema.
Florian
Novembro de 2019, Python3. A melhor solução para mim é descrever em aarongorka.com/blog/portable-virtualenv
Samir Sadek

Respostas:

148

Você precisa ajustar sua instalação para usar caminhos relativos. virtualenvprevê isso com a --relocatableopção Dos documentos :

Normalmente, os ambientes estão vinculados a um caminho específico. Isso significa que você não pode mover um ambiente ou copiá-lo para outro computador. Você pode corrigir um ambiente para torná-lo realocável com o comando:

$ virtualenv - ENV relocável

NOTA: ENV é o nome do ambiente virtual e você deve executá-lo fora do diretório ENV.

Isso fará com que alguns dos arquivos criados pelo setuptools ou distribua o uso de caminhos relativos e altere todos os scripts para usar o activ_this.py em vez de usar o local do interpretador Python para selecionar o ambiente.

Nota: você deve executá-lo depois de instalar qualquer pacote no ambiente. Se você tornar um ambiente relocável, instale um novo pacote, execute virtualenv --relocatable novamente.

ire_and_curses
fonte
2
advertência: Alterar um env para relocável faz mais do que apenas mover a pasta. (consulte a Nota: copiada dos documentos) ... pode ter efeitos colaterais.
Ben Roberts
7
A opção --relocatable atualmente tem vários problemas e não é garantida que funcione em todas as circunstâncias. É possível que a opção seja descontinuada em uma versão futura do virtualenv. Além disso, isso não torna seus pacotes multiplataforma. Você pode mover o diretório, mas ele só pode ser usado em outros computadores semelhantes.
The Demz
1
O @TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvajudará a encontrar quaisquer shabangs que usem o venv antigo, mas não é uma verificação completa do venv realocado.
quer
2
Além disso, você terá que editar o .projectarquivo virtualenvwrapper , que contém o caminho para o código-fonte que depende do virtualenv, supondo que você esteja usando virutalenvwrapper e também renomeou o diretório do projeto para corresponder ao novo virtualenv.
quer
Eu tive que desativar o virtualenv antes de executar isso.
antonagestam 31/10
108

Eu acredito que "saber o porquê" importa mais do que "saber como" . Então, aqui está outra abordagem para corrigir isso.

Quando você executa . env/bin/activate, ele realmente executa os seguintes comandos (usando, /tmppor exemplo):

VIRTUAL_ENV="/tmp/myproject/env"
export VIRTUAL_ENV

No entanto, você acabou de renomear myprojectpara project, para que o comando não seja executado. É por isso que diz pip is not installed: porque você não instalou pipno ambiente global do sistema e seu virtualenv pipnão foi originado corretamente.

Se você deseja corrigir isso manualmente, é assim:

  1. Com seu editor favorito como o Vim, modifique /tmp/project/env/bin/activatenormalmente na linha 42:

    VIRTUAL_ENV='/tmp/myproject/env' => VIRTUAL_ENV='/tmp/project/env'

  2. Modifique /tmp/project/env/bin/pipna linha 1:

    #!/tmp/myproject/env/bin/python => #!/tmp/project/env/bin/python

Depois disso, ative seu ambiente virtual envnovamente e você verá que pipvoltou.

holys
fonte
6
Se desejar alterar manualmente os caminhos, deve-se observar que há mais de dois arquivos codificados. Encontrá-los todos com algo como: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. De fato, notei que em uma das minhas instâncias do Django, muitos pacotes tinham o "caminho para o Python sh-bang" neles.
23716 Kevin
Isso me ajudou muito. Eu definitivamente precisava saber o porquê ... Obrigado!
Jarvis
Em contraste com o comentário de Keven acima, acho que editar essas duas linhas resolve todos os problemas para mim com relação aos movimentos virtualenv. Talvez haja algum caso de uso que eu não estou usando e, portanto, não encontre o problema.
Deleet 4/11
Risca isso! Hoje encontrei um problema: o ipython não funcionaria dentro do virtualenv. Para resolvê-lo, editei o cabeçalho do bash (como é chamado?) No ipythonarquivo e funcionou bem.
Deleet 04/11
Hmm, isso não está funcionando para mim, e parece que meu script de ativação não possui a Linha 1 mencionada aqui na Etapa 2. Alguma coisa mudou?
Evan Zamir
40

NOTA: Como @jb. salienta que esta solução se aplica apenas a s (re) criados facilmente virtualenv. Se um ambiente demorar várias horas para instalar esta solução, não é recomendado


Os virtualvs são ótimos porque são fáceis de criar e alternar; eles evitam que você fique bloqueado em uma única configuração. Se você conhece os requisitos do projeto ou pode obtê-los, faça um novovirtualenv :

  • Crie um requirements.txtarquivo

    (env)$ pip freeze > requirements.txt

    • Se você não conseguir criar o requirements.txtarquivo, verifique env/lib/pythonX.X/site-packagesantes de remover o original env.
  • Excluir o existente (env)

    deactivate && rm -rf env

  • Crie um novo virtualenv, ative-o e instale requisitos

    virtualenv env && . env/bin/activate && pip install -r requirements.txt


Como alternativa, use virtualenvwrapper para facilitar um pouco as coisas, pois todos os virtualenvs são mantidos em um local centralizado

$(old-venv) pip freeze > temp-reqs.txt
$(old-venv) deactivate
$ mkvirtualenv new-venv
$(new-venv) pip install -r temp-reqs.txt
$(new-venv) rmvirtualenv old-venv
bnjmn
fonte
6
Bem, para algumas pessoas, pip install -r requirements.txtleva algumas horas (compilando extensões C de terceiros no raspberry pi).
jb.
4
Talvez seja verdade, mas isso me parece uma vantagem. Ainda acho que essa pode ser uma solução viável para muitos casos.
bnjmn
Sim, muitos projetos (site do Django, por exemplo) levam apenas 30 segundos para instalar tudo, mesmo que tenham algumas dúzias de dependências (desde que você baixe tudo primeiro e use '--no-index --find-links = downloadDir' )
Jonathan Hartley
1
@bnjmn o one-liner virtualenv env && pip install -r requirements.txtnão instalará os requisitos no novo ambiente, porque você não ativá-lo
Yarin
1
@ Yarin Obrigado por apontar isso. Eu realmente senti falta disso, sendo virtualenv-wrapperusuário (que é ativado automaticamente na criação). Atualizei minha resposta para incluir a ativação do virtualenvna esperança de evitar qualquer confusão.
bnjmn
28

Eu sempre instalo o virtualenvwrapper para ajudar. No prompt do shell:

pip install virtualenvwrapper

Existe uma maneira documentada nos documentos virtualenvwrapper - cpvirtualenv É isso que você faz. Verifique se você está fora do seu ambiente e volte ao prompt do shell. Digite aqui com os nomes necessários:

cpvirtualenv oldenv newenv

E então, se necessário:

rmvirtualenv oldenv

Para ir para o seu newenv:

workon newenv
Afrowave
fonte
1
A resposta de Afrowave realmente deve ser o método aceito.
Jaxian
Isso só funciona se alguém estiver usando virtualenvwrapper, não apenas virtualenv. Esta resposta de @ryankdwyer é melhor.
LS
Eu editei minha resposta para refletir que alguém deveria instalar o 'virtualenvwrapper'. Supondo que a renomeação de ambientes virtuais aconteça muito, eu recomendaria dessa maneira.
Afrowave
Embora confie no virtualenvwrapper, é o mais simples. E isso funciona bem.
precisa saber é o seguinte
17

Você pode corrigir seu problema seguindo estas etapas:

  1. renomeie seu diretório
  2. execute novamente: $ virtualenv ..\path\renamed_directory
  3. O virtualenv corrigirá as associações de diretório, deixando seus pacotes no lugar
  4. $ scripts/activate
  5. $ pip freeze para verificar se seus pacotes estão no lugar
  6. Uma ressalva importante, se você tiver alguma dependência de caminho estático nos arquivos de script no diretório virtualenv, precisará alterá-las manualmente.
ryankdwyer
fonte
1
Esta foi uma solução muito boa para mim. Como essa solução pode evitar alguns dos problemas associados --relocatable, acho que essa solução é melhor que a resposta aceita. Até agora, notei que muitos .pycarquivos _new_name_/lib/python2.7ainda se referem _old_name_. No entanto, isso não parece afetar o funcionamento do meu ambiente. Talvez a única solução melhor esteja usando virtualenvwrapperou alguns dos outros utilitários mencionados entre as respostas aqui. Pelo menos esta solução não requer a instalação de programas adicionais.
LS
Funciona como um encanto!
AmirHossein
13

Outra maneira de fazer isso que funcionou para mim muitas vezes sem problemas é o virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
fonte
Isso deve ser marcado como a melhor resposta. Mãos para baixo! Demorou algum tempo para clonar, então tenha paciência, pessoal.
Amitrajit Bose
O virtualenv-clone negligencia a atualização do prompt. Tinha que fazer isso manualmente. Fora isso, é ótimo.
user3667349 23/03
5

(dentro da pasta do projeto)

cd bin
sed -i 's/old_dir_name/new_dir_name/g' *

Não se esqueça de desativar e ativar

Ignacio
fonte
Funciona bem; Ou para o caminho do Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *para macs
Alex
1

virtualenv --relocatable ENVnão é uma solução desejável. Suponho que a maioria das pessoas deseja renomear um virtualenv sem nenhum efeito colateral a longo prazo.

Então, eu criei uma ferramenta simples para fazer exatamente isso. A página do projeto para virtualenv-mv descreve-a um pouco mais detalhadamente, mas essencialmente você pode usá- virtualenv-mvlo como faria com uma implementação simples de mv(sem nenhuma opção).

Por exemplo:

virtualenv-mv myproject project

Observe, no entanto, que acabei de hackear isso. Isso pode ocorrer em circunstâncias incomuns (por exemplo, virtualenvs com links simbólicos), portanto, tenha cuidado (faça backup do que você não pode perder) e informe-me se encontrar algum problema.

Seis
fonte