Python pip 10 和 apt:如何避免 distutils 包的“无法卸载 X”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49932759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 19:18:58  来源:igfitidea点击:

pip 10 and apt: how to avoid "Cannot uninstall X" errors for distutils packages

pythondockerpipdistutilsapt

提问by elethan

I am dealing with a legacy Dockerfile. Here is a very simplifiedversion of what I am dealing with:

我正在处理旧的 Dockerfile。这是我正在处理的非常简化的版本:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt # includes e.g., numpy==1.13.0
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

First, several packages are installed using apt, and then several packages are installed using pip. pipversion 10 has been released, and part of the releaseis this new restriction:

首先,使用 安装几个包apt,然后使用 安装几个包pippip版本 10 已经发布,发布的一部分是这个新限制:

Removed support for uninstalling projects which have been installed using distutils. distutils installed projects do not include metadata indicating what files belong to that install and thus it is impossible to actually uninstall them rather than just remove the metadata saying they've been installed while leaving all of the actual files behind.

删除了对卸载使用 distutils 安装的项目的支持。distutils 安装的项目不包含指示哪些文件属于该安装的元数据,因此不可能实际卸载它们,而不仅仅是删除元数据,表明它们已安装,同时留下所有实际文件。

This leads to the following problem in my setup. For example, first aptinstalls python-numpy. Later piptries to install a newer version of numpyfrom e.g., /tmp/requirements1.txt, and tries to uninstall the older version, but because of the new restriction, it cannot remove this version:

这导致我的设置中出现以下问题。例如,首先apt安装python-numpy. 后来pip尝试安装较新版本的numpyfrom eg, /tmp/requirements1.txt,并尝试卸载旧版本,但由于新限制,无法删除此版本:

Installing collected packages: numpy
  Found existing installation: numpy 1.8.2
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

Now I know at this point there are several solutions.

现在我知道在这一点上有几种解决方案。

I could not install python-numpythrough apt. However, this causes issues because python-numpyinstalls a few different packages as requirements, and I do not know if another part of the system relies on these packages. And in reality, there are several aptpackages installed through the Dockerfile, and each one I remove seems to reveal another Cannot uninstall Xerror, and removes a number of other packages along with it, that our app may or may not rely on.

我无法python-numpy通过apt. 但是,这会导致问题,因为需要python-numpy安装几个不同的包,我不知道系统的其他部分是否依赖这些包。实际上,apt通过 Dockerfile 安装了多个包,我删除的每个包似乎都揭示了另一个Cannot uninstall X错误,并同时删除了许多其他包,我们的应用程序可能依赖也可能不依赖这些包。

I could also use the --ignore-installedoption when I try to pipinstall things that have already been installed through apt, but then again I have the same problem of every --ignore-installedargument revealing yet another thing that needs to be ignored.

--ignore-installed当我尝试pip安装已经通过 安装的东西时,我也可以使用该选项,但是我又遇到apt了同样的问题,每个--ignore-installed参数都揭示了另一个需要忽略的东西。

I could pin pipat an older version that does not have this restriction, but I don't want to be stuck using an outdated version of pipforever.

我可以pip使用没有此限制的旧版本,但我不想使用过时的pip永远版本。

I have been going around in circles trying to come up with a good solution that involves minimal changes to this legacy Dockerfile, and allows the app we deploy with that file to continue to function as it has been. Any suggestions as to how I can safely get around this problem of pip10 not being able to install newer versions of distutilspackages? Thank you!

我一直在兜兜转转,试图提出一个好的解决方案,该解决方案只对这个遗留 Dockerfile 进行最少的更改,并允许我们使用该文件部署的应用程序继续按原样运行。关于如何安全地解决pip10 无法安装较新版本distutils软件包的问题有什么建议吗?谢谢!

UPDATE:

更新:

I did not realize that --ignore-installedcould be used without a package as an argument to ignore all installed packages. I am considering whether or not this might be a good option for me, and have asked about it here.

我没有意识到--ignore-installed可以在没有包的情况下用作忽略所有已安装包的参数。我正在考虑这对我来说是否是一个不错的选择,并在这里询问了它。

回答by elethan

This is the solution I ended up going with, and our apps have been running in production without any issues for close to a month with this fix in place:

这是我最终采用的解决方案,我们的应用程序已经在生产环境中运行了近一个月,没有任何问题,并进行了此修复:

All I had to do was to add

我所要做的就是添加

--ignore-installed

--ignore-installed

to the pip installlines in my dockerfile that were raising errors. Using the same dockerfile example from my original question, the fixed dockerfile would look something like:

pip install我的 dockerfile 中引发错误的行。使用与我原来的问题相同的 dockerfile 示例,固定的 dockerfile 看起来像:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt --ignore-installed # don't try to uninstall existing packages, e.g., numpy
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

The documentation I could find for --ignore-installedwas unclear in my opinion (pip install --helpsimply says "Ignore the installed packages (reinstalling instead)."), and I asked about the potential dangers of this flag here, but have yet to get satisfying answer. However, if there are any negative side effects, our production environment has yet to see the effects of them, and I think the risk is low/none (at least that has been our experience). I was able to confirm that in our case, when this flag was used, the existing installation was not uninstalled, but that the newer installation was always used.

--ignore-installed我认为我能找到的文档不清楚(pip install --help只是说“忽略已安装的包(重新安装)。”),我在这里询问了这个标志的潜在危险,但还没有得到令人满意的答案。但是,如果有任何负面影响,我们的生产环境还没有看到它们的影响,我认为风险很低/没有(至少这是我们的经验)。我能够确认在我们的例子中,当使用这个标志时,现有的安装没有被卸载,而是总是使用较新的安装。

Update:

更新:

I wanted to highlight thisanswer by @ivan_pozdeev. He provides some information that this answer does not include, and he also outlines some potential side-effects of my solution.

我想通过@ivan_pozdeev强调这个答案。他提供了此答案未包含的一些信息,并概述了我的解决方案的一些潜在副作用。

回答by Archie Jain

This is what worked for me--

这对我有用——

pip install --ignore-installed <Your package name>

or

或者

sudo pip install --ignore-installed <Your package name>

or (inside jupyter notebook)

或(在 jupyter 笔记本内)

import sys
!{sys.executable} -m pip install --ignore-installed <Your package name>

回答by Prasann

For windows write

对于 windows 写

conda update --all pip install --upgrade <Your package name>

conda update --all pip install --upgrade <Your package name>

OR

或者

conda update --all pip install <Your package name>

conda update --all pip install <Your package name>

OR

或者

pip install wrapt --upgrade --ignore-installed pip install <Your package name>

pip install wrapt --upgrade --ignore-installed pip install <Your package name>

from ERROR: Cannot uninstall 'wrapt'. during upgrade

来自错误:无法卸载“wrapt”。升级期间

回答by Moharnab Saikia

You can just remove numpy manually but keep the other dependencies installed by apt. Then use pip as before to install the latest version of numpy.

您可以手动删除 numpy,但保留 apt 安装的其他依赖项。然后像以前一样使用pip安装最新版本的numpy。

#Manually remove just numpy installed by distutils
RUN rm /usr/lib/python2.7/dist-packages/numpy-1.8.2.egg-info
RUN rm -r /usr/lib/python2.7/dist-packages/numpy

RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt

The location of numpy should be the same. But if you want to confirm the location you can run the container without running the requirements.txt files and issue the following commands in the python console inside the container.

numpy 的位置应该是一样的。但是如果你想确认位置,你可以在不运行 requirements.txt 文件的情况下运行容器,并在容器内的 python 控制台中发出以下命令。

>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc