Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle dependency on scipy in setup.py

I am trying to create a setup.py for a project that depends on SciPy. The following setup.py reproduces this:

setup(
    name='test',
    version='0.1',
    install_requires=['scipy']
)

When installing this using python setup.py develop it generates the following error:

ImportError: No module named numpy.distutils.core

However, when I install scipy using pip, it installed it from a wheel, and it works just fine.

So, my questions is, how can I create a setup.py that depends on SciPy? Why won't setuptools install dependencies from wheels? Would this work better when using Python 3 (we plan to migrate anyway, so if it works there, I'll just wait until the migration is complete).

I am using Python 2.7.8 on Mac OS X 10.10.1 with setuptools 3.6 and pip 1.5.6.

like image 632
Björn Pollex Avatar asked Nov 19 '14 15:11

Björn Pollex


People also ask

How do you manage dependencies in Python?

Using venv and pipenv are two methods of managing dependencies in Python. They are simple to implement and, for most users, adequate solutions for handling multiple projects with different dependencies. However, they are not the only solutions. Other services can complement their use.

How do I install Python packages with dependencies?

In this case, you have two options: Use the pipdeptree utility to gather a list of all dependencies, create a requirements. txt file listing all the dependencies, and then download them with the pip download command. Get the list of dependencies for a package from the setup.py file.

How do I resolve dependencies in pip?

Unfortunately, pip makes no attempt to resolve dependency conflicts. For example, if you install two packages, package A may require a different version of a dependency than package B requires. Pip can install from either Source Distributions (sdist) or Wheel (. whl) files.

What is Setup_requires in setup py?

install_requires is a setuptools setup.py keyword that should be used to specify what a project minimally needs to run correctly.


1 Answers

Ultimately, this worked for me:

#!/usr/bin/env python

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as _build_ext

#
# This cludge is necessary for horrible reasons: see comment below and
# http://stackoverflow.com/q/19919905/447288
#
class build_ext(_build_ext):
    def finalize_options(self):
        _build_ext.finalize_options(self)
        # Prevent numpy from thinking it is still in its setup process:
        __builtins__.__NUMPY_SETUP__ = False
        import numpy
        self.include_dirs.append(numpy.get_include())

setup(
    #
    # Amazingly, `pip install scipy` fails if `numpy` is not already installed.
    # Since we cannot control the order that dependencies are installed via
    # `install_requires`, use `setup_requires` to ensure that `numpy` is available
    # before `scipy` is installed.
    #
    # Unfortunately, this is *still* not sufficient: `numpy` has a guard to
    # check when it is in its setup process that we must circumvent with
    # the `cmdclass`.
    #
    setup_requires=['numpy'],
    cmdclass={'build_ext':build_ext},
    install_requires=[
        'numpy',
        'scipy',
    ],
    ...
)
like image 99
Alex Reece Avatar answered Sep 21 '22 06:09

Alex Reece