【问题标题】:How to identify conda package dependents?如何识别 conda 包依赖项?
【发布时间】:2014-09-29 14:13:34
【问题描述】:

对于给定的conda 包,我如何列出依赖它的包?

我最近在一个已经有 MPI (openmpi) 版本的大学集群上安装了 anaconda。与 anaconda 一起安装的 mpich2 软件包和 mpi4py 软件包适用于 mpi4py 的演示,但 mpi* 编译器(mpicc 等)不兼容。所以我 conda remove'd mpich2mpi4py 并使用 pip 使用本地 MPI 安装和编译器安装 mpi4py

我不得不四处寻找mpi4py 的依赖项,然后找到mpich2 的依赖项,为此我只确定了mpi4py是否有一种“简单”的方法可以找出依赖于 mpich2 的内容?

【问题讨论】:

  • 解析你关于 MPI 的故事是否有必要理解你的问题,或者你的开场白是否涵盖了它?
  • @duozmo 我猜开场白已经涵盖了它,但我通常喜欢为我的问题提供背景信息,以防我问的问题不正确。
  • 不反对提供上下文。这只是一个相当复杂的场景,我花了很多时间试图弄清楚我们是否有同样的问题(你的开场白)。

标签: conda


【解决方案1】:

conda info 将告诉您您的package cache 所在的目录(或多个目录)。这些目录包含每个包的唯一目录,每个包目录包含一个info 目录和一个名为index.json 的文件。每个文件中都有一个requires 字段引用conda 依赖项列表。简而言之,您需要在这些文件中搜索您要删除的包。

例如,如果anaconda 安装在我的主目录中,因此包缓存为~/anaconda/pkgs,要查找mpich2 的家属,我会:

