Atualize o python em um virtualenv

206

Existe uma maneira de atualizar a versão do python usada em um virtualenv (por exemplo, se for lançado um bugfix)?

Eu poderia pip freeze --local > requirements.txtremover o diretório e pip install -r requirements.txt, mas isso requer muita reinstalação de grandes bibliotecas, por exemplo numpy, que eu uso muito.

Percebo que essa é uma vantagem ao atualizar de, por exemplo, 2.6 -> 2.7, mas e 2.7.x -> 2.7.y?

Simon Walker
fonte
2
Embora você possa modificar alguns caminhos etc. para fazê-lo funcionar. A última coisa que você deseja é um ambiente um pouco diferente da produção. Apenas pense ... se houver uma diferença entre a forma como as várias versões são compiladas, você perderá o tempo todo economizando rastreando o bug. Eu levaria um tempo para criar um novo virtualenv e reinstalar tudo.
Sam Dolan
@ Simon Walker. Exatamente o mesmo problema. Eu tenho que atualizar o python 3.5.3 para uma correção de bug.
Mohammed Shareef C

Respostas:

77

Você viu isso ? Se não entendi mal essa resposta, tente criar um novo virtualenv em cima do antigo. Você só precisa saber qual python vai usar seu virtualenv (você precisará ver sua versão virtualenv).

Se o seu virtualenv estiver instalado com a mesma versão python da versão anterior e a atualização do pacote virtualenv não for uma opção, você pode ler isso para instalar um virtualenv com a versão python desejada.

EDITAR

Eu testei essa abordagem (a que cria um novo virtualenv em cima do antigo) e funcionou bem para mim. Eu acho que você pode ter alguns problemas se mudar do python 2.6 para 2.7 ou 2.7 para 3.x, mas se você apenas atualizar dentro da mesma versão (mantendo-se em 2.7 como desejar), não deverá ter nenhum problema, pois todos os pacotes são mantidos nas mesmas pastas para as duas versões do python (os pacotes 2.7.xe 2.7.y estão dentro de your_env / lib / python2.7 /).

Se você alterar sua versão do virtualenv python, será necessário instalar todos os seus pacotes novamente para essa versão (ou apenas vincular os pacotes necessários à nova pasta de pacotes da versão, ou seja: your_env / lib / python_newversion / site-packages)

marianobianchi
fonte
13
Ele não queria reinstalar nenhum pacote, se possível. Obviamente, você nunca instalou o numpy da fonte, se você não sabe por que isso é importante;) dica: leva um tempo de LOOOOOOOOOOOOOONG.
Antti Haapala
Sim, eu entendo isso. Mas parece que se ele criar um virtualenv em cima do outro, os pacotes não serão perdidos, então ele não precisará reinstalar o numpy ou qualquer outro pacote. No entanto, acho que ele deve tentar isso em um novo virtualenv, caso falhe.
marianobianchi
Descobri meu caso, acredito que as novas versões do virtualenv realmente atualizam, no entanto, para versões antigas, elas nem substituíram o executável python, o que causou problemas com pelo menos uma versão de correção de bug do python.
Antti Haapala
4
Não funcionou para mim e parece que não deveria: github.com/pypa/virtualenv/issues/437
Kentzo
1
Eu tentei criar um novo virtualenvem cima do velho, e ele fez o trabalho. Eu tive que especificar -ppara apontar para a versão correta do python.
Osa
76

Se você estiver usando o módulo venv que acompanha o Python 3.3+, ele suporta uma --upgradeopção. De acordo com os documentos :

Atualize o diretório do ambiente para usar esta versão do Python, supondo que o Python tenha sido atualizado no local

