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

新手上路,请多包涵

我正在处理一个遗留的 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

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

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

这导致我的设置中出现以下问题。例如,首先 apt 安装 python-numpy 。后来 pip 尝试从例如 --- 安装新版本的 numpy /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.

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

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

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

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

我一直在兜圈子,试图提出一个好的解决方案,该解决方案涉及对这个遗留 Dockerfile 的最小更改,并允许我们使用该文件部署的应用程序继续像以前一样运行。关于如何安全地解决 pip 10 无法安装更新版本的 distutils 软件包的问题的任何建议?谢谢!

更新:

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

原文由 elethan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 906
2 个回答

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

我所要做的就是添加

--ignore-installed

到我的 dockerfile 中引发错误的 pip install 行。使用我原始问题中的相同 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

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

更新:

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

原文由 elethan 发布,翻译遵循 CC BY-SA 4.0 许可协议

这对我有用——

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

或者

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

或(在 jupyter 笔记本内)

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

原文由 Archie Jain 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题