Posso mover um virtualenv?

93

Esta pergunta não é uma duplicata.

Não se refere apenas a renomear um ambiente virtual, mas também a movê- lo para um diretório diferente, incluindo, potencialmente, um diretório de usuário diferente.

Isso não é o mesmo que simplesmente renomear um ambiente virtual, especialmente para pessoas não familiarizadas com o virtualenvs.

Se eu criar um virtualenv e movê-lo para uma pasta diferente, ele ainda funcionará?

$ virtualenv -p /usr/bin/python3 /home/me/Env/my-python-venv
$ source Env/my-python-venv/bin/activate
(my-python-venv) $ 

... mais tarde naquele dia, o ambiente virtual mudou ...

(my-python-venv) $ deactivate
$ mkdir -p /home/me/PeskyPartyPEnvs
$ mv /home/me/Env/my-python-venv /home/me/PeskyPartyPEnvs/

Questão:

Isso vai funcionar?

$ source /home/me/PeskyPartyPEnvs/my-python-venv/bin/activate
(my-python-venv) $ /home/me/PeskyPartyPEnvs/my-python-venv/bin/pip3 install foaas

Quero dizer isso menos como uma questão sobre a sabedoria de tentar isso (a menos que essa sabedoria seja engraçada, é claro), e mais sobre se é possível. Eu realmente quero saber se é possível fazer no Python 3 ou se eu apenas tenho que engolir e clonar.

Posso apenas mvuma virtualenvcomo que sem tristeza? Eu quero evitar tristeza.

Nathan Basanese
fonte

Respostas:

70

Sim. É possível movê-lo na mesma plataforma. Você pode usar --relocatableem um ambiente existente.

De --help:

--relocatable - Torna um ambiente virtualenv EXISTENTE realocável. Isso corrige scripts e torna todos os arquivos .pth relativos.

NO ENTANTO, isso NÃO parece alterar o activatescript, apenas altera os scripts pip*e easy_install*. No activatescript, a $VIRTUAL_ENVvariável de ambiente codificada como original /path/to/original/venv. A $VIRTUAL_ENVvariável é usada para definir o PATHde seu ambiente ativo também, portanto, deve ser alterada com base no novo local para fazer a chamada pythone pipetc. sem caminho absoluto.

Para corrigir esse problema, você pode alterar a $VIRTUAL_ENVvariável de ambiente no activatescript (por exemplo, usando sed), e tudo deve estar pronto para ir.

Um exemplo de uso:

$ cd ~/first
$ virtualenv my-venv
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV="/home/username/first/my-venv"
$ virtualenv --relocatable my-venv
Making script my-venv/bin/easy_install relative
Making script my-venv/bin/easy_install-2.7 relative
Making script my-venv/bin/pip relative
Making script my-venv/bin/pip2 relative
Making script my-venv/bin/pip2.7 relative
### Note that `activate` has not been touched
$ mkdir ~/second
$ mv my-venv ~/second
$ cd ~/second
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV=/home/username/first/my-venv
### (This variable hasn't been changed, it still refers to the old, now non-existent directory!)
$ sed -i -e 's|username/first|username/second|' my-venv/bin/activate
## sed can be used to change the path.
## Note that the `-i` (in place) flag won't work on all machines. 
$ source my-venv/bin/activate 
(my-venv) $ pip install foass
...
(my-venv) $ python 
[...]
> import foass

Hooray, agora você pode instalar coisas e carregá-los em seu ambiente virtual recém-localizado.

