Reputation: 8124
I have a python package (python 2.7) that includes some optimized functions written in cython. My setup.py handles the pure-python files and the installed package uses the un-optimized pure python functions.
I'm trying to understand what is the best way to setup the project for distributing the C extension.
Right now I have a specific setup.py
in the extension folder that can be used to compile the extension with:
python setup.py build_ext --inplace
But I want the package installation to also handle the C extension. Possibly with a single:
python setup.py
I was thinking of merging the specific setup.py in the project-wide setup.py. However, to compile the extension, I need to import numpy. But I know that importing anything outside the standard lib in setup.py is discouraged.
What are the best practices for python packages including a simple cython extensions that only uses numpy and no other external libs?
Upvotes: 3
Views: 766
Reputation: 8124
For now I settled on the following solution that requires importing numpy. It does not cause problems so far.
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',
)
Upvotes: 2