Comment puis-je obtenir la version définie dans setup.py
mon package (à des --version
fins ou à d'autres fins)?
python
setuptools
Elmarco
la source
la source
Réponses:
Interroger la chaîne de version de la distribution déjà installée
Pour récupérer la version de l'intérieur de votre package au moment de l'exécution (ce que votre question semble réellement demander), vous pouvez utiliser:
Stocker la chaîne de version à utiliser lors de l'installation
Si vous voulez aller dans l'autre sens (ce qui semble être ce que les autres auteurs de réponses semblent avoir pensé que vous demandiez ici), mettez la chaîne de version dans un fichier séparé et lisez le contenu de ce fichier
setup.py
.Vous pouvez créer un version.py dans votre package avec une
__version__
ligne, puis le lire à partir de setup.py en utilisantexecfile('mypackage/version.py')
, de sorte qu'il soit__version__
défini dans l'espace de noms setup.py.Si vous voulez un moyen beaucoup plus simple qui fonctionnera avec toutes les versions de Python et même les langages non Python qui peuvent avoir besoin d'accéder à la chaîne de version:
Stockez la chaîne de version comme le seul contenu d'un fichier texte brut, nommé par exemple
VERSION
, et lisez ce fichier pendantsetup.py
.Le même
VERSION
fichier fonctionnera alors exactement aussi bien dans n'importe quel autre programme, même non Python, et il vous suffit de changer la chaîne de version en un seul endroit pour tous les programmes.Avertissement sur les conditions de concurrence lors de l'installation
À propos, N'importez PAS votre package depuis votre setup.py comme suggéré dans une autre réponse ici: cela semblera fonctionner pour vous (car vous avez déjà installé les dépendances de votre package), mais cela fera des ravages sur les nouveaux utilisateurs de votre package , car ils ne pourront pas installer votre package sans d'abord installer manuellement les dépendances.
la source
execfile
fonctionne vraiment bien ... mais (malheureusement) ne fonctionne pas avec Python 3.with open('mypackage/version.py') as f: exec(f.read())
à la place deexecfile('mypackage/version.py')
. (De stackoverflow.com/a/437857/647002 )exemple d'étude:
mymodule
Imaginez cette configuration:
Ensuite, imaginez un scénario habituel où vous avez des dépendances et
setup.py
ressemble à:Et un exemple
__init__.py
:Et par exemple
myclasses.py
:problème n ° 1: importation
mymodule
lors de la configurationSi vos
setup.py
importationsmymodule
puis lors de l' installation , vous obtiendraient probablement unImportError
. Il s'agit d'une erreur très courante lorsque votre package a des dépendances. Si votre package n'a pas d'autres dépendances que les fonctions intégrées, vous pouvez être en sécurité; cependant ce n'est pas une bonne pratique. La raison en est que ce n'est pas à l'épreuve du temps; disons que demain, votre code doit consommer une autre dépendance.problème n ° 2: où est mon
__version__
?Si vous codez
__version__
en dur,setup.py
cela peut ne pas correspondre à la version que vous enverriez dans votre module. Pour être cohérent, vous le mettriez au même endroit et le liriez à partir du même endroit lorsque vous en avez besoin. En utilisantimport
vous pouvez obtenir le problème n ° 1.solution: à la
setuptools
Vous utiliseriez une combinaison de
open
,exec
et fourniriez un dict pourexec
ajouter des variables:Et en
mymodule/version.py
exposer la version:De cette façon, la version est livrée avec le module et vous ne rencontrez pas de problèmes lors de l'installation en essayant d'importer un module qui a des dépendances manquantes (encore à installer).
la source
La meilleure technique consiste à définir
__version__
dans votre code produit, puis à l'importer dans setup.py à partir de là. Cela vous donne une valeur que vous pouvez lire dans votre module en cours d'exécution, et n'avez qu'un seul endroit pour la définir.Les valeurs de setup.py ne sont pas installées et setup.py ne reste pas après l'installation.
Ce que j'ai fait (par exemple) dans coverage.py:
UPDATE (2017): coverage.py ne s'importe plus pour obtenir la version. L'importation de votre propre code peut le rendre désinstallable, car le code de votre produit essaiera d'importer des dépendances, qui ne sont pas encore installées, car setup.py est ce qui les installe.
la source
__version__
qu'il contient est cassé d'une manière ou d'une autre, votre importation sera également interrompue. Python ne sait pas interpréter uniquement les instructions que vous souhaitez. @pjeby a raison: si votre module a besoin d'importer d'autres modules, il se peut qu'ils ne soient pas encore installés et ce sera chaotique. Cette technique fonctionne si vous faites attention à ce que l'importation ne provoque pas une longue chaîne d'autres importations.pip install <packagename>
, je reçois l'erreur suivante:ImportError: No module named <packagename>
. Veuillez avertir vos lecteurs que vous ne pouvez pas exécuter de fichiers setup.py comme celui-ci sur des environnements où le package n'est pas déjà installé!Votre question est un peu vague, mais je pense que vous demandez comment la préciser.
Vous devez définir
__version__
comme ceci:Et puis vous pouvez confirmer que setup.py connaît la version que vous venez de spécifier:
la source
Je n'étais pas satisfait de ces réponses ... je ne voulais pas exiger setuptools, ni créer un module séparé complet pour une seule variable, alors je les ai trouvés.
Pour quand vous êtes sûr que le module principal est dans le style pep8 et le restera:
Si vous souhaitez être très prudent et utiliser un véritable analyseur:
setup.py est en quelque sorte un module jetable, donc pas de problème s'il est un peu moche.
Mise à jour: assez drôle, je me suis éloigné de cela ces dernières années et j'ai commencé à utiliser un fichier séparé dans le package appelé
meta.py
. J'ai mis beaucoup de méta-données là-dedans que je pourrais vouloir changer fréquemment. Donc, pas seulement pour une valeur.la source
ast.get_docstring()
avec certains.split('\n')[0].strip()
etc pour remplir automatiquement àdescription
partir de la source. Une chose de moins à synchroniserCréez un fichier dans votre arborescence source, par exemple dans yourbasedir / yourpackage / _version.py. Laissez ce fichier ne contenir qu'une seule ligne de code, comme ceci:
__version__ = "1.1.0-r4704"
Ensuite, dans votre setup.py, ouvrez ce fichier et analysez le numéro de version comme ceci:
Enfin, dans
yourbasedir/yourpackage/__init__.py
import _version comme ceci:Un exemple de code qui fait cela est le package "pyutil" que je gère. (Voir PyPI ou recherche Google - stackoverflow ne me permet pas d'inclure un lien hypertexte vers celui-ci dans cette réponse.)
@pjeby a raison de ne pas importer votre package depuis son propre setup.py. Cela fonctionnera lorsque vous le testerez en créant un nouvel interpréteur Python et en exécutant setup.py en premier lieu:,
python setup.py
mais il y a des cas où cela ne fonctionnera pas. C'est parceimport youpackage
que ne veut pas dire lire le répertoire de travail courant pour un répertoire nommé "yourpackage", cela signifie chercher dans le courantsys.modules
une clé "yourpackage" et ensuite faire diverses choses si elle n'est pas là. Donc, cela fonctionne toujours lorsque vous le faitespython setup.py
parce que vous avez un frais, videsys.modules
, mais cela ne fonctionne pas en général.Par exemple, que se passe-t-il si py2exe exécute votre setup.py dans le cadre du processus d'empaquetage d'une application? J'ai vu un cas comme celui-ci où py2exe mettrait le mauvais numéro de version sur un package parce que le package obtenait son numéro de version de
import myownthing
dans son setup.py, mais une version différente de ce package avait déjà été importée lors de l'exécution de py2exe. De même, que se passe-t-il si setuptools, easy_install, distribuer ou distutils2 essaie de créer votre package dans le cadre d'un processus d'installation d'un package différent qui dépend du vôtre? Ensuite, si votre package est importable au moment où son setup.py est évalué, ou s'il existe déjà une version de votre package qui a été importée au cours de la vie de cet interpréteur Python, ou si l'importation de votre package nécessite l'installation préalable d'autres packages , ou a des effets secondaires, peuvent changer les résultats. J'ai eu plusieurs difficultés à essayer de réutiliser les packages Python, ce qui a causé des problèmes pour des outils tels que py2exe et setuptools car leur setup.py importe le package lui-même afin de trouver son numéro de version.En passant, cette technique joue bien avec des outils pour créer automatiquement le
yourpackage/_version.py
fichier pour vous, par exemple en lisant votre historique de contrôle de révision et en écrivant un numéro de version basé sur la balise la plus récente dans l'historique de contrôle de révision. Voici un outil qui fait cela pour darcs: http://tahoe-lafs.org/trac/darcsver/browser/trunk/README.rst et voici un extrait de code qui fait la même chose pour git: http: // github .com / warner / python-ecdsa / blob / 0ed702a9d4057ecf33eea969b8cf280eaccd89a1 / setup.py # L34la source
Cela devrait également fonctionner, en utilisant des expressions régulières et en fonction des champs de métadonnées pour avoir un format comme celui-ci:
Utilisez ce qui suit au début de votre setup.py:
Après cela, vous pouvez utiliser les métadonnées dans votre script comme ceci:
la source
Avec une structure comme celle-ci:
où version.py contient:
Vous pouvez le faire dans setup.py :
Cela ne posera aucun problème avec les dépendances que vous avez dans votre mymodule / __ init__.py
la source
Pour éviter d'importer un fichier (et donc d'exécuter son code), on pourrait l'analyser et récupérer l'
version
attribut à partir de l'arbre de syntaxe:Ce code tente de trouver l' affectation
__version__
ouVERSION
au niveau supérieur du module return is string value. Le côté droit peut être une chaîne ou un tuple.la source
Il y a mille façons d'écorcher un chat - voici la mienne:
la source
Nettoyage de https://stackoverflow.com/a/12413800 de @ gringo-suave:
la source
Maintenant, c'est dégoûtant et a besoin d'être affiné (il peut même y avoir un appel de membre découvert dans pkg_resources que j'ai manqué), mais je ne vois tout simplement pas pourquoi cela ne fonctionne pas, ni pourquoi personne ne l'a suggéré à ce jour (googler autour a n'a pas augmenté cela) ... notez qu'il s'agit de Python 2.x, et nécessiterait d'exiger pkg_resources (soupir):
la source
Nous voulions mettre les méta - informations sur notre package
pypackagery
dans__init__.py
, mais ne pouvait pas car il a des dépendances tiers comme PJ Eby a déjà indiqué (voir sa réponse et la mise en garde concernant l'état de la course).Nous l'avons résolu en créant un module séparé
pypackagery_meta.py
qui ne contient que les méta-informations:puis importé les méta-informations dans
packagery/__init__.py
:et finalement utilisé dans
setup.py
:Vous devez inclure
pypackagery_meta
dans votre package avec l'py_modules
argument setup. Sinon, vous ne pouvez pas l'importer lors de l'installation car la distribution packagée en manquerait.la source
Simple et direct, créez un fichier appelé
source/package_name/version.py
avec le contenu suivant:Ensuite, sur votre fichier
source/package_name/__init__.py
, vous importez la version que d'autres personnes pourront utiliser:Maintenant, tu peux mettre ça
setup.py
Testé avec Python
2.7
,3.3
,3.4
,3.5
,3.6
et3.7
sous Linux, Windows et Mac OS. J'ai utilisé sur mon package qui a l'intégration et les tests unitaires pour toutes ces plates-formes. Vous pouvez voir les résultats de.travis.yml
etappveyor.yml
ici:Une autre version utilise le gestionnaire de contexte:
Vous pouvez également utiliser le
codecs
module pour gérer les erreurs Unicode à la fois sur Python2.7
et3.6
Si vous écrivez un module Python à 100% en C / C ++ en utilisant les extensions C Python, vous pouvez faire la même chose, mais en utilisant C / C ++ au lieu de Python.
Dans ce cas, créez ce qui suit
setup.py
:Qui lit la version du fichier
version.h
:Mais n'oubliez pas de créer le
MANIFEST.in
pour inclure leversion.h
fichier:Et il est intégré à l'application principale avec:
Références:
la source
Déployez le package sur le serveur et la convention de dénomination des fichiers pour les packages d'index:
exemple de conversion de version dynamique pip:
gagner:
Mac:
Trouvez l'exemple setup.py appelle la version de pip dynamique correspondant à partir de git commit
la source
J'utilise une variable d'environnement comme ci-dessous
VERSION = 0.0.0 python setup.py sdist bdist_wheel
Dans setup.py
Pour vérifier la cohérence avec la version du packer, j'utilise le script ci-dessous.
la source