For a given conda
package, how to I list the packages that depend on it?
I recently installed anaconda on a university cluster that al
With recent versions of conda, you can do
conda remove --dry-run <package>
to get a list of packages that would be uninstalled along with the given one.
Shameless plug: conda-depgraph can do this fairly easily:
$ conda depgraph --from-channels in mpich2
┌────────┐
│anaconda│
└───┬─┬──┘
│ │
│ └──┐
v │
┌──────┐ │
│mpi4py│ │
└──┬───┘ │
│ ┌───┘
│ │
v v
┌──────┐
│mpich2│
└──────┘
conda search --reverse-dependency <package>
should be the answer. Except it's not working. Please vote on this issue to show that it's important to users. It's been reported in Jan-18 and there has been no change in status. Hopefully if enough votes is gathered it'll be looked at. Or perhaps someone could submit a PR to fix it.
Until then you may have a partial solution using pipdeptree if pip's version of the package's reverse dependencies are identical to conda's version, which is often not the case. But at least it will give you some indication.
pipdeptree --reverse --packages <package>
conda info
will tell you the directory (or directories) where your package cache
is located. These directories contain a unique directory for each package, and each package directory contains an info
directory and a file called index.json
. There is a requires
field in each of these files that refers to a list of conda
dependencies. So in short, you need to search these files for the package you're trying to remove.
For example, if anaconda
's installed in my home directory, and therefore the package cache is ~/anaconda/pkgs
, to find mpich2
's dependents, I would:
grep mpich2 ~/anaconda/pkgs/*/info/index.json
You will see 2 lines for the anaconda
package, because mpich2
is both in the aforementioned requires
list and in a list called depends
. You'll also see one line for each mpich2
package available, because there is also a name
field for each package. Then you'll see one or more lines for each package that depends on, requires mpich2
. My search produced only mpi4py
.
Now I thought you could do a --dry-run
remove, but it appears that remove
does not remove dependents, so nothing special is listed.
If grep
is unavailable, then I'm sure you could make a python script to do the same thing, using say the glob
module and maybe even json
to do the searching.
Based on Yann's answer, code diving in conda core and reading this I came up with the following script to get a reverse-dependency graph of all cached channels:
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']))
Now you can get the reverse dependencies of a specific package:
>>> print(rdeps['mpich2'])
set()
Well, right now nothing depends on it anymore... But if you run it in ipython or Jupyter, you can then quickly query the reverse dependencies, e.g.:
>>> print(rdeps['aiosqlite'])
{('databases', 'https://conda.anaconda.org/conda-forge/linux-64')}
You get the package name (without versions, of which there may be many), and the channel URL (which can show you, if it's pkgs/main/(arch)
or conda-forge
etc.
Searching the package cache will only show you the packages that you have downloaded already. For your case, this behavior is fine, but if you want to know every package that depends on a given package, a better way is to search the repodata of your channels. The repodata is cached in ~/anaconda/pkgs/cache
, or you can navigate with your browser to http://repo.continuum.io/pkgs/free/ and click on repodata.json
for the platform you use (for Binstar, go to, e.g., https://conda.binstar.org/asmeurer). Then search for the name of the package in the "depends" key.