qué que módulos modulos llamar lista librerias instalar incluidas importar implementa como cliente basicas python packaging cython

módulos - ¿Cómo debería estructurar un paquete de Python que contiene el código de Cython?



que es pip python (8)

Añadiendo a la respuesta de Craig McQueen: vea a continuación cómo anular el comando sdist para que Cython compile automáticamente sus archivos de origen antes de crear una distribución fuente.

De esa forma, no corras el riesgo de distribuir accidentalmente fuentes de C obsoletas. También ayuda en el caso en que tiene un control limitado sobre el proceso de distribución, por ejemplo, cuando se crean automáticamente distribuciones a partir de la integración continua, etc.

from distutils.command.sdist import sdist as _sdist ... class sdist(_sdist): def run(self): # Make sure the compiled Cython files in the distribution are up-to-date from Cython.Build import cythonize cythonize([''cython/mycythonmodule.pyx'']) _sdist.run(self) cmdclass[''sdist''] = sdist

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 cuál es la mejor manera de empaquetarlo.

Para la mayoría de las personas que solo desean instalar el paquete, me gustaría incluir el archivo .c que crea Cython, y hacer arreglos para que setup.py compile eso 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, también me gustaría proporcionar los archivos .pyx Cython, y de alguna manera también permitir que setup.py construya usando Cython (por lo que esos usuarios necesitarían instalar Cython).

¿Cómo debería estructurar los archivos en el paquete para atender estos dos escenarios?

La documentación de Cython ofrece una pequeña guía . Pero no dice cómo hacer un solo setup.py que maneje ambos casos con / sin Cython.


El truco simple que se me ocurrió:

from distutils.core import setup try: from Cython.Build import cythonize except ImportError: from pip import pip pip.main([''install'', ''cython'']) from Cython.Build import cythonize setup(…)

Simplemente instale Cython si no se pudo importar. Probablemente uno no debería compartir este código, pero para mis propias dependencias es suficiente.


Este es un script de configuración que escribí que facilita la inclusión de directorios anidados dentro de la compilación. Uno necesita ejecutarlo desde la carpeta dentro de un paquete.

Givig estructura de esta manera:

__init__.py setup.py test.py subdir/ __init__.py anothertest.py

setup.py

from setuptools import setup, Extension from Cython.Distutils import build_ext # from os import path ext_names = ( ''test'', ''subdir.anothertest'', ) cmdclass = {''build_ext'': build_ext} # for modules in main dir ext_modules = [ Extension( ext, [ext + ".py"], ) for ext in ext_names if ext.find(''.'') < 0] # for modules in subdir ONLY ONE LEVEL DOWN!! # modify it if you need more !!! ext_modules += [ Extension( ext, ["/".join(ext.split(''.'')) + ".py"], ) for ext in ext_names if ext.find(''.'') > 0] setup( name=''name'', ext_modules=ext_modules, cmdclass=cmdclass, packages=["base", "base.subdir"], ) # Build -------------------------- # python setup.py build_ext --inplace

Compilación feliz;)


Incluir archivos .c generados (Cython) es bastante extraño. Especialmente cuando incluimos eso en git. Prefiero usar setuptools_cython . Cuando Cython no está disponible, construirá un huevo que tenga un entorno de Cython incorporado, y luego construirá tu código usando el huevo.

Un posible ejemplo: https://github.com/douban/greenify/blob/master/setup.py

Actualización (2017-01-05):

Desde setuptools 18.0 , no es necesario usar setuptools_cython . Here hay un ejemplo para crear un proyecto de Cython desde cero sin setuptools_cython .


La forma más fácil que encontré usando solo herramientas de configuración en lugar de la función limitada distutils es

from setuptools import setup from setuptools.extension import Extension try: from Cython.Build import cythonize except ImportError: use_cython = False else: use_cython = True ext_modules = [] if use_cython: ext_modules += cythonize(''package/cython_module.pyx'') else: ext_modules += [Extension(''package.cython_module'', [''package/cython_modules.c''])] setup(name=''package_name'', ext_modules=ext_modules)


Lo he hecho yo mismo ahora, en un paquete Python simplerandom ( repositorio BitBucket - EDIT: ahora github ) (no espero que este sea un paquete popular, pero fue una buena oportunidad para aprender Cython).

Este método se basa en el hecho de que crear un archivo .pyx con Cython.Distutils.build_ext (al menos con la versión 0.14 de Cython) siempre parece crear un archivo .c en el mismo directorio que el archivo .pyx origen.

Aquí hay una versión reducida de setup.py que espero muestre lo esencial:

from distutils.core import setup from distutils.extension import Extension try: from Cython.Distutils import build_ext except ImportError: use_cython = False else: use_cython = True cmdclass = { } ext_modules = [ ] if use_cython: ext_modules += [ Extension("mypackage.mycythonmodule", [ "cython/mycythonmodule.pyx" ]), ] cmdclass.update({ ''build_ext'': build_ext }) else: ext_modules += [ Extension("mypackage.mycythonmodule", [ "cython/mycythonmodule.c" ]), ] setup( name=''mypackage'', ... cmdclass = cmdclass, ext_modules=ext_modules, ... )

También mycythonmodule.c MANIFEST.in para asegurarme de que mycythonmodule.c esté incluido en una distribución fuente (una distribución fuente que se crea con python setup.py sdist ):

... recursive-include cython * ...

No mycythonmodule.c al control de versiones ''trunk'' (o ''predeterminado'' para Mercurial). Cuando realizo una publicación, debo recordar hacer python setup.py build_ext primero, para asegurarme de que mycythonmodule.c esté presente y actualizado para la distribución del código fuente. También hago una rama de liberación y envío el archivo C a la rama. De esa manera tengo un registro histórico del archivo C que se distribuyó con ese lanzamiento.


Lo más fácil es incluir ambos, pero solo use el archivo c? Incluir el archivo .pyx es agradable, pero no es necesario una vez que tenga el archivo .c de todos modos. Las personas que quieran recompilar el .pyx pueden instalar Pyrex y hacerlo manualmente.

De lo contrario, debe tener un comando build_ext personalizado para distutils que crea el archivo C primero. Cython ya incluye uno. http://docs.cython.org/src/userguide/source_files_and_compilation.html

Lo que esa documentación no hace es decir cómo hacer que esto sea condicional, pero

try: from Cython.distutils import build_ext except ImportError: from distutils.command import build_ext

Debería manejarlo.


http://docs.cython.org/src/reference/compilation.html#distributing-cython-modules

Se recomienda encarecidamente que distribuya los archivos .c generados, así como sus fuentes de Cython, para que los usuarios puedan instalar su módulo sin necesidad de tener Cython disponible.

También se recomienda que la compilación Cython no esté habilitada de forma predeterminada en la versión que distribuye. Incluso si el usuario tiene Cython instalado, probablemente no quiera usarlo solo para instalar su módulo. Además, la versión que tiene puede no ser la misma que usaste, y puede que no compile tus fuentes correctamente.

Esto simplemente significa que el archivo setup.py que envíe será solo un archivo distutils normal en los archivos .c generados, para el ejemplo básico que tendríamos en su lugar:

from distutils.core import setup from distutils.extension import Extension setup( ext_modules = [Extension("example", ["example.c"])] )