grep mpich2 ~/anaconda/pkgs/*/info/index.json

您将看到anaconda 包的两行,因为mpich2 既位于上述requires 列表中,又位于名为depends 的列表中。您还将看到每个可用的 mpich2 包对应一行,因为每个包还有一个 name 字段。然后你会看到每个依赖包的一行或多行,需要mpich2。我的搜索只产生了mpi4py

现在我认为您可以执行 --dry-run 删除,但似乎 remove 不会删除家属,因此没有列出任何特殊内容。

如果grep 不可用,那么我相信您可以制作一个python 脚本来做同样的事情,使用globmodule 甚至json 来进行搜索。

【讨论】:

  • 关于conda info的有用提示!另请注意 - 如果您想使用此信息编写脚本,请查看 conda info --json
【解决方案2】:
conda search --reverse-dependency <package>

应该是答案。除了它不工作。请对此issue 投票,以表明它对用户很重要。已于 1 月 18 日报告,状态没有变化。希望如果收集到足够的选票,它将被关注。或者也许有人可以提交 PR 来修复它。

在此之前,如果 pip 的包反向依赖的版本与 conda 的版本相同,那么您可能会使用 pipdeptree 获得部分解决方案,但通常情况并非如此。但至少它会给你一些指示。

pipdeptree --reverse --packages <package>

【讨论】:

    【解决方案3】:

    使用最新版本的 conda,您可以这样做

    conda remove --dry-run <package>
    

    获取将与给定软件包一起卸载的软件包列表。

    【讨论】:

      【解决方案4】:

      搜索包缓存只会显示您已经下载的包。对于您的情况,这种行为很好,但是如果您想知道依赖于给定包的每个包,更好的方法是搜索频道的 repodata。 repodata 缓存在~/anaconda/pkgs/cache,或者您可以使用浏览器导航到http://repo.continuum.io/pkgs/free/,然后单击您使用的平台的repodata.json(对于Binstar,请转到例如https://conda.binstar.org/asmeurer)。然后在“depends”键中搜索包的名称。

      【讨论】:

      • 很高兴能在网上轻松获取这些信息。
      • 现在就是这样! :)
      • 很好的答案,我见过的大多数回购也有repodata.json.bz2,它的下载速度更快。除了 JSON 中的几个键之外,缓存中的数据几乎相同,例如 _url_mod_cache_control - 如果没有这些信息,我不知道这是用于哪个通道的(缓存 JSON 文件名是一些模糊的哈希)。
      【解决方案5】:

      无耻的插件:conda-depgraph 可以很容易地做到这一点:

      $ conda depgraph --from-channels in mpich2
      
       ┌────────┐
       │anaconda│
       └───┬─┬──┘
           │ │
           │ └──┐
           v    │
       ┌──────┐ │
       │mpi4py│ │
       └──┬───┘ │
          │ ┌───┘
          │ │
          v v
       ┌──────┐
       │mpich2│
       └──────┘
      

      【讨论】:

        【解决方案6】:

        根据 Yann 的回答,在 conda 核心中潜入代码并阅读 this 我想出了以下脚本来获取所有缓存通道的反向依赖图:

        import glob
        import json
        import os
        
        from collections import defaultdict
        
        info = json.load(os.popen('conda info --json'))
        
        print('Loading channels...')
        channels = [
            json.load(open(repodata))
            for pkg_dir in info['pkgs_dirs']
            for repodata in glob.glob(os.path.join(pkg_dir, 'cache', '*.json'))
        ]
        print('Done')
        
        rdeps = defaultdict(set)
        
        for c in channels:
            for k, v in c['packages'].items():
                package = '-'.join(k.split('-')[:-2])
                for dep in v['depends']:
                    dependant = dep.split()[0]
                    rdeps[dependant].add((package, c['_url']))
        

        现在可以获取特定包的反向依赖了:

        >>> print(rdeps['mpich2'])
        set()
        

        好吧,现在什么都不再依赖它了...但是如果你在 ipython 或 Jupyter 中运行它,你可以快速查询反向依赖关系,例如:

        >>> print(rdeps['aiosqlite'])
        {('databases', 'https://conda.anaconda.org/conda-forge/linux-64')}
        

        你会得到包名(没有版本,可能有很多版本)和频道 URL(可以显示你,如果它是 pkgs/main/(arch)conda-forge 等。

        【讨论】:

        • $ conda_rd () { python -c 'from reverse_dependency import rdeps; print(rdeps['$1'])' ; }
        • 这是一个不错的 bash 函数!我们只需要让这个模块可以从任何地方导入。
        【解决方案7】:

        为此有一个 conda 包:conda-treeDocumentation.

        要查找依赖于某个包的包:

        # which packages depend on a specific package
        $ conda-tree whoneeds xz
        ['samtools', 'bcftools', 'htslib', 'python']
        

        你也可以转储整个依赖树,然后搜索:

        # full dependency tree
        $ conda-tree deptree --full
        neovim==0.3.1
          ├─ pynvim 0.3.2 [required: any]
          │  ├─ greenlet 0.4.15 [required: any]
        ...
        

        【讨论】:

          【解决方案8】:

          mamba repoquery

          虽然Mamba 主要是 Conda 的替代品,但它提供的额外功能之一是通过其repoquery command 进行依赖和反向依赖查询的可靠功能。但是请注意,这仅适用于环境级别的关系,因此必须安装包并激活环境。

          演示

          请注意,这与最初的问题相去甚远,所以我只是通过mpi4py 安装演示并使用已安装的版本。

          $ mamba create -n so-mpi4py mpi4py
          ## installs 24 packages
          
          $ conda activate so-mpi4py
          (so-mpi4py) $ mamba repoquery whoneeds mpich
                            __    __    __    __
                           /  \  /  \  /  \  /  \
                          /    \/    \/    \/    \
          ███████████████/  /██/  /██/  /██/  /████████████████████████
                        /  / \   / \   / \   / \  \____
                       /  /   \_/   \_/   \_/   \    o \__,
                      / _/                       \_____/  `
                      |/
                  ███╗   ███╗ █████╗ ███╗   ███╗██████╗  █████╗
                  ████╗ ████║██╔══██╗████╗ ████║██╔══██╗██╔══██╗
                  ██╔████╔██║███████║██╔████╔██║██████╔╝███████║
                  ██║╚██╔╝██║██╔══██║██║╚██╔╝██║██╔══██╗██╔══██║
                  ██║ ╚═╝ ██║██║  ██║██║ ╚═╝ ██║██████╔╝██║  ██║
                  ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝╚═════╝ ╚═╝  ╚═╝
          
                  mamba (0.19.0) supported by @QuantStack
          
                  GitHub:  https://github.com/mamba-org/mamba
                  Twitter: https://twitter.com/QuantStack
          
          █████████████████████████████████████████████████████████████
          
          
          Executing the query mpich
          
          
          
           Name   Version Build           Depends              Channel           
          ────────────────────────────────────────────────────────────────────────
           mpi4py 3.1.3   py310hd348148_0 mpich >=3.4,<4.0.0a0 conda-forge/osx-64
          

          就个人而言,我通常使用树格式,与

          (so-mpi4py) $ mamba repoquery whoneeds --tree mpich
          
          mpich[3.4.2]
            └─ mpi4py[3.1.3]
          

          现实世界的例子

          更多地证明了它的实用性,我注意到我的一个 R 环境不知何故最终安装了 Python。我对此很严格,所以我联系了mamba repoquery whoneeds,发现:

          (bioc_3_12) host:dir usr$ mamba repoquery whoneeds -t python
          
          Executing the query python
          
          python[3.9.2]
            ├─ numpy[1.20.2]
            │  └─ colormath[3.0.0]
            │     └─ spectra[0.0.11]
            │        └─ r-rspectra[0.16_0]     # <- this package is the culprit!
            │           └─ r-uwot[0.1.10]
            ├─ networkx[2.5]
            │  └─ colormath already visited
            ├─ certifi[2021.5.30]
            │  └─ setuptools[49.6.0]
            │     ├─ networkx already visited
            │     └─ pip[21.0.1]
            ├─ python_abi[3.9]
            │  ├─ numpy already visited
            │  ├─ certifi already visited
            │  └─ setuptools already visited
            ├─ colormath already visited
            ├─ spectra already visited
            ├─ decorator[4.4.2]
            │  └─ networkx already visited
            ├─ wheel[0.36.2]
            │  └─ pip already visited
            ├─ pip already visited
            └─ setuptools already visited
          

          原来 Conda Forge 中的 r-spectra 包配方让 misstated one of its dependencies 成为 Python 包 (spectra) 而不是 C++ 动态库 (spectralib)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-01-24
            • 1970-01-01
            • 1970-01-01
            • 2021-03-27
            • 2023-01-18
            • 2021-04-16
            • 2016-11-05
            • 2013-08-21
            相关资源
            最近更新 更多