interfect
interfect

Reputation: 2877

Marking Cython as a Build Dependency?

There is a Python package with a setup.py that reads thusly:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
  name = 'fastahack',
  ext_modules=[
    Extension("fastahack.cfastahack",
              sources=["fastahack/cfastahack.pyx", "lib/Fasta.cpp", "lib/split.cpp"],
              libraries=["stdc++"],
              include_dirs=["lib/"],
              language="c++"),
    ],
    package_data = {'lib': ['*.pyx', "*.c", "*.h", "README.rst"]},
    package_dir = {"fastahack": "fastahack"},
    cmdclass = {'build_ext': build_ext},
    packages = ['fastahack', 'fastahack.tests'],
    author = "Brent Pedersen",
    author_email="[email protected]",
    #test_suite='nose.collector'
)

This setup.py can't be imported if Cython is not installed. As far as I know, importing setup.py is how tools like pip figure out the dependencies of a package. I want to set up this package so that it could be uploaded to PyPI, with the fact that it depends on Cython noted, so that Cython will be downloaded and installed when you try to "pip install fastahack", or when you try to "pip install" directly from the Git repository.

How would I package this module so that it installs correctly from the Internet when Cython is not installed? Always using the latest version of Cython would be a plus.

Upvotes: 6

Views: 3347

Answers (3)

Epic Wink
Epic Wink

Reputation: 845

You can specify Cython as a build dependency using PEP-518 project specification.

In the file pyproject.toml (in the same directory as setup.py) insert:

[build-system]
requires = ["setuptools", "wheel", "Cython"]

Cython will then be installed before building your package.

Note that (currently) you need to pass --no-use-pep517 to pip install if you are installing your package locally as editable (ie with --editable or -e) setuptools v64 supports editable installs with pyproject.toml builds

Upvotes: 5

SanityIO
SanityIO

Reputation: 824

My standard template for setup.py:

have_cython = False
try:
    from Cython.Distutils import build_ext as _build_ext
    have_cython = True
except ImportError:
    from distutils.command.build_ext import build_ext as _build_ext

if have_cython:
    foo  = Extension('foo', ['src/foo.pyx'])
else:
    foo  = Extension('foo', ['src/foo.c'])

setup (
   ...
   ext_modules=[foo],
   cmdclass={'build_ext': build_ext}

And don't forget to provide extention .c files with package - that will allow users to build module without installing cython.

Upvotes: 4

punchagan
punchagan

Reputation: 5836

Use a try and except for the Cython import and modify your setup based on whether or not your import succeeds. Look at the setup.py of Pandas for an example

Upvotes: 1

Related Questions