hilcharge
fonte
//, Hm. Isso não parece realmente torná-los realocáveis. Eu continuo recebendo alguns erros sobre eles não serem arquivos de script "normais".
Nathan Basanese,
7
"A opção --relocatable atualmente tem uma série de problemas e não é garantido que funcione em todas as circunstâncias. É possível que a opção seja descontinuada em uma versão futura do virtualenv. " (
Grifo
1
Tentei fazer isso no windows e o erro lista todos os scripts (* .py, * .bat, * .ps1) no Scriptsdir (equivalente a binem * nix) e diz algo como activate.ps1 cannot be made relative (it's not a normal script that starts with #!c:\..python.exe.basicamente está reclamando do hash-bang no arquivo header não é o python.exe do virtualenv atual, é aquele de onde o movi -easy fixou. Eu olhei naquele roteiro chique e ele já descobriu seu próprio caminho de qualquer maneira - legal. Alguns dos outros scripts também não dependem de caminhos (por exemplo, deactivate.bat), portanto, em resumo, isso funciona.
Davos
2
@NathanBasanese a mensagem activate.ps1 cannot be made relativepode ser ignorada porque o script já é relativo. A mensagem não é útil no Windows, porque os scripts não usam #!diretivas como no Linux para informar ao shell qual aplicativo deve executá-lo. O activate.batnão é modificado, mas não é usado (pelo menos no Windows 10, chamar activateinicia o script PoSH), então não, não precisei editar nenhum script. O problema é pip.exeque tem um caminho para Python embutido em código e precisa ser editado com um editor hexadecimal ou apenas reinstalado.
Davos
3
@Sgedda Em retrospecto, eu diria não faça isso. Seus ambientes Python devem ser facilmente recriados usando no mínimo pip freezeum arquivo de requisitos para que você possa reinstalar facilmente todos os seus pacotes, docker (funciona bem com o virtualenv instalado nele), conda, pyenv ou algumas outras ferramentas. Você deve ser capaz de criar e destruir ambientes como infraestrutura imutável, eles não devem ser preciosos.
Davos
19

Para Python 3.3+ (com novo venvmódulo integrado)

Resposta curta (independentemente da versão):

  • Não há maneira limpa e direta de mover um ambiente virtual
  • Basta recriar, é fácil !!


Resposta longa:

A partir do Python v3.3, virtualenvtornou-se um módulo integrado chamado venv.

A --relocatableopção mencionada em outras respostas não foi incluída venve, atualmente, não há uma maneira boa e segura que eu conheça de renomear ou realocar um ambiente virtual Python.

No entanto, existe uma maneira bastante simples de simplesmente recriar um ambiente virtual, com todos os seus pacotes instalados atualmente. Consulte esta resposta ou consulte a seção abaixo para obter informações sobre como recriar um ambiente virtual. Durante o processo, você pode recriar o novo ambiente em qualquer local e com o nome que desejar. Ou consulte a seção abaixo para ver o processo.

Nessa resposta, ele menciona alguns outros pacotes de terceiros que podem suportar mudanças ou renomeações diretas. Se você está decidido a buscar uma maneira de mover um ambiente virtual intacto, pode verificar se eles também funcionam com ele venv.

Observação: nessa resposta, o foco está em virtualenv, em vez de venv. Veja abaixo como traduzir.



venvx virtualenvsintaxe de comando mais antiga

O comando a ser usado venvé:

python -m venv

em vez de apenas virtualenv, que é instalado como um comando no pacote original. Onde "python" se refere ao modo como você executa seu executável python, que pode ser uma variedade de coisas, como:

  1. python
  2. pyou py -3.7ou semelhante (o Python Launcher para Windows para Python 3.3+ e Windows apenas no momento)
  3. python3 (convenção para ambientes Linux que instalam duas vezes o python 2 e 3)
  4. Se você estiver tendo problemas, use o caminho absoluto para o executável Python que deseja executar: por exemplo, c:\program files\python37\python.exe

Se você não tiver certeza de qual versão está sendo executada, você sempre pode python --versiondescobrir.



Como recriar um ambiente virtual

Criar / recriar um ambiente virtual é fácil e deve se tornar uma segunda natureza depois de trabalhar um pouco com eles. Este processo reflete o que você faria para distribuir seu script como um pacote (com suas dependências) na primeira metade, e então o que alguém faria para instalar seu script / pacote para desenvolvimento posterior.

Primeiro, obtenha uma lista atualizada do que há no ambiente virtual. Com ele ativo, obtenha a versão do Python que ele usa e salve a lista de dependências em um arquivo.

  1. Use python --versioncom o ambiente virtual ativado para ver qual versão do Python ele está usando.

    • Isso é para maior clareza - você pode querer atualizar a versão Python por vários motivos - pelo menos para a versão de patch mais recente
    • Por exemplo, se o venv existente está usando Python v3.7.4, mas agora v3.7.6 foi lançado - use v3.7.6, que deve incluir apenas segurança ininterrupta e correções de bugs.
  2. Use python -m pip freeze > requirements.txtpara criar a lista de dependências do pacote atual e colocá-las no requirements.txtarquivo. Este comando funciona no Linux ou no Git Bash com certeza - não 100% certo sobre o Powershell ou a linha de comando no Windows.

Agora crie um novo ambiente virtual e adicione as dependências do antigo.

  1. Faça o seu novo venv.

    • Certifique-se de estar usando a versão correta do python que deseja instalar no venv.
    • Se você quiser que seja exatamente a mesma versão do Python:
      • Execute o python diretamente do ambiente virtual atual (com ele ativado) e use apenas pythoncomo o comando
      • Ou use um caminho absoluto python.exena pasta do ambiente virtual
    • Para a nova entrada da pasta venv no comando:
      • Adicione um caminho absoluto ou relativo ao local da pasta final desejada.
      • Use python -m venv my_new_venvpara criar um novo ambiente virtual no diretório de trabalho atual em uma nova my_new_venvpasta.
      • O nome da pasta venv será o nome do venv (que aparece no prompt quando é ativado).
  2. Instale suas dependências do requirements.txtarquivo.

    • python -m pip install -r requirements.txt

Você pode precisar reinstalar os pacotes locais que estão em modo de desenvolvimento.

Observe, se você precisar ver o local específico em que um pacote está instalado, use:

  • python -m pip list -v
  • A opção -vou "verbose" irá adicionar algumas informações extras sobre cada pacote instalado, incluindo o caminho em que está instalado. Isso é útil para garantir que você está mantendo os pacotes virtuais, do usuário e do sistema instalados corretamente.

Neste ponto, você pode apenas excluir a pasta venv antiga e todo o conteúdo. Eu recomendo usar uma GUI para isso - as exclusões de arquivos geralmente são permanentes na linha de comando do Linux, e um pequeno erro de digitação pode ser uma má notícia.

LightCC
fonte
Não há como copiar o estado venv pip, ou seja, sem precisar baixar novamente todas as bibliotecas com pip?
Aydo
Não tenho certeza do motivo pelo qual você desejaria - é devido a uma situação de largura de banda extremamente baixa para a Internet ou à enorme necessidade de duplicar muito? Eu acredito que você poderia obter todos os zips do pypi e instalar localmente, mas não estou atualizado sobre isso. Eu sei que você pode configurar um servidor pip local para hospedar pacotes.
LightCC de
O problema (que estou tentando resolver) é que desejo executar um script Python em uma máquina que não permite que o tráfego de rede seja enviado (ou quase em qualquer lugar). Posso colocar arquivos nele, mas ele não pode falar com pip. Um caso de nicho, com certeza, mas exatamente por que preciso mover essas coisas.
Richard Rast de
@RichardRast Esse é um problema diferente, estou apenas respondendo à pergunta original. Nota: existem soluções para o seu problema (baixe os pacotes como arquivos compactados e instale localmente, execute um servidor espelho PyPi atrás do seu firewall, etc.), mas este não é o certo: Q&A para isso ..
LightCC
2
Você poderia criar rodas de todos os seus pacotes com pip wheel . -w wheelse, em seguida, apenas reinstalar os pacotes no novo ambiente virtual compip install --no-index --find-links /path/to/wheels/ -r requirements.txt
np8 01 de
7

O --relocatableargumento para virtualenvparece permitir que você faça isso.

Ruth Franklin
fonte
//, isso depende apenas de caminhos relativos, ou de alguma outra forma?
Nathan Basanese,
1
--relocatable funciona apenas em ambientes virtuais existentes. Execute virtualenv --relocatable my-python-venvAPÓS o ambiente já existir.
hilcharge
1
De --help: This fixes up scripts and makes all .pth files relative. Não, não vai fazer bibliotecas independentes de plataforma. Se você quiser movê-lo para uma plataforma diferente, precisará reinstalá-lo com base no python local.
hilcharge
5
o módulo python3 venv não suporta este sinalizador
Nelson,
7

MAS ALAS:

Não, você não pode simplesmente mv. Existem soluções alternativas, mas pode ser mais fácil reinstalar.

(my-python-venv)$ /home/me/PeskyPartyPEnvs/pip3 install foaas
zsh: /home/me/PeskyPartyPEnvs/pip3: bad interpreter: /home/me/Env/my-python-venv/bin/python3: no such file or directory
(my-python-venv)$ deactivate
$ 

... pressiona entermuito em frustração, e o seguinte funciona

$
$
$ pip3 search foaas

Exceto que não é, portanto my-python-venv, tristeza.

Quer mvo seu virtualenve usá-lo, caso contrário, não modificada?

Resposta curta:

Vou deixar Boromir dizer, para que ele possa deixar claro:

Bem, você não pode .

Nathan Basanese
fonte
2
a menos que você queira ser sangrento e modificá-lo apropriadamente: são os links nos binários na caixa que causam o problema de movimento. Se você sabe de onde veio, pode usar algo como find bin -type f -exec ex -sc "%s,${FROM},${PWD},g|x" {} \;assumir que seu bin e lib estão em sua pasta venv atual. Eu uso isso como uma maneira rápida e suja de copiar e mover envs virtuais python3 com muitos pacotes pip instalados.
Paul Whipp de
1
@PaulWhipp Existe alguma vantagem em usar esse comando em vez de apenas usar --relocatable? Além disso, Nathan, ótima pergunta, mas esta é uma resposta terrível. Aceitar sua própria resposta é sempre um pouco tendencioso, a menos que seja bem escrito e enumere claramente as opções, mas determinar que você mesmo seria subjetivo de qualquer maneira.
Davos
1
@Davos --relocatable não funcionou para mim, mas rotineiramente movo os venvs do python3 hackeando os binários e até agora não tive problemas.
Paul Whipp
1
Eu estava sugerindo que você deveria mudar aceito para uma resposta diferente (ou seja, não a sua) Talvez aquela escolhida pelo povo: D
Davos
3
A pergunta era "posso simplesmente mvum venv?", E a resposta é "não, você não pode simplesmente mv, existem soluções alternativas, mas pode ser mais fácil reinstalar". Se essa fosse a melhor resposta, pouparia a mim e a outros algum tempo.
Nickolay
5

Sim, isso deve ser possível se você não fez nada que dependa do diretório atual do virtualenv.

No entanto, se você tiver escolha, a melhor coisa a fazer é criar um novo virtualenv e começar a usar o novo virtualenv. Esta é a escolha mais segura e com menor probabilidade de causar problemas posteriormente.

A documentação menciona que :

Cada virtualenv tem informações de caminho embutidas nele,

Por exemplo, se você o executou setvirtualenvproject, não será possível alternar para o diretório correto após a execução, workon ...então, nesse caso, será necessário corrigir isso manualmente.

Em geral, um virtualenv é pouco mais do que um diretório com os arquivos do interpretador Python necessários mais os pacotes de que você precisa.

Simeon Visser
fonte
3

Usando as respostas deste e de outros tópicos sobre tópicos semelhantes, fiz um script bash que, localizado e executado dentro do próprio diretório virtualenv , ajudará em seus movimentos do virtualenv.

Depois de fazer isso, virtualenv --relocatable yourenvvocê precisará alterar sua VIRTUAL_ENVvariável toda vez que mover o diretório, então se você não quiser alterá-la manualmente, use isto.

#!/bin/bash \n 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
EXISTING=$(grep 'VIRTUAL_ENV=' bin/activate)  
NEWDIR=VIRTUAL_ENV=\"$DIR\"
sed -i -e "s|$EXISTING|$NEWDIR|" bin/activate
source bin/activate

Espero que ajude.

Gerbs
fonte
1

SIM VOCÊ PODE! (Em windows)

A solução alternativa é fácil, basta mover seu ambiente virtual para qualquer lugar e editar activate.batdentro de scripts\:

  1. Mova para o ambiente virtual para o diretório desejado

  2. Clique com o botão direito e edite activate.batlocalizado em venv_folder\scripts.

  3. Alterar VIRTUAL_ENVvariável de:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    para dentro

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. Salve o arquivo em lote editado e pronto!

NOTA: Minha solução deve funcionar e economizar windows usersconfiguração de novos ambientes virtuais, duvido que funcione em outro sistema operacional, pois .batéMS-DOS

kyle olodin
fonte
1
Mudar old_directorypara old_directory- isso é um erro de digitação?
ack