Как определить зависимых от пакета 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-spectra
package в 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
и т.п.