编译和分发Cython扩展

时间:2014-11-12 19:45:10

标签: python numpy cython packaging setuptools

我有一个python包(python 2.7),其中包含一些用cython编写的优化函数。我的setup.py处理pure-python文件,安装的包使用未优化的纯python函数。

我正在尝试了解设置项目以分发C扩展名的最佳方法。

现在我在扩展文件夹中有一个特定的setup.py,可用于编译扩展名:

python setup.py build_ext --inplace

但我希望软件包安装也能处理C扩展。可能只有一个:

python setup.py

我在考虑在项目范围的setup.py中合并特定的setup.py。但是,要编译扩展,我需要导入numpy。但我知道不鼓励在setup.py中导入标准库之外的任何内容。

python包的最佳做法是什么,包括只使用numpy而没有其他外部库的简单cython扩展?

1 个答案:

答案 0 :(得分:2)

现在我决定使用以下需要导入numpy的解决方案。到目前为止它不会引起问题。

<强> setup.py

from setuptools import setup
from setuptools.extension import Extension
import numpy as np
import versioneer

## Metadata
project_name = 'foobar'
long_description = """
Long description in RST. Used by PyPI.
"""

## Configure versioneer
versioneer.VCS = 'git'
versioneer.versionfile_source = project_name + '/_version.py'
versioneer.versionfile_build = project_name + '/_version.py'
versioneer.tag_prefix = '' # tags are like 1.2.0
versioneer.parentdir_prefix = project_name + '-'

## Configuration to build Cython extensions
try:
    from Cython.Distutils import build_ext
except ImportError:
    # cython is not installed, use the .c file
    has_cython = False
    ext_extention = '.c'
else:
    # cython is installed, use .pyx file
    has_cython = True
    ext_extention = '.pyx'
ext_modules = [Extension("corecalculation_c",
                         [project_name + \
                         "/calculation/corecalculation_c" + ext_extention])]

## Configure setup.py commands
cmdclass = versioneer.get_cmdclass()
if has_cython:
    cmdclass.update(build_ext=build_ext)


setup(name = project_name,
      version = versioneer.get_version(),
      cmdclass = cmdclass,
      include_dirs = [np.get_include()],
      ext_modules = ext_modules,
      author = 'Author Name',
      author_email = 'email@address',
      url          = 'http://github.com/USER/PROJECT/',
      download_url = 'http://github.com/USER/PROJECT/',
      install_requires = ['numpy', 'scipy', 'matplotlib', 'ipython'],
      license = 'GPLv2',
      description = ("Oneline description"),
      long_description = long_description,
      platforms = ('Windows', 'Linux', 'Mac OS X'),
      classifiers=['Intended Audience :: Science/Research',
                   'Operating System :: OS Independent',
                   'Programming Language :: Python',
                   'Programming Language :: Python :: 2.7',
                   'Topic :: Scientific/Engineering',
                   ],
      packages = [project_name, project_name+'.utils'],
      keywords = 'keyword1 keyword2',
      )