在virtualenv中升级python

问题:在virtualenv中升级python

有没有一种方法可以升级virtualenv中使用的python版本(例如,如果出现错误修复版本)?

我可以pip freeze --local > requirements.txt删除目录和pip install -r requirements.txt,但这需要大量重新安装大型库,例如,numpy我经常使用。

我可以看到从2.6-> 2.7升级时这是一个优势,但是2.7.x-> 2.7.y呢?

Is there a way to upgrade the version of python used in a virtualenv (e.g. if a bugfix release comes out)?

I could pip freeze --local > requirements.txt, then remove the directory and pip install -r requirements.txt, but this requires a lot of reinstallation of large libraries, for instance, numpy, which I use a lot.

I can see this is an advantage when upgrading from, e.g., 2.6 -> 2.7, but what about 2.7.x -> 2.7.y?


回答 0

你看到吗?如果我没有误解这个答案,您可以尝试在旧版本的基础上创建一个新的virtualenv。您只需要知道哪个python将使用您的virtualenv(您将需要查看您的virtualenv版本)。

如果您的virtualenv安装了与旧版本相同的python版本,并且无法升级virtualenv软件包,则可能需要阅读此内容,以便使用所需的python版本安装virtualenv。

编辑

我已经测试了这种方法(在旧方法的基础上创建新的virtualenv的方法),它对我来说很好用。我认为,如果您从python 2.6更改为2.7或从2.7更改为3.x,则可能会遇到一些问题,但是如果您在同一版本内升级(保持在2.7不变),则不会有任何问题,因为所有软件包对于两个python版本,它们都位于相同的文件夹中(2.7.x和2.7.y软件包位于your_env / lib / python2.7 /中)。

如果更改了virtualenv python版本,则需要再次安装该版本的所有软件包(或仅将所需的软件包链接到新版本的packages文件夹中,即:your_env / lib / python_newversion / site-packages)

Did you see this? If I haven’t misunderstand that answer, you may try to create a new virtualenv on top of the old one. You just need to know which python is going to use your virtualenv (you will need to see your virtualenv version).

If your virtualenv is installed with the same python version of the old one and upgrading your virtualenv package is not an option, you may want to read this in order to install a virtualenv with the python version you want.

EDIT

I’ve tested this approach (the one that create a new virtualenv on top of the old one) and it worked fine for me. I think you may have some problems if you change from python 2.6 to 2.7 or 2.7 to 3.x but if you just upgrade inside the same version (staying at 2.7 as you want) you shouldn’t have any problem, as all the packages are held in the same folders for both python versions (2.7.x and 2.7.y packages are inside your_env/lib/python2.7/).

If you change your virtualenv python version, you will need to install all your packages again for that version (or just link the packages you need into the new version packages folder, i.e: your_env/lib/python_newversion/site-packages)


回答 1

如果您恰巧使用的是Python 3.3+随附的venv模块,则它支持一个--upgrade选项。根据文档

假设Python已就地升级,请升级环境目录以使用此版本的Python

python3 -m venv --upgrade ENV_DIR

If you happen to be using the venv module that comes with Python 3.3+, it supports an --upgrade option. Per the docs:

Upgrade the environment directory to use this version of Python, assuming Python has been upgraded in-place

python3 -m venv --upgrade ENV_DIR

回答 2

再次更新: 以下方法在较新版本的virtualenv中可能不起作用。在尝试对旧版virtualenv进行修改之前,应将依赖项保存在需求文件(pip freeze > requirements.txt)中,并在其他位置进行备份。如果有任何问题,您仍然可以创建一个新的virtualenv并在其中安装旧的依赖项(pip install -r requirements.txt)。

更新:我最初回答5个月后就更改了答案。以下方法更方便,更可靠。

副作用:在将Python升级到v2.7.8之后在虚拟环境中Symbol not found: _SSLv2_method执行操作时,它还修复了异常import ssl

注意:目前,这仅适用于Python2.7.x


如果您在OS X上使用Homebrew Python,请首先使用deactivate所有virtualenv,然后升级Python:

brew update && brew upgrade python

运行以下命令(<EXISTING_ENV_PATH>是您的虚拟环境的路径):

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

最后,重新创建您的虚拟环境:

virtualenv <EXISTING_ENV_PATH>

这样一来,旧的Python核心文件和标准库(plus setuptoolspip)就被删除,而安装在其中的自定义库site-packages则在纯Python 中被保留并正常工作。二进制库可能需要也可能不需要重新安装才能正常运行。

这在安装了Django的5个虚拟环境中为我工作。

顺便说一句,如果./manage.py compilemessages之后仍然无法使用,请尝试以下操作:

brew install gettext && brew link gettext --force

Updated again: The following method might not work in newer versions of virtualenv. Before you try to make modifications to the old virtualenv, you should save the dependencies in a requirement file (pip freeze > requirements.txt) and make a backup of it somewhere else. If anything goes wrong, you can still create a new virtualenv and install the old dependencies in it (pip install -r requirements.txt).

Updated: I changed the answer 5 months after I originally answered. The following method is more convenient and robust.

