Conda remove命令卸载的软件包数量超出预期

3
简化的 MWE => 假设我有 Anaconda 并执行以下操作:
conda create -n demo python=3.6
conda activate demo
conda install seaborn

最后一个命令安装了39个新的软件包,包括seabornmatplotlibpandas。现在假设时间过去了,我继续设置我的环境并希望明确地安装matplotlibpandas

conda install matplotlib pandas

这告诉我"所有请求的软件包已经安装",这很好。现在,如果我决定不再需要seaborn并将其移除,
conda remove seaborn

这会删除安装 seaborn 时安装的全部39个软件包,包括在此之后我明确安装的 matplotlibpandas!我该如何避免这个问题?

我期望的行为是 conda remove seaborn 只删除 seaborn 及其依赖项,但不会删除任何在 seaborn 之前或之后明确安装的软件包(或其依赖项)。有些人可能会建议卸载 seaborn 和所有39个软件包,然后手动重新安装 matplotlibpandas。这在简单情况下可行,但一旦有25个具有复杂相互依赖关系的软件包,这将变得非常复杂,至少对维护来说是完全的麻烦。

作为一个具体的例子,我该如何构建一个完整的 Anaconda 环境,去掉特定的软件包以及仅包含依赖于它的软件包?我尝试过:

conda create -n test python=3.6 anaconda
conda remove libtiff  # I want this to strictly only remove libtiff and its recursive dependents, but obviously this is not what happens

但第二行会移除整个环境中几乎所有的软件包,因为它会移除anaconda。有什么想法吗?


这是令人惊讶的行为。我会在代码库上报告此问题。首先,当已经存在时,Conda无法将请求的软件包添加到显式规范中(注意:你可以使用--force-reinstall强制执行此操作,例如对于matplotlib,但我认为它应该默认执行)。其次,当调用conda remove时,Conda似乎会积极地修剪显式规范。要使conda env update命令像这样工作,需要显式添加--prune标志,因此类似的功能应该被添加到conda remove中。 - merv
顺便说一下,通过“明确的规范”,我指的是Conda从其事务历史(conda-meta/history)中获取的包规范的内部列表。这些是你明确要求在你的仓库中的内容。当你运行conda env export --from-history时,基本上会得到它的一个YAML副本。 - merv
是的,conda remove的行为似乎与合理预期不符。假设现在conda的行为仍然保持不变,我还有办法绕过它来实现我所描述的吗? - pallgeuer
1个回答

1

解决方法

我想不出一种自动化的方法来做到这一点,但如果你非常需要实现这个功能,那么一个可行的办法是:

  • 只删除您想要的软件包:

    conda remove --force libtiff
    
  • 触发一致性检查以获取现在损坏的软件包列表:

    conda install -d python
    
  • 如果有软件包,则重复执行(即使用步骤1删除它们);否则,您已完成。

  • 实际上,你还没有完成,因为现在每次尝试更改环境时,所有不是显式规范依赖的软件包都会被建议移除。下一步可能是:
    4. 导出生成的环境: ``` conda env export -n my_env > env.yaml ```
    5. 重新创建环境: ``` conda env remove -n my_env conda env create -n my_env -f env.yaml ```
    现在所有的软件包都将是明确的规范,这并不一定是件好事,但至少确保它们不会在后续更新中被删除。
    评论
    个人而言,我认为这是一个坏主意,也不太理解其动机。我认为更好的做法是从你知道需要的软件包开始,将它们放在一个YAML定义中,并从中创建环境。

    也许先导出并重新创建环境,然后再移除libtiff会更高效一些吗?这样做能否在不进行递归步骤1-3的情况下达到相同的效果?另外,在我提出的第一个问题中,有没有办法解决卸载软件包时自动删除我明确安装的软件包的问题? - pallgeuer
    @pallgeuer 你可能是对的。另外一件事,使用 --force-reinstall 参数来安装你想要添加到规范中的软件包。 - merv

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接