¿Es seguro llamar a `setup ()` varias veces en un solo `setup.py`?

Estoy desarrollando un paquete que contiene extensiones de Cython.

De acuerdo con https://github.com/pypa/pip/issues/1958 setup_requires y posponeré la importación de Cython . La mejor solución que se me ocurrió es llamar a setup() dos veces en setup.py :

 ... # initial imports setup(setup_requires=['cython']) from Cython.Build import cythonize bar = Extension('foo.bar', sources = ['bar.pyx']) setup(name = 'foo', ... # parameters ext_modules = cythonize([bar]), ... # more parameters ) 

Sin embargo, tengo la sensación de que el nombre de setup() sugiere que se llamará solo una vez. ¿Es seguro llamarlo varias veces como lo hago?

No puedo simplemente distribuir ruedas porque el paquete estará disponible también para usuarios de Linux.

[EDITAR]

También veo la pregunta como más general que tratar con las dependencias del comstackdor. Uno puede querer importar algún paquete (por ejemplo, sphinx o pweave ) para preprocesar la descripción del paquete.

La respuesta simple es: No. Una vez que llama a la configuración, analizará los argumentos de la línea de comandos y comenzará a hacer su trabajo.

En cuanto a la dependencia de Cython , setup_requires no puede ayudar aquí. Probablemente intentará descargar Cython sin instalar. Como comentó SpotlightKid:

distutils no intenta ser un comstackdor o instalar gcc como una dependencia tampoco

Según las herramientas de configuración.

este argumento (setup_requires) es necesario si está utilizando extensiones distutils,

Y por lo tanto, no para paquetes como Cython .

Creo que el usuario es responsable de instalar Cython antes de llamar a setup.py . Si desea proporcionar un mensaje de error más amigable, intente utilizar

 try: from Cython.Build import cythonize except ImportError: # Kindly ask the user to install Cython 

Las siguientes publicaciones pueden ayudar:

  • Instalar el paquete que tiene setup_requires …
  • setup_requires para entornos de desarrollo

Tuve un escenario diferente en el que necesitaba ejecutar setup() varias veces: en mi caso, estaba creando dos paquetes de las mismas fonts. El primer paquete fue una herramienta de línea de comandos basada en Fabric , el segundo paquete fue solo de biblioteca (API, herramientas, etc.) Parecía muy poco práctico dividir el proyecto en dos repositorys para un proyecto tan pequeño, ya que la parte CLI era realmente solo una envoltura . La ejecución de setup() varias veces con diferentes argumentos provocó que la comstackción fallara en varios errores (en su mayoría, archivos faltantes). Mi solución fue ejecutar cada setup() como un Process diferente:

 from setuptools import setup, find_packages from multiprocessing import Process if __name__ == '__main__': setups = [ { 'name': 'cli-tool', 'description': 'Some description...', 'packages': find_packages(), 'entry_points': { 'console_scripts': [ 'cli-tool = fabfile:main' ] }, '...': 'etc. needed for setup() ...' }, { 'name': 'cli-tool-lib', 'packages': find_packages(exclude=('fabfile',)), '...': 'etc.' } ] for s in setups: name = s['name'] print("Building '{}'.".format(name)) p = Process(target=setup, kwargs=s) p.start() p.join() print("Building of '{}' done.\n".format(name))