Side effect: it also fixes the Symbol not found: _SSLv2_method exception when you do import ssl in a virtual environment after upgrading Python to v2.7.8.

Notice: Currently, this is for Python 2.7.x only.


If you’re using Homebrew Python on OS X, first deactivate all virtualenv, then upgrade Python:

brew update && brew upgrade python

Run the following commands (<EXISTING_ENV_PATH> is path of your virtual environment):

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

Finally, re-create your virtual environment:

virtualenv <EXISTING_ENV_PATH>

By doing so, old Python core files and standard libraries (plus setuptools and pip) are removed, while the custom libraries installed in site-packages are preserved and working, as soon as they are in pure Python. Binary libraries may or may not need to be reinstalled to function properly.

This worked for me on 5 virtual environments with Django installed.

BTW, if ./manage.py compilemessages is not working afterwards, try this:

brew install gettext && brew link gettext --force

回答 3

我无法在旧版本的基础上创建新的virtualenv。但是pip中有一些工具,可以更快地将需求重新安装到全新的venv中。Pip可以将requirements.txt中的每个项目构建到wheel包中,并将其存储在本地缓存中。当您创建新的venv并在其中运行pip install时,如果pip找到了它们,它将自动使用预建的轮子。车轮的安装速度比每个模块的setup.py运行速度快得多。

我的〜/ .pip / pip.conf看起来像这样:

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

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

我安装了wheel(pip install wheel),然后运行pip wheel -r requirements.txt。这会将已构建的车轮存储在我的pip.conf中的wheel-dir中。

从那时起,每当我点安装这些要求中的任何一个时,它都会从轮子上安装它们,这非常快。

I wasn’t able to create a new virtualenv on top of the old one. But there are tools in pip which make it much faster to re-install requirements into a brand new venv. Pip can build each of the items in your requirements.txt into a wheel package, and store that in a local cache. When you create a new venv and run pip install in it, pip will automatically use the prebuilt wheels if it finds them. Wheels install much faster than running setup.py for each module.

My ~/.pip/pip.conf looks like this:

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

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

I install wheel (pip install wheel), then run pip wheel -r requirements.txt. This stores the built wheels in the wheel-dir in my pip.conf.

From then on, any time I pip install any of these requirements, it installs them from the wheels, which is pretty quick.


回答 4

如何为现有的virtualenvwrapper项目升级Python版本并保持相同名称

我要为使用Doug Hellmann出色的virtualenvwrapper的任何人添加一个答案,特别是因为现有的答案对我没有帮助。

一些背景:

  • 我从事一些Python 2项目和Python 3项目;虽然我想使用python3 -m venv它,但它不支持Python 2环境
  • 当我开始一个新项目时,我使用mkproject它来创建虚拟环境,创建一个空项目目录,并在其中进行cds
  • 我想继续使用virtualenvwrapper的workon命令来激活任何项目,而与Python版本无关

方向:

假设您的现有项目已命名foo,并且当前正在运行Python 2(mkproject -p python2 foo),尽管从2.x升级到3.x,从3.6.0升级到3.6.1等的命令都是相同的。我还假设您当前位于激活的虚拟环境中。

1.停用并删除旧的虚拟环境:

$ deactivate
$ rmvirtualenv foo

请注意,如果您已将任何自定义命令添加到了挂钩(例如bin/postactivate),则需要在删除环境之前保存这些自定义命令。

2.将实际项目存储在temp目录中:

$ cd ..
$ mv foo foo-tmp

3.创建新的虚拟环境(和项目目录)并激活:

$ mkproject -p python3 foo

4.用实际项目替换生成的空项目目录,改回项目目录:

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

5.重新安装依赖项,确认新的Python版本,等等:

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

如果这是一个常见的用例,我将考虑打开PR,为virtualenvwrapper 添加类似$ upgradevirtualenv/的内容$ upgradeproject

How to upgrade the Python version for an existing virtualenvwrapper project and keep the same name

I’m adding an answer for anyone using Doug Hellmann’s excellent virtualenvwrapper specifically since the existing answers didn’t do it for me.

Some context:

  • I work on some projects that are Python 2 and some that are Python 3; while I’d love to use python3 -m venv, it doesn’t support Python 2 environments
  • When I start a new project, I use mkproject which creates the virtual environment, creates an empty project directory, and cds into it
  • I want to continue using virtualenvwrapper’s workon command to activate any project irrespective of Python version

Directions:

Let’s say your existing project is named foo and is currently running Python 2 (mkproject -p python2 foo), though the commands are the same whether upgrading from 2.x to 3.x, 3.6.0 to 3.6.1, etc. I’m also assuming you’re currently inside the activated virtual environment.

1. Deactivate and remove the old virtual environment:

$ deactivate
$ rmvirtualenv foo

Note that if you’ve added any custom commands to the hooks (e.g., bin/postactivate) you’d need to save those before removing the environment.

2. Stash the real project in a temp directory:

$ cd ..
$ mv foo foo-tmp

3. Create the new virtual environment (and project dir) and activate:

$ mkproject -p python3 foo

