web-dev-qa-db-fra.com

setup_requires avec Cython?

Je crée un setup.py fichier pour un projet avec quelques modules d'extension Cython.

Je l'ai déjà fait fonctionner:

from setuptools import setup, Extension
from Cython.Build import cythonize

setup(
    name=...,
    ...,
    ext_modules=cythonize([ ... ]),
)

Cela s'installe bien. Cependant, cela suppose que Cython est installé. Et s'il n'est pas installé? Je comprends que c'est ce que le setup_requires le paramètre est pour:

from setuptools import setup, Extension
from Cython.Build import cythonize

setup(
    name=...,
    ...,
    setup_requires=['Cython'],
    ...,
    ext_modules=cythonize([ ... ]),
)

Cependant, si Cython n'est pas déjà installé, cela échouera bien sûr:

$ python setup.py install
Traceback (most recent call last):
  File "setup.py", line 2, in <module>
    from Cython.Build import cythonize
ImportError: No module named Cython.Build

Quelle est la bonne façon de procéder? Je dois en quelque sorte importer Cython seulement après le setup_requires l'étape s'exécute, mais j'ai besoin de Cython pour spécifier le ext_modules valeurs.

24
Claudiu

Vous devez envelopper le from Cython.Build import cythonize dans un try-except, et dans except, définissez cythonize comme une fonction factice. De cette façon, le script peut être chargé sans échec avec un ImportError.

Plus tard, lorsque le setup_requires l'argument est géré, Cython sera installé et le script de configuration sera réexécuté. Étant donné qu'à ce stade, Cython est installé, vous serez en mesure d'importer avec succès cythonize

try:
    from Cython.Build import cythonize
except ImportError:
     def cythonize(*args, **kwargs):
         from Cython.Build import cythonize
         return cythonize(*args, **kwargs)

ÉDITER

Comme indiqué dans les commentaires, une fois que setuptools traite les dépendances manquantes, il ne rechargera pas Cython. Je n'y avais pas pensé auparavant, mais vous pouvez également essayer une approche de liaison tardive pour éliminer cythonize

4
mobiusklein

À partir de 18. version de setuptools (publiée le 2015-06-23), il est possible de spécifier Cython dans setup_requires et passez *.pyx sources de modules pour setuptools.Extension:

from setuptools import setup, Extension


setup(
    # ...
    setup_requires=[
        # Setuptools 18.0 properly handles Cython extensions.
        'setuptools>=18.0',
        'cython',
    ],
    ext_modules=[
        Extension(
            'mylib',
            sources=['src/mylib.pyx'],
        ),
    ],
)
27
rutsky