Journal Mes outils Python en 2020

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
14
18
août
2020

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.

  • # Dependences non-python

    Posté par  (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  (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  . Évalué à 2.

      Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Re: Dependences non-python

      Posté par  . É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  . É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  . É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 :

    • pre-commit qui exécute un ensemble de tâches avant un commit et cela sans avoir besoin d'installer chaque outils au préalable.
    • yapf en complément de black parce que 2 c'est mieux que 1.

    À tester :

    • Pysa, un analyseur statique pour Python créé par Facebook.
    • mypy pour une vérification statistique de l'usage des types annoncés.
    • [^] # Re: Invoke et autres

      Posté par  (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  . É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  . Évalué à 4.

          il produit des diffs bruités

          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  (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  . Évalué à 6.

    Je commence toujours par choisir la version de python officielle du projet sur lequel je travaille :

    pyenv local 3.7.2
    https://github.com/pyenv/pyenv

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.