[Cython] import-free setuptools integration
Nils Werner
nils.werner at gmail.com
Fri Feb 5 15:43:32 EST 2016
I have implemented some very simple setuptools integration that circumvents
the requirement to `import cython` in `setup.py` entirely, doing away with
the
century-old problem of having to importing requirements during installation:
<https://github.com/cython/cython/pull/477>
This implementation is inspired by CFFI's setuptools integration:
<https://cffi.readthedocs.org/en/latest/cdef.html#distutils-setuptools>.
They do not require you to `import cffi` but simply define an additional
keyword
argument `cffi_modules` for `setup()`. This additional keyword argument
_does not
raise errors when cffi is not installed yet_ but can be used once cffi is
there
(as defined in `setup_requires`). Later setuptools will call cffi and have
it do
whatever it wants with the contents of the argument.
Cython can do the exact same. Below you have the usual `setup.py`, with the
chicken and egg `import` problem and a few `Extensions` that need to be
`cythonize`d:
import setuptools
from Cython.Build import cythonize # this will fail if cython is not
present prior to running `pip install this`
from setuptools.extension import Extension
extensions = [
Extension("fib", ["fib.pyx"]),
Extension("fib2", ["fib2.pyx"]),
]
setuptools.setup(
name='example',
version="1.0.0",
packages=setuptools.find_packages(),
setup_requires=['cython'],
install_requires=['cython'],
ext_modules=cythonize(extensions),
)
With the changes I am proposing the usual
ext_modules=cythonize(extensions),
can be replaced with
cython_modules=extensions,
removing the need for `from Cython.Build import cythonize` and solving the
import problem:
import setuptools
from setuptools.extension import Extension
extensions = [
Extension("fib", ["fib.pyx"]),
Extension("fib2", ["fib2.pyx"]),
]
setuptools.setup(
name='example',
version="1.0.0",
setup_requires=['cython'], # we must later require a Cython
version that has this kind of integration
install_requires=['cython'],
cython_modules=extensions,
)
This allows a nicer automated installation of tools that depend on cython
and
also allows end users to keep their `setup.py` cleaner and leaner.
Additionally, I have also extended `cythonize()` a bit and thus allow for
definitions like:
import setuptools
from setuptools.extension import Extension
extensions = [
Extension("fib", ["fib.c"]),
Extension("fib2", ["fib2.c"]),
]
setuptools.setup(
name='example',
version="1.0.0",
extras_require={'cython': ['cython']},
ext_modules=extensions,
cython_modules=extensions,
)
This will automatically compile pyx->c if cython is installed and a
re-compilation is
needed. Otherwise it will merely compile c->so.
This allows devs to ship the generated C-code (as you suggest per your
docs) but
takes the heuristic to find out whether to compile pyx->C->so or only C->so
completely out of `setup.py` and under control of cython.
The change is written to be backwards compatible:
- Using `cython_modules` is entirely optional and not using it is
sideeffect-free
- Having `cythonize()` internally automatically compile *.pyx files when
*.c files
are provided is disabled by default and must be enabled using the
`replace_extension`
keyword argument (`cython_modules` enables that option).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20160205/3f6d21e6/attachment-0001.html>
More information about the cython-devel
mailing list