• [^] # Re: Excellent article

    Posté par (site web personnel, Mastodon) . En réponse à la dépêche L'installation et la distribution de paquets Python (2/4). Évalué à 3.

    D'accord ok mais du coup cela ne pose-t-il pas un pb d'orchestrer l'ensemble qui fonctionne dans des environnements séparés ? si mon application dépend de lib1 dans env1 (et qui partagerait cet environnement, pour faire plus simple), et de lib2 dans env2, combien ai-je d’interpréteurs lancés ? Faut-il des mécanismes particuliers pour partager les données s'il y en a plusieurs ? Ou alors je suis a côté de la plaque et l'env est complètement transparent pour au runtime.

    Ah... mais non, il y a un environnement par application, pas un environnement par dépendance de chaque application. Si j'installe Sphinx avec pipx install sphinx, pipx va créer un environnement pour Sphinx, et mettre toutes les dépendances de Sphinx dans cet environnement, donc aucune interaction entre environnements, Sphinx s'exécute juste à l'intérieur de cet environnement. Par contre, si je fais ensuite pipx install hatch, il y aura un environnement séparé pour Hatch.

    Par ailleurs comme tu le soulignes pour les distributions linux, on n'utilise pas directement pip pour installer les paquets mais la distribution qui bénéficient du travail de ces mainteneurs. Cela rendrait l'utilisation de pipx superflue dans ce cas non ?

    Oui, si on dispose d'un paquet de sa distribution et qu'on préfère l'utiliser, on n'a pas besoin de pipx. Par contre, s'il n'y a pas de paquet dans la distribution, ou si ce n'est pas la bonne version, il faut passer par pipx. (Et accessoirement, si on est sous macOS ou Windows, on n'a pas le choix.)

    Quand à l'espace disque utilisé : il me semble que python laisse un fichier compilé des modules lancés, ce qui multiplie l'espace utilisé.
    Je viens de l'embarqué, l'optimisation de l'espace disque reste un critère dans les choix de design. C'est moins le cas pour des applications desktops.

    Ces fichiers contiennent du « bytecode », un code intermédiaire qui est de bas niveau mais pas du code natif. Ce n'est pas si lourd.

    Dans mon ~/.local/pipx/, ces fichiers font moins d'un quart de la taille totale (88 Mo / 379 Mo, les 88 Mo sont comptés par du --si -ch $(fd -g '*.pyc')).

    Alors le lock file est il un fichier pour le "packageur" ou l'utilisateur ?

    Ça dépend de quel utilisateur on parle, mais en tous cas, jamais pour un "packageur" lorsqu'il distribue une librairie ou application. Mettons que je développe l'application Sphinx. Il est absolument hors de question que je crée un lock file pour fixer toutes les dépendances de Sphinx et que j'en fasse les dépendances du paquet que je distribue. Par exemple, si je le fais, les mainteneurs de distributions Linux vont me détester parce que je vais forcer les versions exactes de tous les paquets dont je dépends. Par exemple, je vais exiger jinja2 3.1.2. Et il suffirait que le mainteneur d'une autre application, disons Flask , fasse la même chose mais exige jinja2 3.1.1, pour qu'il devienne impossible à la distribution de proposer à la fois Sphinx et Flask.

    Par contre, si je suis développeur d'une librairie, mettons foo, et que foo utilise Sphinx comme outil de documentation, je peux avoir un lock file qui fixe les versions de Sphinx et de ses dépendances que je veux pour générer ma documentation. Mais le contenu de ce lock file n'a rien à voir avec les dépendances de ma librairie foo elle-même. Les utilisateurs de ma librairie foo ne verront jamais mon lock file, ils verront juste ma jolie documentation.

    Est-ce que la finalité de ces différents backend c'est de pousser les paquets sur pypi ?

    Par définition, un build backend est ce qui génère les fichiers sdist et wheel, qui sont les formats distribués sur PyPI. Donc, tous les build backends (dont Hatchling, Poetry-core, PDM-backend et Flit-core) permettent de distribuer sur PyPI, il n'y a aucun problème d'interopérabilité à ce niveau-là.

    En fait j'essaie de compiler en tête les critères pour sélectionner un backend plutôt qu'un autre, dans une sorte de table tu vois.

    Attention à ne pas confondre le choix du build backend avec le choix d'un outil plus large qui maintient des environnements, compile des lock files et ce genre de choses. En particulier, si tu as besoin de lock files avec Conda, tu peux utiliser PDM, et PDM te laisse le choix du build backend (il possède son propre build backend PDM-backend, mais ce n'est pas une obligation de l'utiliser, tu peux aussi te servir de PDM tout en ayant Hatchling, Poetry-core ou Flit-core comme build backend).

    Bêtement je pensais utiliser pyinstaller pour un truc très simple à fournir à un utilisateur non-developpeur. Mais visiblement on propose cet outil pour freezer plus que pour distribuer un package, même si pyinstaller génèrerait les bons fichiers pour.

    Disons que le freeze est une première étape. Ensuite, on peut passer un coup de Inno Setup par exemple.

    J'ai une connaissance qui a utilisé poetry, visiblement à cause de la complexité des dépendances de l'application utilisé. Je prends peut-être un raccourci, mais genre si la gestion du packaging est est complexe a cause des dépendances alors prends poetry qui t'évitera les accidents.

    Le résolveur de Poetry est effectivement censé faire des choix plus malins en contrepartie du temps qu'il prend. Je n'ai pas d'expérience pour savoir si les avantages sont substantiels.

    Comme je l'écrivais dans la dépêche, il résout toutes les dépendances en même temps (dépendances du projet mais aussi de ses outils de test et de documentation), ce qui peut causer des problèmes inutilement.

    Ensuite j'ai l'impression qu'anaconda vise un milieu bien particulier pour les applications : une simple recherche google et dans le résumé du lien je lis : "Python/R data science and machine learning on a single machine".

    Oui, Conda s'adresse clairement à un public de calcul scientifique.