Me gustaría hacer un paquete de Python que contenga algún código de Cython . Tengo el código de Cython funcionando bien. Sin embargo, ahora quiero saber cómo empaquetarlo mejor.
Para la mayoría de las personas que solo desean instalar el paquete, me gustaría incluir el .carchivo que crea Cython y organizar la setup.pycompilación para producir el módulo. Entonces el usuario no necesita Cython instalado para instalar el paquete.
Pero para las personas que quieran modificar el paquete, me gustaría también como para proporcionar la Cython .pyxarchivos, y de alguna manera también permiten setup.pyconstruirlos usando Cython (por lo que los usuarios podrían necesitar instalar Cython).
¿Cómo debo estructurar los archivos en el paquete para atender estos dos escenarios?
La documentación de Cython da una pequeña guía . Pero no dice cómo hacer un single setup.pyque maneje ambos casos con / sin Cython.

Respuestas:
Lo hice yo mismo ahora, en un paquete de Python
simplerandom( BitBucket repo - EDIT: ahora github ) (no espero que sea un paquete popular, pero fue una buena oportunidad para aprender Cython).Este método se basa en el hecho de que construir un
.pyxarchivo conCython.Distutils.build_ext(al menos con la versión 0.14 de Cython) siempre parece crear un.carchivo en el mismo directorio que el.pyxarchivo fuente .Aquí hay una versión reducida de la
setup.pyque espero muestre lo esencial:También edité
MANIFEST.inpara asegurarme de quemycythonmodule.cesté incluido en una distribución fuente (una distribución fuente que se crea conpython setup.py sdist):No me comprometo
mycythonmodule.ccon el control de versiones 'trunk' (o 'default' para Mercurial). Cuando hago un lanzamiento, necesito recordar hacerpython setup.py build_extprimero, para asegurarme de quemycythonmodule.cesté presente y actualizado para la distribución del código fuente. También hago una rama de lanzamiento y confirmo el archivo C en la rama. De esa manera tengo un registro histórico del archivo C que se distribuyó con esa versión.fuente
Agregando a la respuesta de Craig McQueen: vea a continuación cómo anular el
sdistcomando para que Cython compile automáticamente sus archivos fuente antes de crear una distribución fuente.De esta forma, no corre el riesgo de distribuir accidentalmente
Cfuentes obsoletas . También ayuda en el caso de que tenga un control limitado sobre el proceso de distribución, por ejemplo, al crear distribuciones automáticamente a partir de la integración continua, etc.fuente
http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
fuente
¿Lo más fácil es incluir ambos pero solo usar el archivo c? Incluir el archivo .pyx es bueno, pero no es necesario una vez que tenga el archivo .c de todos modos. Las personas que desean recompilar el .pyx pueden instalar Pyrex y hacerlo manualmente.
De lo contrario, debe tener un comando personalizado build_ext para distutils que primero compila el archivo C. Cython ya incluye uno. http://docs.cython.org/src/userguide/source_files_and_compilation.html
Lo que no hace esa documentación es decir cómo hacer que esto sea condicional, pero
Debería manejarlo.
fuente
setup.pypueda construir directamente desde el.pyxarchivo cuando se instala Cython. Mi respuesta también lo ha implementado.Incluyendo (Cython) los archivos .c generados son bastante raros. Especialmente cuando incluimos eso en git. Prefiero usar setuptools_cython . Cuando Cython no está disponible, creará un huevo que tiene un entorno Cython incorporado, y luego construirá su código usando el huevo.
Un posible ejemplo: https://github.com/douban/greenify/blob/master/setup.py
Actualización (2017-01-05):
Desde entonces
setuptools 18.0, no hay necesidad de usarsetuptools_cython. Aquí hay un ejemplo para construir un proyecto Cython desde cero sin élsetuptools_cython.fuente
'setuptools>=18.0'setup_requires en lugar de crear el métodois_installed?setuptools>=18.0se ha instalado, a continuación, sólo tiene que poner'Cython >= 0.18'ensetup_requires, y Cython se instalará durante la instalación progreso. Pero si está utilizando setuptools <18.0, incluso su cython específico en setup_requires, no se instalará, en este caso, debe considerar su usosetuptools_cython.pip install wheel. Entonces debe ser la razón 1. Instale la rueda primero e intente nuevamente.Este es un script de configuración que escribí que hace que sea más fácil incluir directorios anidados dentro de la compilación. Uno necesita ejecutarlo desde la carpeta dentro de un paquete.
Estructura Givig como esta:
setup.py
Compilación feliz;)
fuente
El simple truco que se me ocurrió:
Simplemente instale Cython si no se pudo importar. Probablemente no se deba compartir este código, pero para mis propias dependencias es lo suficientemente bueno.
fuente
Todas las demás respuestas dependen de
Cython.Build, lo que crea un problema de huevo y gallina entre requerir cython víasetup_requirese importarlo.Una solución moderna es usar setuptools en su lugar, vea esta respuesta (el manejo automático de extensiones de Cython requiere setuptools 18.0, es decir, está disponible desde hace muchos años). Un estándar moderno
setup.pycon manejo de requisitos, un punto de entrada y un módulo cython podría verse así:fuente
Cython.Buildel momento de la configuración me causa ImportError. Tener herramientas de configuración para compilar pyx es la mejor manera de hacerlo.La forma más fácil que encontré usando solo herramientas de configuración en lugar de la característica limitada distutils es
fuente
Cython.Build, vea mi respuesta.Creo que encontré una forma bastante buena de hacerlo proporcionando un
build_extcomando personalizado . La idea es la siguiente:Agrego los encabezados numpy anulando
finalize_options()y haciendoimport numpyen el cuerpo de la función, lo que evita muy bien el problema de que numpy no esté disponible antes desetup()instalarlo.Si cython está disponible en el sistema, se engancha en el
check_extensions_list()método del comando y por cythoniza todos los módulos de cython desactualizados, reemplazándolos con extensiones C que luego puede manejar elbuild_extension()método. También proporcionamos la última parte de la funcionalidad en nuestro módulo: esto significa que si cython no está disponible pero tenemos una extensión C presente, todavía funciona, lo que le permite hacer distribuciones de origen.Aquí está el código:
Esto le permite a uno escribir los
setup()argumentos sin preocuparse por las importaciones y si uno tiene cython disponible:fuente