4. Replace the empty generated project dir with real project, change back into project dir:

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

5. Re-install dependencies, confirm new Python version, etc:

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

If this is a common use case, I’ll consider opening a PR to add something like $ upgradevirtualenv / $ upgradeproject to virtualenvwrapper.


回答 5

这种方法总是对我有用:

# 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

取自:

This approach always works for me:

# 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

Taken from:


回答 6

我将主目录从一台Mac移到了另一台(Mountain Lion到优胜美地),直到我失去了旧笔记本电脑的机会,才意识到虚拟机损坏了。brew自从Yosemite随附Python 2.7以来,我已经安装了指向Python 2.7的virtualenv点,因此我想将我的virtualenv更新为系统python。当我virtualenv在现有目录上运行时,OSError: [Errno 17] File exists: '/Users/hdara/bin/python2.7/lib/python2.7/config'出现错误。通过反复试验,我通过删除一些链接并手动修复了一些问题来解决此问题。这是我最终所做的(类似于@Rockalite所做的,但更简单):

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

之后,我就可以在现有目录之上运行virtualenv了。

I moved my home directory from one mac to another (Mountain Lion to Yosemite) and didn’t realize about the broken virtualenv until I lost hold of the old laptop. I had the virtualenv point to Python 2.7 installed by brew and since Yosemite came with Python 2.7, I wanted to update my virtualenv to the system python. When I ran virtualenv on top of the existing directory, I was getting OSError: [Errno 17] File exists: '/Users/hdara/bin/python2.7/lib/python2.7/config' error. By trial and error, I worked around this issue by removing a few links and fixing up a few more manually. This is what I finally did (similar to what @Rockalite did, but simpler):

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

After this, I was able to just run virtualenv on top of the existing directory.


回答 7

在使用Homebrew安装和升级Python3的OS X或macOS上,我必须先删除符号链接,然后python -m venv --upgrade ENV_DIR才能使用。

我将以下内容保存在upgrade_python3.sh中,所以我会记得从现在开始需要几个月的时间:

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

更新:虽然这乍看起来似乎很好,但是当我运行py.test时却出现了错误。最后,我只是从需求文件中重新创建了环境。

On OS X or macOS using Homebrew to install and upgrade Python3 I had to delete symbolic links before python -m venv --upgrade ENV_DIR would work.

I saved the following in upgrade_python3.sh so I would remember how months from now when I need to do it again:

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

UPDATE: while this seemed to work well at first, when I ran py.test it gave an error. In the end I just re-created the environment from a requirements file.


回答 8

如果您使用pipenv,我不知道是否可以在适当的位置升级环境,但是至少对于次要版本升级来说,它似乎足够聪明,在创建新环境时不从头开始重建软件包。例如,从3.6.4到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
>>>

If you’re using pipenv, I don’t know if it’s possible to upgrade an environment in place, but at least for minor version upgrades it seems to be smart enough not to rebuild packages from scratch when it creates a new environment. E.g., from 3.6.4 to 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
>>>

回答 9

我只想澄清一下,因为有些答案是指venv,有些则是指virtualenv

在上支持使用-p--python标志virtualenv,但不支持venv。如果您有多个Python版本,并且想要指定使用哪个版本创建venv,请在命令行上执行以下操作:

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

当然,您也可以venv像其他人指出的那样进行升级,但是前提是您已经升级了最初用于创建该Python的Python venv。您无法升级到系统上某个地方尚未拥有的Python版本,因此请确保首先获取所需的版本,然后再从中获取所需的所有Venv。

I just want to clarify, because some of the answers refer to venv and others refer to virtualenv.

Use of the -p or --python flag is supported on virtualenv, but not on venv. If you have more than one Python version and you want to specify which one to create the venv with, do it on the command line, like this:

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

You can of course upgrade with venv as others have pointed out, but that assumes you have already upgraded the Python that was used to create that venv in the first place. You can’t upgrade to a Python version you don’t already have on your system somewhere, so make sure to get the version you want, first, then make all the venvs you want from it.


回答 10

步骤1:冻结要求并备份现有环境

pip freeze > requirements.txt
deactivate
mv env env_old

步骤2:安装Python 3.7并激活虚拟环境

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

步骤3:安装需求

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

Step 1: Freeze requirement & take a back-up of existing env

pip freeze > requirements.txt
deactivate
mv env env_old

Step 2: Install Python 3.7 & activate virutal environment

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

Step 3: Install requirements

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

回答 11

对于有问题的每个人

错误:命令'[‘/ Users / me / Sites / site / venv3 / bin / python3’,’-Im’,’ensurepip’,’-upgrade’,’-default-pip’]’返回非零退出状态1。

您必须安装python3.6-venv

 sudo apt-get install python3.6-venv

For everyone with the problem

Error: Command ‘[‘/Users/me/Sites/site/venv3/bin/python3’, ‘-Im’, ‘ensurepip’, ‘–upgrade’, ‘–default-pip’]’ returned non-zero exit status 1.

You have to install python3.6-venv

 sudo apt-get install python3.6-venv