python3 -m venv --upgrade ENV_DIR
CoupleWavyLines
fonte
1
Infelizmente, isso não funciona no Ubuntu 16.04, onde eles quebraram venve se recusam a corrigi-lo com base em "você poderia simplesmente usar o virtualenv". EDIT: na verdade, ele funciona! Ele também mostra uma mensagem de erro sobre "surepip".
Rspeer
2
Atualizei o python de 3.5.1 para 3.6.4 no meu sistema. E para atualizar python no meu virtualenv, eu tinha que mencionar explicitamente python3.6 no comando:python3.6 -m venv --upgrade <path_of_existing_env>
Sarfraaz Ahmed
1
No meu caso, bin/pythone bin/python3ainda ligado ao antigo python3.4binário, e eu tive que definir os links manualmente. Além disso, existe uma maneira de remover a versão python agora desatualizada?
Jens
4
Eu tenho Error: Command '['/Users/me/Sites/site/venv3/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.> o que isso significa? Não vejo processos python ativos, não é possível atualizar.
user305883
1
@ user305883 Recebi um erro semelhante depois de atualizar minha versão do sistema Python de 3.5 para 3.6 (e removi o 3.5). Eu tive que reinstalar o 3.5 e executar python3.6 -m venv --upgrade ENV_DIRpara que ele funcionasse. Acho que ainda terei que atualizar alguns links simbólicos ENV_DIR/bin. Portanto, o truque era atualizar com a nova versão do Python enquanto a versão antiga ainda estava instalada.
AstroFloyd 25/02/19
24

Atualizado novamente: O método a seguir pode não funcionar em versões mais recentes do virtualenv. Antes de tentar fazer modificações no antigo virtualenv, salve as dependências em um arquivo de requisitos (pip freeze > requirements.txt) e faça um backup dele em outro lugar. Se algo der errado, você ainda poderá criar um novo virtualenv e instalar as antigas dependências nele (pip install -r requirements.txt).

Atualizado: alterei a resposta cinco meses depois de responder originalmente. O método a seguir é mais conveniente e robusto.

Efeito colateral: também corrige aSymbol not found: _SSLv2_methodexceção quando você fazimport sslem um ambiente virtual após atualizar o Python para a v2.7.8.

Aviso: Atualmente, este é apenas 2.7.x Python .


Se você estiver usando o Homebrew Python no OS X, primeiro faça o deactivatevirtualenv e atualize o Python:

brew update && brew upgrade python

Execute os seguintes comandos ( <EXISTING_ENV_PATH>é o caminho do seu ambiente virtual):

