URL: https://linuxfr.org/users/flan--2/journaux/mes-outils-python-en-2020 Title: Mes outils Python en 2020 Authors: flan Date: 2020年08月18日T21:03:14+02:00 License: CC By-SA Tags: python3 Score: 14 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 configuration `setup.cfg` et qui demande également un `MANIFEST.in`, * `pip`, qui permet d'installer le projet avec ses dépendances, grâce notamment à un fichier `requirements.txt`, * `pipenv`, qui va s'occuper du virtualenv et des dépendances avec son fichier `pipfile`, * `poetry`, qui s'occupe du virtualenv, des dépendances, et de la configuration d'autres outils avec son fichier `pyproject.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 menu `Run 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 dans `setup.py`, `requirements.txt` ou `Pipfile`, PyCharm me propose de l'ajouter, * PyCharm fait le boulot tout seul pour la création des virtualenv, que ce soit via `virtualenv`, `pipenv` ou `poetry`. 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écuter `setup.py` (on perd l'intérêt d'un `setup.py` toujours exécutable), * accepter d'avoir des informations redondantes à gérer à la main, * regénérer automatiquement `setup.cfg` quand on modifie `pyproject.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` et `virtualenv` en attendant, * je n'ai pas regardé les perfs (même si apparemment `poetry` est meilleure que `pipenv`). 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_.