Que ce soit à titre professionnel ou personnel, je fais pas mal de Python, en utilisant toujours le même EDI (PyCharm Pro).
Comme j'ai fait quelques recherches sur les outils de packaging, je me suis dit que j'allais partager le résultat (sachant que le but est uniquement de répondre à mes besoins, pas aux vôtres que je ne connais pas).
Pour me faciliter la vie, j'utilise un certain nombre d'outils classiques : flake8, mypy, black, isort, tox, git, travis-ci. Je souhaite également que les outils soient correctement intégrés dans PyCharm.
Ces outils peuvent généralement être configurés par des fichiers de conf', qu'on trouvera généralement à la racine.
Il ne reste plus qu'à s'occuper des dépendances et du packaging… et là, c'est un peu le drame.
Python ne manque pas d'outils de packaging et d'installation, c'est le moins qu'on puisse dire.
Globalement, il reste actuellement quatre outils dont les usages se croisent très largement :
- l'antique fichier
setup.py
, qui peut être simplifié grace à un fichier de configurationsetup.cfg
et qui demande également unMANIFEST.in
, -
pip
, qui permet d'installer le projet avec ses dépendances, grâce notamment à un fichierrequirements.txt
, -
pipenv
, qui va s'occuper du virtualenv et des dépendances avec son fichierpipfile
, -
poetry
, qui s'occupe du virtualenv, des dépendances, et de la configuration d'autres outils avec son fichierpyproject.toml
.
Comme les usages de ces outils se recouvrent, le contenu des fichiers de configuration se recouvrent également, et pour le coup, je n'ai pas envie de dupliquer des informations dans deux fichiers différents.
Faisons un petit bilan de ce que je souhaite pouvoir faire fréquemment, avec un ! quand la fonction est intégrée dans PyCharm :
action | setup.py |
pipenv |
pip |
poetry |
autre |
---|---|---|---|---|---|
installation locale |
python setup.py install ! |
pipenv install . |
pip install . ! |
poetry install |
|
installation (développement) |
python setup.py develop ! |
pipenv install -e . |
pip install -e . ! |
||
génération du sdist |
python setup.py sdist avec MANIFEST.in ! |
poetry build |
|||
génération du wheel |
python setup.py bdist_wheel ! |
poetry build |
|||
publier sur pypi |
python setup.py bdist_wheel upload ! |
poetry publish |
twine upload dist/. |
||
nouvelle installation | pip install -r requirements.txt |
||||
créer un virtualenv |
pipenv ! |
poetry ! |
virtualenv ! |
||
dépendances directes | dans setup.py ! ou setup.cfg
|
dans Pipfile ! |
dans pyproject.toml
|
||
dépendances (développement) | dans setup.py ! ou setup.cfg
|
dans Pipfile ! |
dans requirements.txt ! |
dans pyproject.toml
|
|
dépendances complètes | dans Pipfile.lock ! |
dans requirements.txt ! |
dans pyproject.toml
|
||
mypy (analyse de code) | dans setup.cfg
|
||||
flake8 (formattage du code) | dans setup.cfg
|
dans pyproject.toml
|
|||
black (formattage du code) | dans pyproject.toml
|
||||
isort (formattage du code) | dans setup.cfg
|
dans pyproject.toml
|
|||
tox (tests unitaires) | dans setup.cfg
|
dans pyproject.toml
|
|||
Travis CI (tests unitaires) | dans .travis.yml
|
||||
Heroku (déploiement Django) | dans Pipfile.lock
|
dans requirements.txt
|
|||
git | dans .gitignore
|
||||
n° de version dans le code | from package import __version__ |
importlib_metadata |
Quelques détails concernant l'intégration PyCharm :
- pour exécuter une commande
setup.py
, j'ai un menuRun setup.py Task
avec le raccourci clavier et une complétion et une liste déroulante des commandes possibles, - si je tape
import django
et qu'il n'est pas listé comme dépendance danssetup.py
,requirements.txt
ouPipfile
, PyCharm me propose de l'ajouter, - PyCharm fait le boulot tout seul pour la création des virtualenv, que ce soit via
virtualenv
,pipenv
oupoetry
.
Si je veux utiliser un peu tous ces outils, il faudrait setup.py
, setup.cfg
, requirements.txt
, Pipfile
et pyproject.toml
, avec des redondances (beaucoup). Trop pénible, il faut donc choisir.
Utiliser pipenv
ne me semble pas être une bonne idée car trop limité par rapport à poetry
(sans compter que j'ai lu quelques petits trucs négatifs à droite et à gauche sur pipenv
).
Exit donc pipenv
.
Utiliser poetry
imposer pour moi l'un des choix suivants :
- abandonner complètement
setup.py
, - une dépendance supplémentaire pour lire le
pyproject.toml
et en extraire les infos pour exécutersetup.py
(on perd l'intérêt d'unsetup.py
toujours exécutable), - accepter d'avoir des informations redondantes à gérer à la main,
- regénérer automatiquement
setup.cfg
quand on modifiepyproject.toml
.
Utiliser poetry
me permettrait d'abandonner setup.py
en supprimant en même temps MANIFEST.in
et setup.cfg
.
Malheureusement, je souhaite pouvoir utiliser Heroku, avoir ma version dans le code Python, installer en mode développement et je tiens à mon intégration PyCharm.
En attendant une bonne intégration dans PyCharm et que les outils manquants (comme Heroku ou mypy) permettent d'utiliser le pyproject.toml
, je pense que je vais rester sur du classique :
-
setup.cfg
pour tout y noter sauf les dépendances, -
setup.py
presque vide (en y marquant uniquement les dépendances), -
MANIFEST.in
, -
requirements.txt
, -
virtualenv
pour générer le virtualenv.
Bref :
- je vais continuer à regarder le prometteur
poetry
, - je mets
pipenv
à la poubelle, - je vais rester sur
setup.py
,setup.cfg
,MANIFEST.in
,requirements.txt
etvirtualenv
en attendant, - je n'ai pas regardé les perfs (même si apparemment
poetry
est meilleure quepipenv
).
Au passage, ça serait vraiment pas mal de pouvoir définir une bonne partie de ma configuration PyCharm dans un fichier de configuration, pour permettre à quelqu'un d'autre de configurer rapidement le projet.
Il est en effet nécessaire de définir :
- l'interpréteur Python,
- une ou plusieurs commandes à exécuter en cas de modification d'un fichier (Filewatcher) avec leur « scope » de surveillance,
- plusieurs run configurations,
- les paramètres de plusieurs langages ou frameworks (comme Django, npm, Javascript),
- lister les plugins nécessaires,
- exclure quelques dossiers de la recherche (dossiers qui n'existent pas toujours dès le début).
Le fichier .editorconfig
se limite à l'aspect du code.
Aller un peu plus loin serait un vrai plus, même si on peut maintenant versionner les run configurations.
# Dependences non-python
Posté par Benjamin Henrion (site web personnel) . Évalué à 1.
A Europython en 2003, je disais que Pypi c'etait pas top, et que ça ne gérait pas les dependences non-python. 17 ans plus tard, c'est toujours le même probleme.
[^] # Re: Dependences non-python
Posté par azmeuk (site web personnel) . Évalué à 3.
Que sont les dépendances non-python ? Tu parles de headers C pour construire des bibliothèques ?
[^] # Commentaire supprimé
Posté par Anonyme . Évalué à 2.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: Dependences non-python
Posté par barmic 🦦 . Évalué à 6.
C'est probablement pas à europython qu'il aurait fallu en parler. Il n'existe pas de gestionnaire de paquets pour les 2 langages qui s'interfacent avec le reste du mondeC et C++. C'est probablement par là qu'il faudrait commencer. La communauté python n'a probablement pas envie de se convertir à la maintenance de paquets systèmes.
Ça tombe bien, des gens qui font de l'empaquetage de ce type de bibliothèque, il y en a pleins. Le seul problème c'est qu'ils sont tellement qu'ils n'arrivent pas à se mettre d'accord sur un format de paquet… pkgsrc, nix et guix comme ils sont utilisables par un simple utilisateur peuvent probablement faire le travail.
Mais la plupart des utilisateurs d'un langage s'en foutent. Ils regroupent ça dans les prérequis systèmes qui inclus aussi la présent de telle base de données par exemple et vont gérer ça avec soit les de l'infra automation (ansible, salt, puppet,…) ou des images systèmes prêtes et réutilisables (vagrant ou docker).
Du coup le problème est adressé autrement.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Dependences non-python
Posté par saimn . Évalué à 2.
Il y a bien conda, qui au fil du temps est devenu un gestionnaire de paquets plus généraliste.
# Invoke et autres
Posté par Spack . Évalué à 5.
Invoke est un autre outil qui ne me quitte jamais et qui permet de scripter les tâches courantes d'un projets.
À côté de cela j'ai aussi :
À tester :
[^] # Re: Invoke et autres
Posté par flan (site web personnel) . Évalué à 2.
Je connaissais un peu Invoke (mais il y a fort longtemps, quand Fabric a été abandonné), mais je n'ai jamais utilisé. Je note quand même l'idée.
Que vaut yapf par rapport à black ?
[^] # Re: Invoke et autres
Posté par Octabrain . Évalué à 2.
Autant black ne se veut pas configurable du tout, le code formaté n'est pas beau, et il produit des diffs bruités ("c'est de la merde, mais c'est black qui l'a fait donc on laisse comme ça"), autant yapf est très configurable, et le code est plus beau, mais yapf a pas mal de bugs.
[^] # Re: Invoke et autres
Posté par barmic 🦦 . Évalué à 4.
Ce n'est pas ce que j'ai observé (du peu que je m'en suis servi) et c'est l'un des principaux objectifs du projets. Tu aurais un exemple en tête ?
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Invoke et autres
Posté par flan (site web personnel) . Évalué à 2. Dernière modification le 24 août 2020 à 19:15.
Le principe de black est en effet de ne pas être configurable, pour éviter que chacun le configure à sa façon… Cela dit, mettre la configuration (comme pour tout le reste des outils, dont l'IDE) permet de compenser ce problème.
Mais je ne comprends pas cette histoire de bruit.
# version de python
Posté par blobmaster . Évalué à 6.
Je commence toujours par choisir la version de python officielle du projet sur lequel je travaille :
https://github.com/pyenv/pyenvpyenv local 3.7.2
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.