cd <EXISTING_ENV_PATH>
rm .Python
rm bin/pip{,2,2.7}
rm bin/python{,2,2.7}
rm -r include/python2.7
rm lib/python2.7/*
rm -r lib/python2.7/distutils
rm lib/python2.7/site-packages/easy_install.*
rm -r lib/python2.7/site-packages/pip
rm -r lib/python2.7/site-packages/pip-*.dist-info
rm -r lib/python2.7/site-packages/setuptools
rm -r lib/python2.7/site-packages/setuptools-*.dist-info

Por fim, recrie seu ambiente virtual:

virtualenv <EXISTING_ENV_PATH>

Ao fazer isso, os arquivos principais antigos do Python e as bibliotecas padrão (mais setuptoolse pip) são removidos, enquanto as bibliotecas personalizadas instaladas no site-packagessão preservadas e funcionando, assim que estiverem no Python puro. Bibliotecas binárias podem ou não precisar ser reinstaladas para funcionar corretamente.

Isso funcionou para mim em 5 ambientes virtuais com o Django instalado.

BTW, se ./manage.py compilemessagesnão estiver funcionando depois, tente o seguinte:

brew install gettext && brew link gettext --force
Rockallite
fonte
O único arquivo que tive que excluir foi o bin/pythonarquivo.
Koen.
Para algumas versões mais antigas do Python, excluir setuptoolse pipé necessário.
Rockallite 26/09/16
1
Eu também tive que excluir, <EXISTING_ENV_PATH>/.Pythonpois isso interrompeu a criação do virtualenv.
Kiran Jonnalagadda
2
Com base nessa resposta que eu escrevi um pequeno script (com atribuição completa): burgundywall.com/post/update-all-python-virtual-environments
Kurt
Você pode realmente remover facilmente seu ambiente virtual, executando rmvirtualenv <env_name>e irá remover todas as suas dependências forradas :) Veja mais em: virtualenvwrapper.readthedocs.io/en/latest/...
Nick Lucas
7

Não consegui criar um novo virtualenv em cima do antigo. Mas existem ferramentas no pip que tornam muito mais rápido reinstalar os requisitos em um novo dispositivo. O Pip pode criar cada um dos itens em seu requirements.txt em um pacote wheel e armazená-lo em um cache local. Quando você cria uma nova venv e executa a instalação do pip nele, o pip usará automaticamente as rodas pré-construídas, se as encontrar. O Wheels instala muito mais rápido do que executar o setup.py para cada módulo.

Meu ~ / .pip / pip.conf fica assim:

[global]
download-cache = /Users/me/.pip/download-cache
find-links =
/Users/me/.pip/wheels/

[wheel]
wheel-dir = /Users/me/.pip/wheels

Eu instalo o wheel ( pip install wheel) e depois corro pip wheel -r requirements.txt. Isso armazena as rodas construídas no direcional de roda no meu pip.conf.

A partir de então, sempre que instalo algum desses requisitos, ele é instalado a partir das rodas, o que é bastante rápido.

Russ Egan
fonte
1
Para a maioria das pessoas, acho que usar máquinas de pip para fazer o trabalho faz sentido, mas para quem personalizou seus virtualenvs pós-ativados, pré-ativados etc., essa não é uma opção desejável, porque tudo o que está perdido e precisa ser lido manualmente.
dpwrussell
6

Como atualizar a versão Python para um projeto virtualenvwrapper existente e manter o mesmo nome

Estou adicionando uma resposta para qualquer pessoa que use o excelente virtualenvwrapper de Doug Hellmann especificamente, pois as respostas existentes não fizeram isso por mim.

Algum contexto:

  • Eu trabalho em alguns projetos que são Python 2 e outros que são Python 3; enquanto eu adoraria usar python3 -m venv, ele não suporta ambientes Python 2
  • Quando inicio um novo projeto, uso o mkprojectque cria o ambiente virtual, cria um diretório de projeto vazio e os cds nele
  • Quero continuar usando o workoncomando virtualenvwrapper para ativar qualquer projeto, independentemente da versão do Python

Instruções:

Digamos que seu projeto existente seja nomeado fooe esteja atualmente executando o Python 2 ( mkproject -p python2 foo), embora os comandos sejam os mesmos, seja para atualizar de 2.x para 3.x, 3.6.0 para 3.6.1 etc. Também estou assumindo que você ' está atualmente dentro do ambiente virtual ativado.

1. Desative e remova o ambiente virtual antigo:

$ deactivate
$ rmvirtualenv foo

Observe que, se você adicionou comandos personalizados aos ganchos (por exemplo, bin/postactivate) , precisará salvá-los antes de remover o ambiente.

2. Esconda o projeto real em um diretório temporário:

$ cd ..
$ mv foo foo-tmp

3. Crie o novo ambiente virtual (e o diretório do projeto) e ative:

$ mkproject -p python3 foo

4. Substitua o diretório do projeto gerado vazio pelo projeto real, volte para o diretório do projeto:

$ cd ..
$ mv -f foo-tmp foo
$ cdproject

5. Reinstale as dependências, confirme a nova versão do Python, etc:

$ pip install -r requirements.txt
$ python --version

Se esse for um caso de uso comum, considerarei abrir um PR para adicionar algo como $ upgradevirtualenv/ $ upgradeprojectao virtualenvwrapper.

Taylor Edmiston
fonte
1
Sim por favor. Eu cheguei na metade e tive grandes problemas ... Uma verificação seria legal porque o primeiro passo é irreversível depois de excluído (pelo que
sei
2

Essa abordagem sempre funciona para mim:

# First of all, delete all broken links. Replace  my_project_name` to your virtual env name
find ~/.virtualenvs/my_project_name/ -type l -delete
# Then create new links to the current Python version
virtualenv ~/.virtualenvs/my_project_name/
# It's it. Just repeat for each virtualenv located in ~/.virtualenvs

Tirado de:

Anton Danilchenko
fonte
1

Mudei meu diretório pessoal de um Mac para outro (Mountain Lion para Yosemite) e não percebi o virtualenv quebrado até que perdi o controle do laptop antigo. Eu tinha o ponto virtualenv para o Python 2.7 instalado brewe, como o Yosemite veio com o Python 2.7, eu queria atualizar meu virtualenv para o sistema python. Quando corri virtualenvem cima do diretório existente, estava recebendo OSError: [Errno 17] File exists: '/Users/hdara/bin/python2.7/lib/python2.7/config'erro. Por tentativa e erro, resolvi esse problema removendo alguns links e corrigindo mais alguns manualmente. Isto é o que eu finalmente fiz (semelhante ao que o @Rockalite fez, mas mais simples):

cd <virtualenv-root>
rm lib/python2.7/config
rm lib/python2.7/lib-dynload
rm include/python2.7
rm .Python
cd lib/python2.7
gfind . -type l -xtype l | while read f; do ln -s -f /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/${f#./} $f; done

Depois disso, consegui executar o virtualenv no diretório existente.

haridsv
fonte
1

No OS X ou no macOS usando o Homebrew para instalar e atualizar o Python3, tive que excluir links simbólicos antes python -m venv --upgrade ENV_DIRque funcionasse.

Salvei o seguinte em upgrade_python3.sh, para que eu me lembrasse daqui a alguns meses quando precisar fazer isso novamente:

brew upgrade python3
find ~/.virtualenvs/ -type l -delete
find ~/.virtualenvs/ -type d -mindepth 1 -maxdepth 1 -exec python3 -m venv --upgrade "{}" \;

UPDATE: enquanto isso parecia funcionar bem no começo, quando eu executei o py.test, deu um erro. No final, acabei de recriar o ambiente a partir de um arquivo de requisitos.

Jeff C Johnson
fonte
py.testnão funciona porque `~ / .virtualenvs / myenv / bin / python3.7 não é um link simbólico; portanto, não é atualizado.
Ash Berlin-Taylor
Ah, na verdade, o problema é ~/.virtualenvs/myenv/.Pythonque existe um link simbólico.
Ash Berlin-Taylor
1

Se você estiver usando pipenv, não sei se é possível atualizar um ambiente, mas pelo menos para atualizações de versão menores, parece ser inteligente o suficiente para não reconstruir pacotes do zero quando ele cria um novo ambiente. Por exemplo, de 3.6.4 a 3.6.5:

$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv
Creating a v$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv
Creating a virtualenv for this project
Using /usr/local/bin/python3.6m (3.6.5) to create virtualenv
Running virtualenv with interpreter /usr/local/bin/python3.6m
Using base prefix '/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python3.6
Also creating executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python
Installing setuptools, pip, wheel...done.

Virtualenv location: /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD
Installing dependencies from Pipfile.lock (84dd0e)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 47/47  00:00:24
To activate this project's virtualenv, run the following:
 $ pipenv shell
$ pipenv shell
Spawning environment shell (/bin/bash). Use 'exit' to leave.
. /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
bash-3.2$ . /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
(autoscale-aBUhewiD) bash-3.2$ python
Python 3.6.5 (default, Mar 30 2018, 06:41:53) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>>
David Moles
fonte
impressionante! Obrigado por esta jóia #
Mayur Patil
1

Eu só quero esclarecer, porque algumas das respostas se referem venve outras se referem virtualenv.

O uso do sinalizador -pou --pythoné suportado virtualenv, mas não ativado venv. Se você possui mais de uma versão do Python e deseja especificar com qual criar venv, faça-o na linha de comando, assim:

malikarumi@Tetuoan2:~/Projects$ python3.6 -m venv {path to pre-existing dir you want venv in}

É claro que você pode atualizar com o venvque os outros indicaram, mas isso pressupõe que você já tenha atualizado o Python que foi usado para criar isso venvem primeiro lugar. Você não pode atualizar para uma versão Python que ainda não possui em seu sistema em algum lugar; portanto, certifique-se de obter a versão desejada primeiro e, em seguida, faça todos os recursos que deseja.

Malik A. Rumi
fonte
1

Etapa 1: Congele o requisito e faça um backup do ambiente existente

pip freeze > requirements.txt
deactivate
mv env env_old

Etapa 2: Instale o Python 3.7 e ative o ambiente virutal

sudo apt-get install python3.7-venv
python3.7 -m venv env
source env/bin/activate
python --version

Etapa 3: instalar requisitos

sudo apt-get install python3.7-dev
pip3 install -r requirements.txt
user3785966
fonte
0

Para todos com o problema

Erro: o comando '[' / Users / me / Sites / site / venv3 / bin / python3 ',' -Im ',' surepip ',' --upgrade ',' --default-pip ']' retornou diferente de zero status de saída 1.

Você deve instalar o python3.6-venv

 sudo apt-get install python3.6-venv
JanL
fonte