Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract dependencies information from a setup.py

I have a python project, let's call it foobar, there is a setup.py script in project root directory like all Python projects. For example

  • foobar
    • setup.py

setup.py file content:

from ez_setup import use_setuptools
use_setuptools()

from setuptools import setup, find_packages
setup(
    name='foobar',
    version='0.0.0',
    packages=find_packages(),
    install_requires=[
        'spam==1.2.3',
        'eggs>=4.5.6',
    ],
)

I need to get dependencies information from that setup.py file using Python. The part I want would be

[
    'spam==1.2.3',
    'eggs>=4.5.6',
]

in the example above. I don't want to install this package, all I need is the dependencies information. Certainly, I can use regular expression to parse it, but that would be ugly, I can also use Python AST to parse it, but I think there should already be some tool can do this. What is the best way to do so?

like image 415
Fang-Pen Lin Avatar asked Jun 16 '14 03:06

Fang-Pen Lin


People also ask

How do I see dependencies in PyPI?

The dependencies of the installed Python packages can be listed using the built-in pip show command. Alternatively the dependencies can be shown as a tree structure using the pipdeptree command. In this note i will show several examples of how to list dependencies of the installed Python packages.

Does pip use setuptools?

Even for projects that do choose to use distutils , when pip installs such projects directly from source (rather than installing from a prebuilt wheel file), it will actually build your project using setuptools instead.


2 Answers

You can use distutils.core's run_setup:

from distutils.core import run_setup

result = run_setup("./setup.py", stop_after="init")
result.install_requires
['spam==1.2.3', 'eggs>=4.5.6']

This way there is no need to mock anything and you can potentially extract more information about the project than would be possible by mocking the setup() call.

Note that this solution might be problematic as there apparently is active work being done to deprecate distutils. See comments for details.

like image 130
Jan Wegger Avatar answered Oct 19 '22 11:10

Jan Wegger


It seems to me that you could use mock to do the work (assuming that you have it installed and that you have all the setup.py requirements...). The idea here is to just mock out setuptools.setup and inspect what arguments it was called with. Of course, you wouldn't really need mock to do this -- You could monkey patch setuptools directly if you wanted ...

import mock  # or `from unittest import mock` for python3.3+.
import setuptools

with mock.patch.object(setuptools, 'setup') as mock_setup:
    import setup  # This is setup.py which calls setuptools.setup

# called arguments are in `mock_setup.call_args`
args, kwargs = mock_setup.call_args
print kwargs.get('install_requires', [])
like image 23
mgilson Avatar answered Oct 19 '22 12:10

mgilson