Je voudrais créer un package Python contenant du code Cython . J'ai le code Cython qui fonctionne bien. Cependant, je veux maintenant savoir comment le conditionner au mieux.
Pour la plupart des gens qui souhaitent simplement installer le package, j'aimerais inclure le .c
fichier créé par Cython et prendre des dispositions pour setup.py
le compiler pour produire le module. Ensuite, l'utilisateur n'a pas besoin d'installer Cython pour installer le package.
Mais pour les personnes qui souhaitent modifier le package, j'aimerais également fournir les .pyx
fichiers Cython , et autoriser d'une manière ou d'une autre setup.py
à les construire en utilisant Cython (donc ces utilisateurs auraient besoin de Cython installé).
Comment dois-je structurer les fichiers du package pour répondre à ces deux scénarios?
La documentation Cython donne quelques conseils . Mais il ne dit pas comment en créer un setup.py
qui gère à la fois les cas avec / sans Cython.
Réponses:
Je l'ai fait moi-même maintenant, dans un package Python
simplerandom
( BitBucket repo - EDIT: now github ) (je ne m'attends pas à ce que ce soit un package populaire, mais c'était une bonne chance d'apprendre Cython).Cette méthode repose sur le fait que la construction d'un
.pyx
fichier avecCython.Distutils.build_ext
(au moins avec Cython version 0.14) semble toujours créer un.c
fichier dans le même répertoire que le.pyx
fichier source .Voici une version réduite
setup.py
dont je l'espère montre l'essentiel:J'ai également édité
MANIFEST.in
pour m'assurer qu'ilmycythonmodule.c
est inclus dans une distribution source (une distribution source créée avecpython setup.py sdist
):Je ne m'engage pas
mycythonmodule.c
sur le contrôle de version «trunk» (ou «default» pour Mercurial). Lorsque je fais une version, je dois me rappeler de faire unepython setup.py build_ext
première, pour m'assurer qu'ellemycythonmodule.c
est présente et à jour pour la distribution du code source. Je crée également une branche de publication et je valide le fichier C dans la branche. De cette façon, j'ai un enregistrement historique du fichier C qui a été distribué avec cette version.la source
Ajout à la réponse de Craig McQueen: voir ci-dessous comment remplacer la
sdist
commande pour que Cython compile automatiquement vos fichiers source avant de créer une distribution source.De cette façon, vous ne courez aucun risque de distribuer accidentellement des
C
sources obsolètes . Cela aide également dans le cas où vous avez un contrôle limité sur le processus de distribution, par exemple lors de la création automatique de distributions à partir d'une intégration continue, etc.la source
http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
la source
Le plus simple est d'inclure les deux mais d'utiliser simplement le fichier c? L'inclusion du fichier .pyx est bien, mais ce n'est pas nécessaire une fois que vous avez le fichier .c de toute façon. Les personnes qui souhaitent recompiler le .pyx peuvent installer Pyrex et le faire manuellement.
Sinon, vous devez avoir une commande build_ext personnalisée pour distutils qui construit d'abord le fichier C. Cython en inclut déjà un. http://docs.cython.org/src/userguide/source_files_and_compilation.html
Ce que cette documentation ne fait pas, c'est dire comment rendre cela conditionnel, mais
Devrait le gérer.
la source
setup.py
puisse construire directement à partir du.pyx
fichier lorsque Cython est installé. Ma réponse a également mis en œuvre cela.L'inclusion de fichiers .c générés par (Cython) est assez étrange. Surtout quand nous incluons cela dans git. Je préfère utiliser setuptools_cython . Lorsque Cython n'est pas disponible, il construira un œuf avec un environnement Cython intégré, puis construira votre code à l'aide de l'oeuf.
Un exemple possible: https://github.com/douban/greenify/blob/master/setup.py
Mise à jour (2017-01-05):
Depuis
setuptools 18.0
, il n'y a plus besoin d'utilisersetuptools_cython
. Voici un exemple pour créer un projet Cython à partir de zéro sanssetuptools_cython
.la source
'setuptools>=18.0'
setup_requires au lieu de créer la méthodeis_installed
?setuptools>=18.0
a été installé, il vous suffit de mettre'Cython >= 0.18'
ensetup_requires
et Cython sera installé lors de l' installation des progrès. Mais si vous utilisez setuptools <18.0, même si vous spécifiez cython dans setup_requires, il ne sera pas installé, dans ce cas, vous devriez envisager de l'utilisersetuptools_cython
.pip install wheel
. Alors ce doit être la raison 1. Veuillez d'abord installer la roue et réessayer.C'est un script de configuration que j'ai écrit qui facilite l'inclusion de répertoires imbriqués dans la construction. Il faut l'exécuter à partir d'un dossier dans un package.
Structure de Givig comme celle-ci:
setup.py
Bonne compilation;)
la source
Le simple hack que j'ai trouvé:
Installez simplement Cython s'il n'a pas pu être importé. On ne devrait probablement pas partager ce code, mais pour mes propres dépendances, c'est assez bon.
la source
Toutes les autres réponses reposent sur
Cython.Build
, ce qui crée un problème de poulet et d'œuf entre la demande de cython viasetup_requires
et son importation.Une solution moderne consiste à utiliser setuptools à la place, voir cette réponse (la gestion automatique des extensions Cython nécessite setuptools 18.0, c'est-à-dire qu'elle est déjà disponible depuis de nombreuses années). Une norme moderne
setup.py
avec gestion des exigences, un point d'entrée et un module cython pourrait ressembler à ceci:la source
Cython.Build
du moment de l'installation provoque ImportError pour moi. Avoir setuptools pour compiler pyx est la meilleure façon de le faire.Le moyen le plus simple que j'ai trouvé en utilisant uniquement setuptools au lieu des fonctionnalités limitées distutils est
la source
Cython.Build
, voir ma réponse.Je pense avoir trouvé un très bon moyen de faire cela en fournissant une
build_ext
commande personnalisée . L'idée est la suivante:J'ajoute les en-têtes numpy en remplaçant
finalize_options()
et en faisantimport numpy
dans le corps de la fonction, ce qui évite joliment le problème de la non disponibilité de numpy avant de l'setup()
installer.Si cython est disponible sur le système, il se connecte à la commande
check_extensions_list()
connecte à méthode de et cythonise tous les modules cython obsolètes, en les remplaçant par des extensions C qui peuvent plus tard être gérées par labuild_extension()
méthode. Nous fournissons simplement la dernière partie de la fonctionnalité dans notre module: cela signifie que si cython n'est pas disponible mais que nous avons une extension C présente, cela fonctionne toujours, ce qui vous permet de faire des distributions de sources.Voici le code:
Cela permet d'écrire simplement les
setup()
arguments sans se soucier des importations et de savoir si cython est disponible:la source