23

Say that python package A requires B, C and D; is there a way to list A → B C D without loading them ?
Requires in the metadata (yolk -M A) are often incomplete, grr.
One can download A.tar / A.egg, then look through A/setup.py, but some of those are pretty gory.

(I'd have thought that getting at least first-level dependencies could be mechanized; even a 98 % solution would be better than avalanching downloads.)

A related question: pip-upgrade-package-without-upgrading-dependencies

Community
  • 1
  • 1
denis
  • 21,378
  • 10
  • 65
  • 88

3 Answers3

31

Snakefood

sfood -fuq package.py | sfood-target-files 

will list the dependencies.

`-f` tells sfood to follow dependencies recursively
`-u` tells sfood to ignore unused imports
`-q` tells sfood to be quiet about debugging information

To filter out modules from the standard library, you could use

sfood -fuq package.py | sfood-filter-stdlib | sfood-target-files 

As you've already noted, if there are other directories you'd like ignored, you can also use the sfood -I flag.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • looks reasonable, +1. sfoodxx -I /Library/...python2.6 (mac) doesn't filter out standard imports sys, os.path etc. ? – denis May 21 '10 at 15:59
  • @Denis: Use `sfood-filter-stdlib` to remove entries from the Python standard library. I'll edit my answer to include this... – unutbu May 21 '10 at 16:26
  • 1
    sfood-filter-stdlib has '/usr/lib/python' hardwired in, and doesn't work for sfood-imports. Am asking the author ... Bytheway Kevin Teague, "I want a pony" http://groups.google.com/group/django-developers/msg/5407cdb400157259 is an outstanding overview of packaging methods in 2008.) – denis May 24 '10 at 12:02
  • @Denis: Thanks; that's a great link. – unutbu May 24 '10 at 14:38
  • sfood-target-files is not available on Ubuntu 13.04 – Konstantin Jul 17 '15 at 08:28
  • @Konstantin: That's odd. [It is in Ubuntu 12.04](http://packages.ubuntu.com/search?suite=precise&arch=any&mode=exactfilename&searchon=contents&keywords=sfood-target-files) and [also in 14.04](http://packages.ubuntu.com/search?suite=trusty&arch=any&mode=exactfilename&searchon=contents&keywords=sfood-target-files). You might try the [installation instructions per the documentation](http://furius.ca/snakefood/doc/snakefood-doc.html#installation) or upgrading to a supported version of Ubuntu. – unutbu Jul 17 '15 at 09:43
  • @Konstantin: `sfood-target-files` is in the distribution (at least for 14.04), as unutbu says; however, it is not linked to /usr/bin. It is in /usr/share/snakefood. Same for `sfood-filter-stdlib`. All tools mentioned in the [docs](http://furius.ca/snakefood/#tools-included) are linked in /usr/bin (by default install). – Bonlenfum Aug 25 '15 at 10:49
13

modulefinder from the standard lib

New in version 2.3.

This module provides a ModuleFinder class that can be used to determine the set of modules imported by a script. modulefinder.py can also be run as a script, giving the filename of a Python script as its argument, after which a report of the imported modules will be printed.

I am not sure if it complies with your requierement about not loading the modules. From here:

modulefinder use bytecode inspection to find dependencies, and therefore is free from any side-effects that may be caused by importing the modules being studied.

Other hints about the use of pylint or Gui2exe here

joaquin
  • 82,968
  • 29
  • 138
  • 152
  • 3
    modulefinder does work but it will show a lot of useless stuff and indirect dependencies (dependencies that MAY be used by your dependencies, but actually are not). You can find an example script I did using modulefinder here: https://gist.github.com/lrq3000/6175634 And an alternative script using an AST parsing approach here (and which works way better for me): https://gist.github.com/lrq3000/6175522 – gaborous Aug 07 '13 at 16:31
6

If by package you mean a pip installed package (and not a directory with an __init__.py), then you can use the Python package called pip. For example:

def get_all_package_dependencies():
    """Return dictionary of installed packages to list of package dependencies."""
    return {
        dist.key: [r.key for r in dist.requires()]
        for dist in pip.get_installed_distributions()
    }
  • I see a package on the web and want to know its deps. There's `pip install --no-deps`, then dig around ... or are there newer pip commands to list-deps ? (Requirements files are most often just not there.) – denis Aug 06 '13 at 10:07
  • and pprint can be used to pretty print the output produced by above snippet – binithb Jul 28 '17 at 12:16
  • 1
    `get_installed_distributions` is now [deprecated](https://stackoverflow.com/questions/49923671/are-there-any-function-replacement-for-pip-get-installed-distributions-in-pip). – Amit Naidu Dec 18 '19 at 02:43