# Faire ses paquets En respectant les standards. ::: notes Se présenter, hackinscience, formations, ... ## Donc on va parler de distutils ? PEP 632 (septembre 2020) : Deprecate distutils module. La doc dit de ne plus l'utiliser depuis ~2014… ::: notes setuptools à commencé en étant du monkey-patch de distutils, maintenant setuptools intègre sa copie de distutils. ## Donc on va parler de {buzzword} ? - pipenv : 304k lignes de code. - bento : 37k lignes de code. - poetry : 16k lignes de code. - flit : 4k lignes de code. - build : <1k lignes de code. ::: notes Ils utilisent tous setuptools ^^ ## Non mais pourquoi pas {buzzword} ? - Ça demande du temps pour migrer d'un standard à un outil tiers. - Ça demande à une partie de l'équipe d'apprendre ce nouvel outil. - Puis ça demande du temps pour migrer à nouveau vers le standard quand l'outil est abandonné. ::: notes On a mieux a faire de notre temps. ## Mais les Pipfile ? En fait oui et non, Pipfile c'est une spec à part : => https://github.com/pypa/pipfile Rien n'empêche d'un jour pouvoir faire un : ``` pip install --pipfile Pipfile.lock ``` ::: notes Cherchez dans les issues de pypa/pip, la discussion est ouverte. Et puis pipenv c'est abandonné ? # OK, bon, comment on fait sans buzzwords ? ## pyproject.toml Les PEP 517 et 518 normalisent la construction de paquets en déclarant son outil de build dans `pyproject.toml` : ```toml [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" ``` Le backend étant `setuptools.build_meta`, on aura besoin d'un `setup.cfg`. ::: notes C'est typiquement utilisé par pip lors d'un `pip install .`. ## setup.py En 2020 il ne prenait plus qu'une ou deux lignes, bienvenu en 2021. ::: notes `setuptools` autorise depuis la v40.0.9 de ne pas avoir de `setup.py`, à condition d'avoir un `pyproject.toml`. (La PEP517 ne gère pas encore les installations éditables, si vous les utilisez, vous aurez donc tout de même besoin d'un `setup.py`.) https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects Bon c'est quand même pratique les installations éditables, et `pip-compile setup.py`. ## setup.cfg ``` [metadata] name = oeis version = attr: oeis.__version__ description = Implementation of a few integer sequences. long_description = file: README.md long_description_content_type = text/markdown; charset=UTF-8 ... ``` ::: notes Voir mon setup.cfg sur le projet githup.com/JulienPalard/oeis. ## Vous venez de 2020 ? Ne faites pas la conversion à la main ! ```text pip install setup-py-upgrade ``` ## Comment je build ? On peut utiliser `build` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien : ``` pip install build python -m build --sdist --wheel . ``` ::: notes Les dépendances de build sont installées dans un environnement isolé (*isolated build*). Oui oui il crée vraiment un venv, avec le module venv de Python. Pas besoin de `pip install setuptools wheel` ## Et comment j'upload ? On peut utiliser `twine` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien : ```text pip install twine twine upload -r test dist/* pip install --index-url https://test.pypi.org/simple/ oeis twine upload dist/* ``` # Et les dépendances !? Les dépendances « runtime » (`install_requires`) sont décrites dans le `setup.cfg`. ## Épinglées ou pas ? Ça dépend de ce que vous faites, mais généralement on vise le plus large possible. ::: notes Vous voulez que votre lib, ou votre programme puisse s'installer sans conflit avec une autre lib ou un autre programme. Et on ne va pas maintenir, à la main, dans le setup.cfg, des versions précisément. ## Épingler saybien ! Je n'ai pas dit que c'était mal, c'est très bien pour les développeurs, pour la CI, pour la prod… ## Épingler saybien ! J'utilise un outil qui ne fait qu'une chose mais qui le fait bien : `pip-compile` du paquet `pip-tools`, ça ne fait *que* geler les dépendances, et ça le fait bien. ::: notes Oui on sent que je n'aime pas les projets qui essayent de tout résoudre d'un coup. ## Épingler saybien ! On peut donc "geler" les dépendances du projet via un : ``` pip-compile setup.py ``` ::: notes https://github.com/jazzband/pip-tools/issues/1047 ## Épingler saybien ! On peut ensuite documenter ses dépendances de dev dans un `requirements-dev.in` : ```txt -r requirements.txt tox ``` ## Épingler saybien ! Et épingler aussi les requirements de dev, afin de les utiliser dans des tests reproductibles : ```txt pip-compile requirements-dev.in ``` ## Épingler saybien ! On peut même hasher les dépendances pour les plus paranos : ```txt pip-compile --generate-hashes setup.py ``` ## Qu'est-ce que ça donne ? ``` pyproject.toml // 3 lignes setup.cfg requirements.txt // autogénéré par pip-compile requirements-dev.in requirements-dev.txt // autogénéré par pip-compile ``` ## Mettre à jour ```txt pip-compile --upgrade requirements-dev.in ``` # Installer Il existe un outil qui ne fait qu'une chose, mais qui le fait bien : `pip`. ``` pip install oeis ``` ## Installer Vous connaissez alors je passe sur le plus gros, mais n'oubliez pas : ```txt pip install git+https://github.com/org/project@branch ``` ::: notes Typiquement pour tester la PR de quelqu'un (et oui ça déclenche la construction d'une wheel via les dépendances et le point d'entrée décrit dans pyproject.toml). # RTFM - https://setuptools.readthedocs.io/en/latest/build_meta.html - https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html - https://packaging.python.org/guides/using-testpypi/ - https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects # Questions ?