Как определить зависимых от пакета conda?

Для данного conda пакет, как я могу перечислить пакеты, которые зависят от него?

Недавно я установил анаконду в университетский кластер, который уже имел версию MPI (openmpi). mpich2 пакет и mpi4py пакеты, установленные с помощью anaconda, были хороши для демонстраций mpi4py, но mpi* компиляторы (mpicc и т. д.) не были совместимы. Так что я conda remove d" mpich2 а также mpi4py и использовал pip установить mpi4py с использованием локальной установки MPI и компиляторов.

Я должен был покопаться, чтобы найти mpi4py Зависимости, а затем mpich2 иждивенцы, для которых я только определил mpi4py, Есть ли "простой" способ узнать, что зависит от mpich2 ?

8 ответов

Решение

Поиск в кэше пакетов покажет только те пакеты, которые вы уже скачали. В вашем случае это нормально, но если вы хотите знать каждый пакет, который зависит от данного пакета, лучшим способом будет поиск по реподанным ваших каналов. Реподанные кешируются в ~/anaconda/pkgs/cacheили вы можете перейти в браузере по http://repo.continuum.io/pkgs/free/ и нажать на repodata.json для используемой вами платформы (для Binstar перейдите, например, по https://conda.binstar.org/asmeurer). Затем найдите имя пакета в ключе "зависит".

conda info скажет вам каталог (или каталоги), где ваш package cache расположен. Эти каталоги содержат уникальный каталог для каждого пакета, и каждый каталог пакета содержит info каталог и файл с именем index.json, E сть requires поле в каждом из этих файлов, которое ссылается на список conda зависимостей. Короче говоря, вам нужно найти в этих файлах пакет, который вы пытаетесь удалить.

Например, если anacondaустановлен в моем домашнем каталоге, и поэтому кеш пакетов ~/anaconda/pkgs, найти mpich2иждивенцы, я бы:

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

Вы увидите 2 строки для anaconda пакет, потому что mpich2 как в вышеупомянутом requires список и в списке под названием depends, Вы также увидите одну строку для каждого mpich2 пакет доступен, потому что есть также name поле для каждой упаковки. Затем вы увидите одну или несколько строк для каждого пакета, который зависит от, требует mpich2, Мой поиск произвел только mpi4py,

Теперь я думал, что вы могли бы сделать --dry-run удалить, но кажется, что remove не удаляет иждивенцев, поэтому ничего особенного в списке нет.

Если grep недоступен, тогда я уверен, что вы могли бы сделать скрипт Python, чтобы сделать то же самое, используя, скажем, globмодуль и, возможно, даже json сделать поиск.

С последними версиями conda вы можете сделать

conda remove --dry-run <package>

получить список пакетов, которые будут удалены вместе с указанным.

conda search --reverse-dependency <package>

должен быть ответ. За исключением того, что это не работает. Пожалуйста, проголосуйте по этому вопросу, чтобы показать, что это важно для пользователей. Об этом сообщалось в 18 января, и статус не изменился. Надеюсь, что если будет набрано достаточное количество голосов, оно будет рассмотрено. Или, возможно, кто-то может представить PR, чтобы исправить это.

До этого у вас может быть частичное решение, использующее pipdeptree, если версия pip обратных зависимостей пакета идентична версии conda, что часто не имеет место. Но, по крайней мере, это даст вам некоторое представление.

pipdeptree --reverse --packages <package>

mamba repoquery

Хотя Mamba в первую очередь является заменой Conda, одной из дополнительных функций, которые она предоставляет, является надежная функциональность для запросов зависимостей и обратной зависимости через ееrepoqueryкоманда . Однако обратите внимание, что это относится только к отношениям на уровне среды, поэтому необходимо установить пакеты и активировать среду.

Демо

Обратите внимание, что это несколько лет от исходного вопроса, поэтому я просто покажу демонстрацию с 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

Оказалось r-spectrapackage в Conda Forge ошибочно указал, что одна из его зависимостей является пакетом Python ( spectra), а не динамическая библиотека C++ ( spectralib).

Для этого есть пакет : condaconda-tree . Документация .

Чтобы найти пакеты, зависящие от пакета:

      # 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]
...

Бесстыдная вилка: conda-depgraph может сделать это довольно легко:

$ conda depgraph --from-channels in mpich2

 ┌────────┐
 │anaconda│
 └───┬─┬──┘
     │ │
     │ └──┐
     v    │
 ┌──────┐ │
 │mpi4py│ │
 └──┬───┘ │
    │ ┌───┘
    │ │
    v v
 ┌──────┐
 │mpich2│
 └──────┘

Основываясь на ответе Янна, погружении кода в ядро ​​conda и чтении этого, я придумал следующий сценарий, чтобы получить график обратной зависимости всех кэшированных каналов:

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 и т.п.

Другие вопросы по тегам