[英]How to get "python -m venv" to directly install latest pip version
As part of the compilation step for a new python version, I fetch and run get-pip.py
, to have the latest pip installed next to the python executable:作为新 python 版本编译步骤的一部分,我获取并运行
get-pip.py
,以便在 python 可执行文件旁边安装最新的 pip:
$ /opt/python/3.7.0/bin/python --version
Python 3.7.0
$ /opt/python/3.7.0/bin/pip --version
pip 18.0 from /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7)
I have 25 such versions under /opt/python
, although I mostly use the five latest versions of each major.minor version that is not EOL.我在
/opt/python
下有 25 个这样的版本,尽管我主要使用不是 EOL 的每个 Major.minor 版本的五个最新版本。 To setup an invironment I used to run virtualenv
or my virtualenvutils
with the -p /opt/python/XYZ/bin/python
option to get a virtual environment with a specific version.为了设置环境,我曾经使用
-p /opt/python/XYZ/bin/python
选项运行virtualenv
或我的virtualenvutils
以获得具有特定版本的虚拟环境。
With Python 3.7 this gives the imp module deprecation warning:在 Python 3.7 中,这会给出 imp 模块弃用警告:
$ virtualenv -p /opt/python/3.7.0/bin/python /tmp/py37virtualenv
Running virtualenv with interpreter /opt/python/3.7.0/bin/python
Using base prefix '/opt/python/3.7.0'
/opt/util/virtualenvutils/lib/python3.6/site-packages/virtualenv.py:1041: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
New python executable in /tmp/py37virtualenv/bin/python
Installing setuptools, pip, wheel...done.
I have little hope this will be solved in virtualenv, as this has had a PendingDeprecationWarning
at least since 2014 (as can be seen from the output in this question )我几乎不希望这会在 virtualenv 中得到解决,因为至少从 2014 年开始就有
PendingDeprecationWarning
(从这个问题的输出中可以看出)
While investigating replacing virtualenv
with python -m venv
in virtualenvutils
, I first created a new venv
based virtual environment by hand:在调查替换
virtualenv
与python -m venv
在virtualenvutils
,我首先创建一个新的venv
用手基于虚拟环境:
$ /opt/python/3.7.0/bin/python -m venv /tmp/py37venv
$ /tmp/py37venv/bin/pip --version
pip 10.0.1 from /tmp/py37venv/lib/python3.7/site-packages/pip (python 3.7)
That has an old pip
version!那有一个旧的
pip
版本! If you use it, you'll get:如果你使用它,你会得到:
You are using pip version 10.0.1, however version 18.0 is available.
您使用的是 pip 版本 10.0.1,但是版本 18.0 可用。
You should consider upgrading via the 'pip install --upgrade pip' command您应该考虑通过“pip install --upgrade pip”命令升级
In the virtual environment created with virtualenv
you immediately get the latest version:在使用
virtualenv
创建的虚拟环境中,您会立即获得最新版本:
$ /tmp/py37virtualenv/bin/pip --version
pip 18.0 from /tmp/py37virtualenv/lib/python3.7/site-packages/pip (python 3.7)
I can run a post-creation step:我可以运行创建后步骤:
/tmp/py37venv/bin/pip install -U --disable-pip-version-check pip
which will take extra time.这将需要额外的时间。 And if there was a some security update for
pip
, this would imply running the non-secure version to get a secure version, an ideal point of attack.如果
pip
有一些安全更新,这意味着运行非安全版本以获得安全版本,这是一个理想的攻击点。
From virtualenvutils
it is trivial to do the multiple steps to create a pip
-less virtualenv and then add pip
using get-pip.py
.从
virtualenvutils
执行多个步骤来创建pip
-less virtualenv 然后使用get-pip.py
添加pip
get-pip.py
。 From the command-line this is not so simple:从命令行这不是那么简单:
$ /opt/python/3.7.0/bin/python -m venv --without-pip /tmp/py37venvnopip
$ /tmp/py37venvnopip/bin/python -c "from urllib.request import urlopen; response = urlopen('https://bootstrap.pypa.io/get-pip'); open('/tmp/tmp_get_pip.py', 'w').write(response.read())"
$ /opt/python/3.7.0/bin/python /tmp/tmp_get_pip.py
......
$ /opt/python/3.7.0/bin/pip --version
pip 18.0 from /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7)来自 /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7) 的 pip 18.0
What is causing /opt/python/3.7.0/bin/python -m venv
to take that old pip
version?是什么导致
/opt/python/3.7.0/bin/python -m venv
采用旧的pip
版本? Is that the version available when 3.7.0 was released? 3.7.0 发布时那个版本可用吗?
How can I update my install under /opt/python/3.7.0
in some way so that using /opt/python/3.7.0/bin/python -m venv
creates a virtualenv with the latest pip
version without reverting to scripts, aliases or using multiple commands?如何以某种方式更新我在
/opt/python/3.7.0
下的安装,以便使用/opt/python/3.7.0/bin/python -m venv
创建一个具有最新pip
版本的 virtualenv,而无需恢复到脚本、别名或使用多个命令? Having the latest pip
installed under /opt/python/3.7.0
obviously is not enough.在
/opt/python/3.7.0
下安装最新的pip
显然是不够的。
There are two bundled wheels:有两个捆绑的轮子:
/opt/python/3.7.0/lib/python3.7/ensurepip/_bundled/setuptools-39.0.1-py2.py3-none-any.whl
/opt/python/3.7.0/lib/python3.7/ensurepip/_bundled/pip-10.0.1-py2.py3-none-any.whl
I suspect I need to update those.我怀疑我需要更新这些。 Is there a better way than updating those by hand?
有没有比手动更新更好的方法? Some option for
/some/python -m venv
would be nice. /some/python -m venv
一些选项会很好。
(And running /some/python -m ensurepip --upgrade
doesn't do the trick) (并且运行
/some/python -m ensurepip --upgrade
不起作用)
Running the deprecated /opt/python/3.7.0/bin/pyvenv
has the same old pip
version problem.运行已弃用的
/opt/python/3.7.0/bin/pyvenv
具有相同的旧pip
版本问题。
The trick is not to install the bundled version of pip (which will almost always be out of date), but to use it to install the most current version from the internet.诀窍不是安装pip 的捆绑版本(它几乎总是过时的),而是使用它来安装来自 Internet 的最新版本。
Standard library venv
offers a --without-pip
flag that can help here.标准库
venv
提供了一个--without-pip
标志,可以在这里提供帮助。 After creating the virtual environment without pip, you can then you can "execute" ensurepip's wheel directly thanks to Python's zip importer.创建没有 pip 的虚拟环境后,您可以直接“执行”ensurepip 的轮子,这要归功于 Python 的 zip 导入器。 This is both faster and less hacky than installing pip and then immediately using that same pip installation to uninstall itself and upgrade.
这比安装 pip 然后立即使用相同的 pip 安装卸载自身并升级更快,也更简单。
Code speaks louder than words, so here's an example bash function for the process I've described:代码胜于雄辩,所以这里是我描述的过程的示例 bash 函数:
# in ~/.bashrc or wherever
function ve() {
local py="python3"
if [ ! -d ./.venv ]; then
echo "creating venv..."
if ! $py -m venv .venv --prompt=$(basename $PWD) --without-pip; then
echo "ERROR: Problem creating venv" >&2
return 1
else
local whl=$($py -c "import pathlib, ensurepip; whl = list(pathlib.Path(ensurepip.__path__[0]).glob('_bundled/pip*.whl'))[0]; print(whl)")
echo "boostrapping pip using $whl"
.venv/bin/python $whl/pip install --upgrade pip setuptools wheel
source .venv/bin/activate
fi
else
source .venv/bin/activate
fi
}
If you prefer the older project virtualenv
, it also offers --no-pip
, --no-setuptools
, and --no-wheel
flags to achieve the same on Python 2.7.如果您更喜欢旧项目
virtualenv
,它还提供--no-pip
、 --no-setuptools
和--no-wheel
标志以在 Python 2.7 上实现相同的目标。
Python 3.9's venv
may get an --upgrade-deps
option to automate this, see https://bugs.python.org/issue34556 for more info about that. Python 3.9 的
venv
可能会获得一个venv
--upgrade-deps
选项来自动执行此操作,有关更多信息,请参阅https://bugs.python.org/issue34556 。
I use upgrade-ensurepip
to update those pip
and setuptools
wheel files that are part of the ensurepip
package.我使用
upgrade-ensurepip
来更新作为ensurepip
包一部分的那些pip
和setuptools
轮文件。 It's not as elegant as being able to upgrade ensurepip
via pip
, but it's still preferable to doing it manually.它不像能够通过
pip
升级ensurepip
那样优雅,但它仍然比手动升级ensurepip
可取。
https://pypi.org/project/upgrade-ensurepip/ https://pypi.org/project/upgrade-ensurepip/
It is an expected behavior.这是预期的行为。
python -m venv
calls python -m ensurepip
to install pip
and This answer shows that ensurepip
would only install the bundled version even with --upgrade
option. python -m venv
调用python -m ensurepip
来安装pip
并且这个答案表明即使使用--upgrade
选项, ensurepip
也只会安装捆绑版本。 There isn't any official option to update the bundled pip
and setuptools
.没有任何官方选项来更新捆绑的
pip
和setuptools
。
Well I have also no good idea to fix this problem as it just is the designed behavior.好吧,我也没有解决这个问题的好主意,因为它只是设计的行为。 I would like to give two suggestions:
我想给出两个建议:
Use pipenv
.使用
pipenv
。 It is really good!真的很好! And it will be the next-generation official package manager in the future(Although there is a big problem related to current Pypi's structure. In short, a package manager can only decide the dependencies with downloading the whole package. This gives a huge difficulty to building dependencies graph.).
并且未来会是下一代官方的包管理器(虽然目前Pypi的结构有很大的问题。总之,包管理器只能通过下载整个包来决定依赖。这给了一个巨大的难度构建依赖关系图。)。
Implement your custom EnvBuilder
, actually there is an official example about this.实现您的自定义
EnvBuilder
,实际上有一个关于此的官方示例。 And in the example, it also use get-pip.py
to install the latest pip
.在示例中,它还使用
get-pip.py
来安装最新的pip
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.