Pip: Vers PEP 518

Créé le 21 oct. 2017  ·  101Commentaires  ·  Source: pypa/pip

Je suis AWOL ce week-end mais si je comprends bien, il doit y avoir une discussion vers PEP 518 et sa mise en œuvre dans pip.

J'ai ouvert ce sujet, car je n'ai pas pu localiser où se déroulait la discussion, si c'est le cas. De plus, l'avoir à un endroit qui n'est pas pypa-dev/distutils-sig serait sympa ?

auto-locked maintenance

Commentaire le plus utile

Vous avez généralement besoin d'installations de pip distinctes à exécuter à l'intérieur d'un sous-processus, à cause des caches dans des endroits comme pkg_resources je crois (bien que je puisse me tromper là-bas).

Cela ne signifie pas que vous devez appeler pip , vous pouvez créer une API qui sérialise les données via la CLI et appeler python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" et lire plus de données hors stdout. Il serait possible de transformer la solution récursive des pips appelant pips appelant pips appelant pips en la transformant en une pile en utilisant une telle API (puisque toute récursivité peut également être décrite comme une pile), vous feriez essentiellement une API privée qui est appelé en tant que processus.

Je prévois toujours de lire ce fil (j'ai eu un tas d'assiettes qui tournaient ces derniers temps !), Mais une chose au-dessus : nous n'avons pas vraiment de calendrier de publication, nous publions quand il est prêt et non à une date cible. Nous avons parfois une idée générale du moment où nous aimerions sortir, mais ce n'est jamais gravé dans le marbre.

Tous les 101 commentaires

4799 est l'endroit où se déroule une grande partie du débat. Il a été principalement motivé par :

  1. J'ai compris que le seul bloqueur exceptionnel du support PEP 518 était le # 4764 (via https://github.com/pypa/pip/pull/4144#issuecomment-302711736)
  2. Puis # 4799 est apparu et je l'ai regardé pour voir si je pouvais donner un sens à tout le travail en cours que faisait @xoviat .
  3. Au cours de cela, # 4647 est apparu comme un bloqueur de publication indiquant que le support PEP 518 était cassé.

Alors que je creusais pour essayer de comprendre ce que @xoviat disait dans # 4799, il est devenu évident que nous avions des problèmes autour de la construction récursive d'environnements de construction (X a besoin de Y pour construire, et Y a besoin de Z, ...) bien que je ' Je ne sais toujours pas s'il s'agit de bogues d'implémentation, de problèmes de conception plus profonds ou de cas désagréables que nous pouvons différer sans trop de problèmes.

Personnellement, je suis au point où je suis hors de ma profondeur. Je ne comprends pas l'implémentation de @xoviat pour juger si c'est nécessaire, ou si nous avons juste besoin de fusionner # 4764 et de corriger # 4647 pour être prêt à partir. Je ne sais pas non plus à quel point il sera facile de réparer # 4647 ( @xoviat semble dire que nous devons fusionner # 4799 pour réparer # 4647, mais cela pose ses propres problèmes).

J'ai manqué de temps et d'énergie pour approfondir la discussion ce week-end, donc je vais abandonner à ce stade (au moins pour un moment). Pour moi, le point clé est que nous voulons un niveau acceptable de support PEP 518 pour le pip 10. J'aimerais que quelqu'un me dise si nous y sommes presque ou si nous sommes dans des semaines, afin que je peut éviter d'exciter les gens à l'idée que le pip 10 arrive pour ensuite dire que ce ne sera pas avant la nouvelle année ...

Merci pour un résumé très utile @pfmoore.

@ncoghlan @dstufft @xoviat Pouvons-nous, s'il vous plaît, amener la discussion ici ? Le faire sur un PR fermé me semble bizarre. ._.

Chose sûre.

@pradyunsg Je sais que tu n'as pas le temps pour ça. Mais vous avez mieux réussi à faire approuver les PR que moi, donc si vous le souhaitez, je serai plus qu'heureux de vous expliquer la mise en œuvre actuelle, son fonctionnement et les problèmes potentiels qu'elle présente. J'expliquerai comment j'ai résolu certains (mais pas tous) de ces problèmes et mes idées pour une solution complète (ce que, encore une fois, je pourrais faire après PEP 517 si ce n'est pas fait). Honnêtement, je me fiche de savoir qui fait le travail tant qu'il est fait.

En fait, vous êtes AWOL, alors laissez-moi écrire un résumé :

pip a une hiérarchie d'objets, comme c'est souvent le cas dans la plupart des projets Python. Tout commence par la commande, qui crée de nouvelles références aux objets, qui créent de nouvelles références aux objets inférieurs. C'est comme un arbre.

Je définirai la "portée" d'un objet comme une sorte de durée de vie. C'est la durée pendant laquelle un objet existe. À l'heure actuelle, la portée de la PEP 518 dans pip est le WheelBuilder . L'environnement PEP 518 est configuré pour bdist_wheel , puis bdist_wheel est exécuté dans cet environnement, puis l'environnement est supprimé.

Alors quel est le problème avec ça ? Le problème est que la portée de l'environnement PEP 518 doit être égale ou supérieure à la portée de tous les appels à setup.py . Plus précisément, il doit encapsuler un objet qui existe pendant toute la durée des appels setup.py . Cet objet est Requirement .

La première décision évidente que vous rencontrerez est : ce qui devrait avoir une référence à BuildEnvironment , et le Requirement est un bon endroit comme n'importe quel autre. En fait, c'est le meilleur endroit à mon humble avis pour mettre la référence car setup.py est appelé si et seulement si Requirement existe.

Le problème suivant que vous pouvez rencontrer est le suivant : comment installer les exigences BuildEnvironment ? Nous pourrions simplement débourser pip . Et c'est la décision qui a été prise par l'exécutant d'origine. Mais il y a un problème avec cela : pip n'a aucun moyen de savoir combien d'appels shell il fait parce que chaque pip pourrait s'appeler à nouveau. En fait, un paquet construit de manière malveillante avec des dépendances circulaires pourrait planter l'ordinateur de quelqu'un si pip engendrait trop de processus.

Un autre problème est quel appel shell devrions-nous faire ? C'est en fait plus délicat que vous ne le pensez, car obtenir les paramètres de ligne de commande est franchement un PITA où vous devez passer cet appel. Vous pourriez donc avoir des difficultés à transmettre les paramètres d'origine que l'utilisateur a transmis à l'enfant. La solution utilisée par l'implémenteur d'origine impliquait l'utilisation de finder , mais je pense que vous connaissez le problème avec cela.

Décortiquer un enfant de vous-même sans une sorte de classe de gestionnaire qui peut tuer des enfants lorsque l'utilisateur appuie sur ctrl + C n'est pas seulement faux, c'est malveillant, surtout lorsque vous ne savez pas combien de processus vous avez générés. Personnellement, je ne sais pas si les enfants meurent dans l'implémentation actuelle (cela pourrait être FUD), mais s'ils ne le font pas, l'implémentation actuelle à mon humble avis est fausse (à part les autres préoccupations).

Voici quelques solutions possibles à ce problème :

  1. Si vous voulez sortir le PEP 518, votre meilleur pari est probablement une sorte de fichier de verrouillage qui n'autorise que jusqu'à 10 verrous environ pour vous assurer que pip ne se multiplie pas à l'infini. Ensuite, vous pouvez simplement transmettre les exigences exactes à l'enfant avec les arguments de ligne de commande.

  2. Une solution appropriée, que j'aimerais implémenter après la PEP 517, consiste à avoir une classe BuildEnvironmentManager initialisée directement dans la commande install . le BuildEnvironmentManager aurait une référence à tous les objets qui s'y trouvent ( RequirementPreparer , WheelBuilder , etc.), et aurait une seule méthode : get_build_environment(requirement_set) . Vous pouvez ensuite implémenter une méthode sur RequirementPreparer qui ressemble à set_build_environment_manager , qu'elle peut ensuite utiliser pour obtenir des environnements de construction. Le BuildEnvironmentManager pourrait même détecter plusieurs utilisations du même environnement (le plus souvent ['setuptools', 'wheel'] ) et fournir le même environnement s'il est nécessaire plusieurs fois afin que vous n'ayez pas besoin de le créer ( très courant au départ avec des projets n'ayant pas pyproject.toml ). Idéalement, il y aurait aussi une conception OOP pour essayer de supprimer les références circulaires (pas triviales).

@xoviat Bien que cela ne couvre peut-être pas le cas de la malveillance délibérée, ai-je raison de penser qu'un cache de construction (qui a été utilisé même lorsque --no-binary :all: a été spécifié) avec la possibilité de suivre non seulement les constructions terminées, mais aussi dans -progress ceux, seraient suffisants pour s'assurer que les cycles de dépendance de construction se sont terminés ? Ce serait une variante de votre première suggestion (une limite inter-processus sur le nombre d'invocations pip simultanées), mais reformulée comme suit :

  1. Un seul processus sur une machine est autorisé à créer le même package en même temps
  2. Il existe un "ID de construction" de niveau supérieur que pip transmet à toutes les sous-constructions qu'il génère (par exemple, le PID du processus de niveau supérieur combiné avec le nom du package en cours de construction)
  3. Si le cache de construction indique que quelque chose est en cours de construction par un ID de construction différent , attendez que cette construction se termine
  4. Si le cache de construction indique que quelque chose est déjà en cours de construction pour le même ID de construction, renflouer avec une erreur signalant la dépendance circulaire et indiquant que --binary <name> va être nécessaire pour que la construction fonctionne

pip devrait également implémenter la suggestion de @pfmoore d'exempter setuptools & wheel de la logique par défaut d'avoir besoin à la fois setuptools et wheel en tant que dépendances de construction, sinon l'injection de dépendance de construction implicite déclencherait de manière inhérente la logique de détection de dépendance circulaire.

Utiliser le disque pour éviter d'avoir à résoudre des problèmes de conception OOP n'est pas une mauvaise idée. C'est comme une option intermédiaire entre la mise en œuvre complètement correcte de la PEP 518 et le piratage de quelque chose ensemble.

Il interagirait également bien avec les environnements conteneurisés et les chroots en général, puisque nous serions en mesure d'utiliser des outils au niveau du système d'exploitation pour garder différentes versions de niveau Python isolées les unes des autres, donc pip aurait juste besoin de comprendre comment assurer ses propres sous-processus coopérer les uns avec les autres.

@xoviat merci pour le résumé ci-dessus. Comme je l'avais dit, j'avais atteint la limite de ma compréhension du code dans ce domaine, et votre explication m'a énormément aidé.

Je n'avais pas réellement regardé le code de # 4144 auparavant. Je viens de le faire et je ne veux vraiment pas que ce soit l'expédition.

mettre en œuvre PEP 518 complètement correctement et juste pirater quelque chose ensemble.

Honnêtement, je pense que cela se résume à cela. La mise en œuvre complète et correcte de la PEP 518 est une tâche qui retarderait/pourrait retarder le pip 10 d'un peu (juste) si nous suivons cette voie.

Je pense qu'un terrain d'entente sûr ici serait d'exiger que les dépendances de construction soient disponibles en tant que roues. De cette façon, nous pouvons éviter le problème de récursivité puisque les dépendances de construction (et toutes leurs dépendances) n'auraient pas besoin d'être construites via ce processus.

Comment cela sonne-t-il ?

C'est restreint, mais je pense qu'une première implémentation restreinte est préférable à une première implémentation où vous pouvez vous tirer une balle dans le pied si vous n'êtes pas prudent.

La mise en œuvre complète et correcte de la PEP 518 est une tâche qui retarderait/pourrait retarder le pip 10 d'un peu (juste) si nous suivons cette voie.

Merci d'avoir confirmé cela - c'était ma crainte.

Cependant, maintenant je suis confus, car je pensais qu'au moins une partie de la PEP 518 était déjà en master. Plus précisément, si je comprends bien, # 4647 démontre un bogue dans le support PEP 518 dans master - il est donc clair que nous avons déjà quelque chose , car quoi que ce soit, ce n'est pas correct ...

Nous devons donc faire quelque chose, et il semble que les options soient :

  1. Déchirez tout ce que nous avons pour le support PEP 518 pour le moment.
  2. Rangez ce que nous avons et expédiez une assistance partielle.
  3. Implémentez complètement la PEP 518 avant de publier le pip 10.

Comme vous le dites (3) signifie un long délai avant le pip 10 et nous avons d'autres correctifs que j'aimerais vraiment voir publiés (les correctifs Unicode étant l'un de ceux sur lesquels nous rencontrons régulièrement des problèmes). Donc je n'ai pas envie de ça. Vous n'avez pas mentionné (1), et je ne sais pas si c'est parce que vous pensiez que nous n'avions pas de support PEP 518 en place, ou si vous supposiez que le recul n'était pas une option. Personnellement, je n'aime pas l'idée - c'est un pas en arrière, et cela envoie un message assez négatif sur le PEP lui-même, si c'est si difficile à mettre en œuvre correctement. Mais je pense que nous devrions être explicites quant à son rejet.

Votre proposition pour (2), que nous expédions une version de PEP 518 qui ne prend en charge que les roues en tant que dépendances de construction (nous aurions encore besoin de corriger # 4647, car la démonstration de cela utilise une dépendance de construction qui est une roue) semble raisonnable , dans le sens où c'est pratique pour nous à mettre en œuvre. Ma principale réserve est que je n'ai aucune idée à quel point cette restriction serait problématique pour les personnes qui souhaitent utiliser la PEP 518.

Donc je suppose que j'ai l'impression que nous sommes coincés quoi que nous fassions, mais un support partiel couvrant uniquement les roues en tant que dépendances de construction est la meilleure option parmi un mauvais lot :-(

Les auteurs du PEP (dans https://github.com/pypa/pip/pull/4799#issuecomment-338331267 et https://github.com/pypa/pip/pull/4799#issuecomment-338332575 en réponse à ma question dans https://github.com/pypa/pip/pull/4799#issuecomment-338325354) étaient assez clairs sur le fait que la prise en charge complète de PEP nécessitait la construction de toutes les dépendances de construction, donc cela ne doit être qu'un palliatif.

Mais ce n'est pas moi qui vais mettre cela en œuvre, donc je suis heureux d'aller avec le jugement de celui qui le fait. Une chose que j'ai faite est de créer #4803 et de le marquer comme un bloqueur de version, pour nous rappeler que nous devons documenter comment nous nous écartons de la spécification, si nous en avons besoin.

(Et hors sujet pour ce problème, mais puis-je suggérer que nous fassions attention à ne pas commettre les mêmes erreurs lorsque nous commençons à mettre en œuvre la PEP 517 ? Assurons-nous de comprendre toutes les implications de la mise en œuvre avant d'aller trop loin dans le codage - mon instinct est que la PEP 517 va être un problème de conception encore plus complexe que la PEP 518...)

Je connais mieux les distributions en ce qui concerne la perspective "tout construire à partir de la source", et nous séparons définitivement le processus d'"amorçage de la racine de construction" de celui des versions de packages standard. L'amorçage automatique complet à partir de la source est difficile , car vous finissez par avoir à faire des choses comme amorcer votre compilateur C.

Donc, pour pip, je pense qu'il est raisonnable de dire que les dépendances de construction seront toujours installables à partir des fichiers wheel. Le raffinement que vous pouvez introduire après 10.x consiste à disposer d'un cache de construction distinct du cache de roue standard, de sorte que les utilisateurs du cache peuvent être sûrs que toutes les roues ont été construites dans un environnement contrôlé, plutôt que téléchargées à partir de PyPI. ou un autre serveur d'index.

Personnellement, je n'aime pas l'idée - c'est un pas en arrière, et cela envoie un message assez négatif sur le PEP lui-même, si c'est si difficile à mettre en œuvre correctement.

Je ne suis pas forcément d'accord avec ça. Il est difficile à implémenter correctement pour pip. Mais pip, comme indiqué dans le PEP, est l'un des seuls frontaux que les gens vont utiliser. Je pense que c'est notre travail en tant qu'implémenteurs de langage, et pip est vraiment un langage que les gens utilisent pour empaqueter leurs projets python, pour rendre aussi simple que possible la création d'un système de construction sans avoir à penser à tous ces problèmes difficiles. Pour eux, cela devrait fonctionner de manière transparente, car nous avons fait le travail acharné.

Je pense qu'un terrain d'entente sûr ici serait d'exiger que les dépendances de construction soient disponibles en tant que roues.

En fait, c'est exactement ce que fait #4799. Si vous le souhaitez, je peux restaurer cette branche, puis vous pouvez la bifurquer et la soumettre en tant que PR.

Deux choses du côté de la mise en œuvre des choses de (2) sont toujours valables - comme @xoviat l' avait souligné ci-dessus :

  1. comprendre comment créer le sous-processus (arguments et al)
    Je pense que ça devrait être faisable.

  2. les versions de package à installer.
    Cela devrait probablement être fait dans le même processus parent bien que je ne sache pas exactement comment cela se produirait étant donné que le code de résolution actuel est toujours entrelacé avec le code dans pip._internal.operations.prepare . J'examinerai cela cette semaine.

Je ne sais pas qui aurait le temps de les faire cependant.


cela envoie un message assez négatif sur le PEP lui-même, s'il est si difficile à mettre en œuvre correctement.

Il n'est probablement pas difficile à mettre en œuvre correctement. C'est juste qu'avec la façon dont la base de code de pip est aujourd'hui, ce n'est pas trivial à implémenter dans pip - il y a des choses qui se passent dans des endroits bizarres et je pense que si cela est nettoyé, ce serait assez trivial.

Vous n'avez pas mentionné (1), et je ne sais pas si c'est parce que vous pensiez que nous n'avions pas de support PEP 518 en place, ou si vous supposiez que le recul n'était pas une option.

J'ai supposé que reculer n'était pas une option.

Maintenant que j'y pense - à quel point est-il important d'expédier PEP 518 en pip 10 ? Je pense que si cela peut être reporté à la prochaine version majeure, ce serait (autre que le moyen facile de sortir de cette situation) être simple et les deux 517 + 518 pourraient atterrir dans une seule grande version. Cela semble assez propre pour que je ne sois pas celui qui dise que ce n'est pas la voie à suivre.

@dstufft @xavfernandez pensées?


L'idée de @ncoghlan d'un build-cache me semble être une bonne idée même si je ne suis pas sûr d'en comprendre toutes les implications.


Si vous le souhaitez, je peux restaurer cette branche, puis vous pouvez la bifurquer et la soumettre en tant que PR.

Je n'aurai probablement pas le temps et même si je le fais, je ne réutiliserai peut-être aucun commit existant. Mais restaurer cette branche ne peut pas faire de mal. :)

Ma principale réserve est que je n'ai aucune idée à quel point cette restriction serait problématique pour les personnes qui souhaitent utiliser la PEP 518.

Nous avons eu cette discussion exacte sauf que vous ne le saviez probablement même pas. Cette situation est la situation X. Appeler egg_info avant que l'environnement de construction ne soit configuré est la situation Y (#4799).

Mais ce n'est pas moi qui vais mettre cela en œuvre, donc je suis heureux d'aller avec le jugement de celui qui le fait.

Je suppose que cela signifie que # 4799 est de retour sur la table alors? Tant qu'il passe tous les tests et fait ce qu'il prétend faire ?

Aargh, ces X et Y reviennent me hanter à nouveau :wink: Oui, je dis que je n'ai aucune idée des probabilités relatives des 2 cas. Je comprends que vous dites que les exigences de construction qui ne sont pas des roues sont suffisamment rares pour que nous soyons d'accord pour ignorer ce cas. Il y avait donc un "c'est OK" et un "je ne sais pas" entre nous, en gros. Je n'essaie pas de bloquer cette option, je dis simplement où se situent les limites de mon intuition, c'est tout.

@xoviat J'ai quelques questions. Ce serait génial si vous y répondiez avant de faire un nouveau PR. :)

  • Comment allez-vous déterminer quels packages seront installés ?
  • Allez-vous vous limiter aux dépendances de construction uniquement binaires ?

J'ai travaillé avec beaucoup de projets scientifiques donc il se peut que je sois partial. Mais je peux débiter une liste de projets avec des dépendances de construction de roue et je ne peux vraiment pas penser à un projet avec des dépendances de source. J'ai peut-être tort.

@rgommers seriez-vous d'accord avec PEP 518 ne prenant en charge que les dépendances de construction disponibles en tant que roues si c'était dans le prochain pip?

Comment allez-vous déterminer quels packages seront installés ?

Le sous-processus obtient la liste des exigences exactement comme spécifié. De cette façon, il passe par le résolveur.

Allez-vous vous limiter aux dépendances de construction uniquement binaires ?

Oui, c'est en fait la raison pour laquelle le test a échoué. La dépendance de construction dans le test n'est pas une roue.

Maintenant que j'y pense - à quel point est-il important d'expédier PEP 518 en pip 10 ? Je pense que si cela peut être reporté à la prochaine version majeure, ce serait (autre que le moyen facile de sortir de cette situation) être simple et les deux 517 + 518 pourraient atterrir dans une seule grande version. Cela semble assez propre pour que je ne sois pas celui qui dise que ce n'est pas la voie à suivre.

Que pensez-vous de savoir si quelqu'un aura le temps de faire les PEP 517 et 518 pour le pip 11 ? Je ne suis pas optimiste. Il me semble que ce sont tous les deux de gros morceaux de travail, et nous avons également le travail de résolveur en cours. Bien que je ne sois pas favorable à ce que le pip 10 reste plus longtemps que nécessaire, je suis également mal à l'aise de laisser dériver tous nos principaux plans de fonctionnalités pendant que nous publions une série de versions essentiellement mineures.

Pour le dire autrement, dire "allons-y pour une version pip 10" a provoqué une recrudescence d'activité sur le travail PEP 518. Si nous supprimons cela du pip 10, pour ma part, je me concentrerai sur la préparation des choses pour la sortie, et je soupçonne qu'il est probable que PEP 518 perde à nouveau de l'élan. Qu'est-ce qui relance les choses ? @xoviat a travaillé sur la mise en œuvre, mais il a eu du mal à nous faire comprendre les problèmes avec lesquels il s'est débattu jusqu'à présent. Je ne veux pas le laisser travailler à nouveau sans commentaires.

Ce que nous pourrions faire, c'est publier un "pip 9.1" avec uniquement les correctifs incrémentiels que nous avons prêts, et réserver le numéro de version "pip 10" pour la mise en œuvre (au moins une des) des 3 fonctionnalités à gros tickets qui sont dans le pipeline. Mais si nous faisons cela, j'aimerais essayer [1] de m'engager dans une version pip 10 au premier trimestre de 2018. Je serais d'accord avec cette approche. Mais est-ce que quelqu'un a une idée de ce que cela impliquerait de retirer le support partiel que nous avons actuellement dans master ? Ou en documentant ce que nous avons et quelles sont ses limites (afin que les gens n'essaient pas de l'utiliser en supposant qu'il est complet, rencontrent des bogues et soulèvent des problèmes auxquels nous devons répondre avec "cette fonctionnalité n'est pas encore complète, désolé mais attendez pip dix")? Sommes-nous en train d'échanger un gros morceau de travail contre un autre ?

[1] Dans la mesure où nous pouvons nous engager dans n'importe quoi avec des ressources bénévoles extrêmement limitées comme tout ce dont nous disposons.

J'ai travaillé avec beaucoup de projets scientifiques donc il se peut que je sois partial

Merci, il est parfois difficile de connaître les antécédents des gens. Si vous connaissez les projets scientifiques, cela atténue beaucoup mes inquiétudes.

Ce que nous pourrions faire, c'est publier un "pip 9.1" avec uniquement les correctifs incrémentiels que nous avons prêts, et réserver le numéro de version "pip 10" pour la mise en œuvre (au moins une des) des 3 fonctionnalités à gros tickets qui sont dans le pipeline.

J'aime vraiment ça. +1 à un pip 9.1.0 au lieu de pip 10.0.0

J'aimerais essayer [1] de m'engager dans une version pip 10 au premier trimestre de 2018. Je serais d'accord avec cela comme approche.

J'avais eu une idée très intéressante - pip fête ses 10 ans le 12 octobre 2018. Ce serait la date idéale pour faire une version pip 10.0.0. C'est une chronologie complètement différente. Je ne dis pas que nous devrions retarder les fonctionnalités de la baleine blanche jusque-là, mais une partie de moi veut vraiment que ce numéro de version et cet âge coïncident aussi.

Je soupçonne qu'il est probable que la PEP 518 perde à nouveau de l'élan.

Je ferai ce que je peux pour m'assurer que ce n'est pas le cas. Espérons que @xoviat le souhaite également. :)

quelqu'un a-t-il une idée de ce qui serait impliqué dans le soutien partiel que nous avons actuellement dans master ?

Cela ne me dérangera pas d'y jeter un œil demain. Étant donné que @dstufft était celui examiné sur # 4144, je pense que sa contribution à ce sujet serait précieuse.

Remarque - je ne voudrais pas faire quelque chose d'aussi radical que de faire marche arrière sans l'accord de @dstufft et @xavfernandez - alors voyons aussi ce qu'ils ont à dire.

@dstufft n'a pas assez de temps dans la journée. Il doit également s'assurer que l'entrepôt ne tombe pas en panne.

voyons aussi ce qu'ils ont à dire.

Oui s'il vous plaît. :)

D'un point de vue UX : contrer de manière globale l'attaque "trusting trust" est vraiment douloureux [1], et vous trouverez beaucoup de gens qui disent "je compile tout à partir de la source" ne le font pas réellement - quelque part dans leur processus là-bas sera une étape de démarrage où ils font confiance à un binaire fourni soit par quelqu'un d'autre (par exemple, l'environnement d'exécution et la chaîne d'outils de construction de leur fournisseur de système d'exploitation), soit d'une génération précédente de leur propre plate-forme (par exemple, les buildroots pour les nouvelles versions de Fedora et RHEL est semé à partir des versions précédentes de Fedora et RHEL, ils ne partent pas complètement de zéro). Même une distribution Linux basée sur les sources comme Gentoo commence par un programme d'installation pour vous offrir un environnement de construction fonctionnel avec un noyau Linux, un compilateur C, des pilotes matériels, etc.

Je pense donc qu'il est tout à fait raisonnable que pip 10 dise que --no-binary :all: ne s'applique qu'aux dépendances d'exécution, pas aux dépendances de construction. Si les gens veulent construire explicitement leur buildroot à partir de la source, ils le peuvent toujours - c'est juste que pip 10 ne l'automatisera pas implicitement pour eux en raison des problèmes d'amorçage récursifs inhérents à l'autorisation des builds source implicites pour vos dépendances de build.

Pour permettre aux gens d'indiquer qu'ils s'attendent à ce que l'environnement de construction soit entièrement préconfiguré, il serait raisonnable d'ajouter une option --no-implicit-builddeps distincte pour que l'installation échoue carrément si un démarrage binaire implicite est nécessaire dans le cadre d'une construction source . De cette façon, les personnes essayant de s'assurer que tout est construit à partir de la source (y compris les dépendances de construction) peuvent faire l'équivalent de :

pip install --no-binary :all: --no-implicit-builddeps -r build-requirements.txt
pip install --no-binary :all: --no-implicit-builddeps -r requirements.txt

Et définissez autant de groupes d'installation distincts que nécessaire pour arriver à un point où le premier n'a besoin de rien d'autre que CPython et de toute chaîne d'outils de construction non-Python préinstallée.

Un futur complément potentiel à ce concept serait de permettre aux gens de dire --buildenv <path> pour spécifier un environnement de build préconfiguré à utiliser pour toutes les builds source requises, plutôt que de faire chaque build dans un environnement isolé. Cependant, je n'essaierais pas d'intégrer cela dans pip 10 - je suggérerais de limiter 10.x au chemin heureux de "les dépendances de construction binaires sont autorisées" et à l'option alternative de "échouer la construction si une dépendance de construction binaire est nécessaire et n'est pas déjà disponible dans l'interpréteur en cours d'exécution".

[1] https://www.schneier.com/blog/archives/2006/01/countering_trus.html

J'ai pensé à une autre option, qui semble raisonnable et ne nécessiterait pas trop de refactorisation : utiliser essentiellement le multi-threading pour mettre le thread principal en attente pendant que l'environnement de construction est configuré. L'idée est un peu comme ceci : dans install.py , vous auriez un BuildEnvironmentManager :

class BuildEnvironmentManager(Thread):
    '''Has references to literally everything (cache, resolver, etc.)'''
    def run(self):
        while True:
            requirement_list, future = self.build_environment_queue.get()

            # install the requirements using all of the things
            # that we have

            # then put the build environment in the future
            future.put(BuildEnvironment())

Vous auriez alors un autre fichier (j'utilise backend.py car il n'est pas assez complet et pourrait probablement contenir plus de choses, et il se trouve à l'extrémité inférieure de l'arborescence):

class Future(Queue):
    pass

class BuildEnvironmentQueue(object):
    def __init__(self):
        self._queue = Queue()

    def request_build_environment(self, requirement_list):
        f = Future()
        self._queue.put((requirement_list, f))
        return f.get()

    def get():
        return self._queue.get()

Et dans operations/prepare.py :

# This call will put the thread to sleep until we have a build environment
# with the requirements installed
self.build_environment_queue.request_build_environment(requirement_list)

Cela a l'avantage de nécessiter une refactorisation minimale, d'avoir un BuildEnvironmentManager sérialisé (afin que les environnements de construction puissent être optimisés et que vous sachiez exactement quelles requêtes ont été faites dans un seul objet) et de garder tout contenu dans un processus (donc le le pire scénario est une impasse). Bien sûr, la journalisation devrait être désactivée pour les autres threads, mais ce n'est pas trop un problème.

Répondre à ma propre question sur l'approche basée sur queue.Queue : il est préférable d'éviter de s'appuyer sur concurrent.futures, car l'utilisation de cela nécessiterait de vendre https://pypi.org/project/futures/ dans Python 2.7.

Sans bien connaître la base de code pip , l'idée de consolider la gestion de l'environnement de construction en un seul endroit semble toujours être une option intéressante.

concurrent.futures n'est pas requis pour cette approche. Future n'est qu'un wrapper plus descriptif.

La seule primitive requise est une file d'attente : https://docs.python.org/2/library/queue.html

Je suppose que nous pouvons simplement déplacer ces lignes dans le BuildEnvironmentManager .

J'ai travaillé avec beaucoup de projets scientifiques donc il se peut que je sois partial. Mais je peux débiter une liste de projets avec des dépendances de construction de roue et je ne peux vraiment pas penser à un projet avec des dépendances de source. J'ai peut-être tort.

Eh bien, pour l'un, il y a tous les systèmes d'exploitation qui ne sont pas [Windows, macOS, Linux], IIRC ceux-ci ne sont pas couverts par manylinux1 .

@rgommers seriez-vous d'accord avec PEP 518 ne prenant en charge que les dépendances de construction disponibles en tant que roues si c'était dans le prochain pip?

Ce n'est pas ma décision, mais je serais heureux de tout pas en avant ici. Le support PEP 518 est de toute façon facultatif, donc il ne fonctionne que lorsque les roues sont disponibles (couvre> 90% des cas, je dirais) dans le pip 10 est toujours une amélioration significative.

Notez que même les plates-formes qui n'autorisent pas les roues sur PyPI auront toujours un cache de roue local, ce qui signifie que même si pip ne peut pas amorcer implicitement les choses, il peut toujours être en mesure de les imprimer et de dire "installer ces dépendances de construction d'une manière ou d'une autre , et ça marchera".

Mais est-ce que quelqu'un a une idée de ce que cela impliquerait de retirer le support partiel que nous avons actuellement dans master ?

J'ai examiné cela; ça n'a pas l'air d'être trop dur. Je serai heureux de faire un PR si nous décidons d'aller de cette façon.

+1 à un pip 9.1.0 au lieu de pip 10.0.0

J'ai enfin eu le temps de lire correctement le fil distutils-sig et de regarder les relations publiques et les discussions pertinentes (#4351, #4144, #4799 et un tas d'autres). Je pense maintenant que depuis que nous avons annoncé le pip 10 ; c'est ce que nous devrions faire, avec le support partiel de PEP 518 -- pas de 9.1.0.

ce numéro de version et l'âge coïncident

Dommage. :(

@ncoghlan Peut-être que ce commentaire est passé sous le radar - https://github.com/pypa/pip/pull/4799#issuecomment -338416543

Au cas où ce ne serait pas le cas, ce serait bien si vous pouviez expliquer pourquoi cela ne fonctionnerait pas, car je comprends en quelque sorte ce type de configuration et je suis définitivement ouvert à en savoir plus à ce sujet. :)

@pradyunsg Je pense que cela fonctionnerait principalement, car il s'agit d'une implémentation spécifique de l'idée de cache de construction. Le seul aspect qu'il ne couvre pas est la construction de boucles de dépendance, car il manque un moyen de détecter "on m'a juste demandé de construire quelque chose que j'essaie déjà de construire".

Notez que pip n'a pas besoin de résoudre comme par magie les boucles de dépendance - il a juste besoin de les détecter et d'échouer dès qu'il en repère une, plutôt que d'entrer dans une boucle infinie.

il ne couvre pas les boucles de dépendance de construction,

Cela ne se produirait pas avec des dépendances de construction uniquement binaires ?

@pradyunsg Le commentaire lié concernait un moyen d'autoriser les builds source pour les dépendances de build, ce qui signifie que les dépendances circulaires deviennent un problème potentiel. Si nous avons besoin de dépendances binaires, alors pip peut simplement s'appuyer sur le cache de roue existant pour le moment.

Ah d'accord. Merci! :)

Je suis en faveur d'un pip 10 avec une implémentation partielle de PEP 518 limitée aux dépendances de construction binaires uniquement (ou déjà disponible dans le cache de roue pip) si c'est tout ce que nous parvenons à inclure.

Je n'ai pas encore lu l'intégralité du fil de discussion, mais je tiens simplement à souligner qu'un effet secondaire de la limitation aux dépendances de construction binaires sera qu'il est ~ impossible d'avoir une dépendance C dans vos deps de construction dans de nombreux cas. Oui, nous avons des roues binaires sur Windows, macOS et certaines versions de Linux, mais nous n'en avons pas sur :

  • Tout Linux qui n'utilise pas la glibc (Alpine Linux à l'intérieur de Docker étant populaire).
  • Tout système d'exploitation *nix qui n'est pas un Linux, comme FreeBSD, etc.

Cela signifierait que tout projet basé sur CFFI, par exemple, ne pourrait pas utiliser PEP 518 ou serait désinstallable sur ces plates-formes.

Cela a peut-être déjà été évoqué ! Je lirai ce fil plus tard.

@dstufft C'est exact. Mais ce que nous proposons, c'est que l'utilisation du cache pip est une option. Ainsi, vous pouvez d'abord pip wheel ou pip install vos dépendances de construction, puis elles seront stockées dans le cache.

Cela a peut-être déjà été évoqué !

Non. :)

Cela signifierait que tout projet basé sur CFFI, par exemple, ne pourrait pas utiliser PEP 518 ou serait désinstallable sur ces plates-formes.

En effet. :-(

Le moyen de contourner cela dans ma tête serait que nous pourrions faire en sorte que le comportement PEP 518 soit opt-in - s'il y a un fichier pyproject.toml , nous utilisons l'environnement isolation + build sinon nous revenons au comportement actuel d'utilisation de setup.py .

Je lirai ce fil plus tard.

Je vous en prie. :)

J'ai eu exactement le même commentaire que Donald; ma compréhension de ce fil est que le binaire uniquement est temporaire car il n'y a pas de temps pour l'implémenter pour pip 10. Correct?

S'il a été proposé comme décision permanente à la place, alors -1 bien sûr.

J'ai eu exactement le même commentaire que Donald; ma compréhension de ce fil est que le binaire uniquement est temporaire car il n'y a pas de temps pour l'implémenter pour pip 10. Correct?

C'est correct. pip devrait prendre en charge les dépendances à la source, mais nous manquons de main-d'œuvre.

Le moyen de contourner cela dans ma tête serait que nous pourrions faire en sorte que le comportement PEP 518 soit opt-in - s'il y a un fichier pyproject.toml, nous utilisons l'environnement isolation + build sinon nous revenons au comportement actuel d'utilisation de setup.py.

J'ai relu ce commentaire et je vais être en désaccord ici. La prise en charge de la PEP 518 ne devrait pas être facultative (pour des raisons de mise en œuvre liées à la PEP 517) à mon humble avis, mais les projets ne devraient pas devenir désinstallables sur ces plates-formes.

Plus précisément, le projet particulier que vous installez ne doit pas déterminer si vous obtenez PEP 518. Cela doit être déterminé par le fait que vos dépendances de construction sont disponibles sous forme de roues ou dans le cache. De plus, nous pouvons également rendre la prise en charge de PEP 518 obligatoire pour ces plates-formes si nous crachons simplement un message comme celui-ci :

Error: build dependency X is not in the pip cache. Run "pip install X" before installing Y.

Résumant mon propre point de vue :

  1. Je considère le "Aucun support de construction implicite pour les dépendances de construction" comme une limitation temporaire dans pip 10 pour rendre certaines classes de problèmes (par exemple, les boucles de dépendance de construction) impossibles à rencontrer dans la première itération publiée de la fonctionnalité. Les futures itérations de la prise en charge du backend de build enfichable peuvent autoriser les builds source implicites pour les dépendances de build, tout en mettant en place des mesures appropriées pour éviter les nouveaux problèmes qui surviennent une fois que vous l'autorisez.
  2. L'émission de la commande python -m pip wheel X Y Z pertinente dans un message d'erreur sans exécuter implicitement la construction est une solution de contournement adéquate pour l'instant, car elle garantit que pip ne peut pas bombarder par inadvertance une machine.
  3. Les constructions isolées ne devraient probablement pas encore être la valeur par défaut, à moins que la roue spécifique en cours de construction ait un fichier pyproject.toml , ou que les constructions isolées soient explicitement demandées à partir de la ligne de commande. Il s'agit d'un problème de rétrocompatibilité, car les projets existants vont attendre le comportement non isolé. Une fois que des builds isolés ont été disponibles pour une version ou deux, et que tous les problèmes d'utilisation avec eux ont été résolus, ils peuvent alors devenir la valeur par défaut en général (peut-être avec une option de ligne de commande pour spécifier un environnement de build particulier à utiliser plutôt que de générer implicitement des builds isolés ceux)

@ncoghlan Juste pour vous donner un avertissement: pas d'isolation de construction par défaut signifie pas de PEP 517 (du moins avec mon approche) car seule la dernière version de setuptools le prend en charge (nous devons installer un setuptools plus récent indépendamment de ce qui est sur la personne l'ordinateur). En pratique, je pense que cela pourrait retarder la PEP 517 d'au moins un an car cela augmentera considérablement la quantité d'efforts nécessaires pour la mettre en œuvre (nécessitant le code PEP 517 et non PEP 517).

Il s'agit d'un problème de rétrocompatibilité, car les projets existants vont attendre le comportement non isolé.

La plupart des gens ont des scripts CI qui exécutent pip install X puis exécutent pip install Y . Ces projets devraient ajouter un pypproject.toml . Mais l'ajout d'un pyproject.toml n'est pas si compliqué, et nous pouvons ajouter un indicateur de ligne de commande pour désactiver l'isolation de construction si nécessaire.

Nous devrions au moins cracher un avertissement si un projet n'a pas pyproject.toml dans le pip 10 (qui semble ne pas avoir le support PEP 517 de toute façon).

@xoviat "Ce ne serait pas si difficile à ajuster" n'est pas la façon dont fonctionne la rétrocompatibilité. Si c'était le cas, pip serait désormais passé à --user comme modèle d'installation non-venv par défaut :)

En ce qui concerne PEP 517, vous ne pouvez pas dépendre de PEP 517 en tant qu'éditeur de packages sans ajouter un fichier pyproject.toml , donc c'est bien si setup.py - seuls les projets ne bénéficient pas du support PEP 517 par défaut.

Seriez-vous d'accord pour cracher un avertissement ?

Je verrais cela comme un problème si une version qui fonctionne actuellement correctement commençait à cracher un avertissement simplement parce que pip a été mis à jour, même si ni le projet lui-même ni aucune de ses dépendances n'avaient changé.

Les PEP 518 et 517 ont été délibérément conçues pour ne causer aucune perturbation aux projets existants où tous les éditeurs impliqués ont continué à s'appuyer uniquement sur les outils de configuration.

Il est logique que pip vise à consolider vers un seul chemin de construction PEP 518 même pour les projets basés sur les outils de configuration, mais le temps pour cela est après que les versions isolées ont vu une ou deux versions d'utilisation pratique, pas dans la première version qui les prend en charge du tout.

J'ai eu exactement le même commentaire que Donald; ma compréhension de ce fil est que le binaire uniquement est temporaire car il n'y a pas de temps pour l'implémenter pour pip 10. Correct?

Ouais. Exactement.


Il est logique que pip vise à se consolider vers un seul chemin de construction PEP 518, même pour les projets basés sur des outils de configuration, mais le temps pour cela est après que les versions isolées ont vu une ou deux versions d'utilisation pratique, pas dans la première version qui les soutient du tout.

+1

Je pense que nous devrions viser à supprimer l'ancien chemin d'accès, comme 2 versions majeures. Lorsque pip atterrit, le support complet et approprié de PEP 518 ; nous devrions déprécier l'ancienne logique de construction et la supprimer conformément à la politique de dépréciation standard.

Je suis d'accord avec le résumé de Nick et...

car cela augmentera considérablement la quantité d'efforts requis pour le mettre en œuvre

Non. Je ne pense pas que la mise en œuvre de la PEP 518 de cette manière ait des obstacles majeurs ; J'ai fait un bref commentaire sur https://github.com/pypa/pip/pull/4799#issuecomment -339219397 sur la façon dont cela pourrait être implémenté dans pip.


Ce que nous voulons faire, c'est offrir aux gens une transition propre de l'ancien au nouveau. Ainsi, nous devons conserver la logique d'installation actuelle de pip 9 inchangée - qui prendrait essentiellement en charge tout ce que nous faisons actuellement de la manière exacte dont nous le faisons.

Mettre un fichier pyproject.toml dans l'archive signifierait que le paquet opte pour la nouvelle norme et est prêt à tester la prise en charge du nouveau comportement - en passant par l'environnement de construction avec isolation et construction binaire uniquement -dépendances (pour l'instant).

Non. Je ne pense pas que la mise en œuvre de la PEP 518 de cette manière ait des obstacles majeurs ;

Discuter de la PEP 517 ici. Désolé pour la confusion.

Nous aurions à exécuter les tests deux fois pour vérifier les deux chemins de code. Ah ben la PEP 517 est probablement reportée.

OMI,

  1. Un avertissement si un projet n'a pas pyproject.toml semble être une très mauvaise idée. Après tout, 99 % des projets sur PyPI n'ont actuellement pas pyproject.toml , et nous ne pouvons pas spammer les utilisateurs finaux avec des avertissements contre lesquels ils ne peuvent rien faire (à part signaler le problème au(x) projet(s ). Est-ce que j'ai raté quelque chose ?
  2. Je ne crois pas que l'isolation de construction ait été mentionnée du tout dans la PEP 518. C'est une fonctionnalité supplémentaire que pip souhaite inclure depuis un certain temps maintenant, mais elle n'est pas liée à la prise en charge de la PEP 518, sauf par le fait fortuit que le même PR mis en œuvre les deux (AFAIR). Donc, si l'isolation de la construction est ce qui nous pose des problèmes ici, je suis d'accord pour n'avoir que PEP 518 au départ et ajouter l'isolation en tant que phase 2. Je laisserai cependant cette décision aux personnes qui implémentent les choses.

Est-ce que je manque quelque chose?

Non.

Je suis d'accord pour n'avoir que PEP 518 au départ et ajouter l'isolation en tant que phase 2.

Je pense que nous devrions faire PEP 518 et construire l'isolation ensemble, car c'est une bonne façon de faire passer les gens aux constructions isolées.

Bien que ni PEP 518 ni PEP 517 ne nécessitent des versions isolées, PEP 517 les recommande pour des raisons valables : https://www.python.org/dev/peps/pep-0517/#recommendations -for-build-frontends-non-normative

Sans cache d'artefact binaire local, les environnements de construction isolés ne sont pas pratiques, mais une fois que vous en avez un (comme pip le fait maintenant), ils sont beaucoup plus faisables, car :

  1. Sur la plupart des installations, vous n'aurez même pas besoin de créer une version source en premier lieu
  2. Lorsque vous avez besoin de créer une version source, vous configurez généralement l'environnement de génération à partir du cache.

Dans le même temps, les environnements de construction isolés nécessitent un peu plus de travail de la part des éditeurs, car ils signifient que les métadonnées boguées casseront les propres constructions de l'éditeur d'une manière qui les obligera à dire explicitement "Mes dépendances de construction ne sont pas entièrement déclarées" afin de faire une construction.

Donc, avoir des builds basés pyproject.toml isolés dès le départ fournit un point de commutation naturel, puisque tout ce PEP consiste à fournir un moyen de déclarer clairement et de manière cohérente les dépendances de build séparément des dépendances d'exécution. Cela signifie que les gens qui passent de setup.py font probablement parce qu'ils se soucient de faire ce genre de chose, tandis que les gens qui viennent pour de nouveaux projets le traiteront simplement comme un autre cerceau que l'outillage d'emballage les oblige à sauter par.

Donc, juste quelques choses que je veux confirmer avant de commencer à écrire du code :

  • Le support PEP 517 n'est pas un bloqueur pour pip 10
  • PEP 518 en pip 10

    • opt-in via pyproject.toml

    • ne prend en charge que les dépendances de construction uniquement binaires

    • constructions isolées

Le PEP 517 ne peut pas être un bloqueur pour le pip 10 car il n'est pas encore prêt et il n'y a pas de chemin clair à ce stade (il y a un chemin à suivre mais ce n'est pas clair).

J'ai un commentaire et une question en réponse au commentaire de @xoviat ici résumant les défis de mise en œuvre ainsi qu'après avoir lu rapidement ce fil.

Premièrement, en ce qui concerne le problème de la récursivité des choses pouvant exploser, en général, toute fonction récursive peut être "traduite" en une fonction itérative. Je me demande si cette approche pourrait aider ici en offrant plus de contrôle.

Deuxièmement, qu'est-ce que le déboursement achète par opposition à l'appel d'une fonction pip depuis Python ? Y a-t-il une raison pour laquelle une fonction API interne n'a pas pu être créée/refactorisée qui ferait tout ce que le bombardement essaie d'accomplir ? Cela devrait offrir plus de flexibilité lors de l'appel de l'appel (par rapport aux paramètres CLI). Cela pourrait également fournir plus de contrôle en permettant de gérer plus facilement l'état du processus global.

Y a-t-il une raison pour laquelle une fonction API interne n'a pas pu être créée/refactorisée qui ferait tout ce que le bombardement essaie d'accomplir ?

Deuxièmement, qu'est-ce que le déboursement achète par opposition à l'appel d'une fonction pip depuis Python ?

Cela fait gagner du temps que nous n'avons pas actuellement. pip est déjà en retard sur son calendrier de sortie.

Premièrement, en ce qui concerne le problème de la récursivité des choses pouvant exploser, en général, toute fonction récursive peut être "traduite" en une fonction itérative.

Je ne suis pas anti récursif. Je suis anti-processus récursif. Je pense que c'est bien si vous voulez utiliser 100% CPU (enfin, ce serait 20% en Python), mais finalement l'utilisateur doit pouvoir ouvrir le gestionnaire de tâches et tuer le maximum de 15 processus qui s'y trouvent. Pour moi, une situation qui pourrait potentiellement provoquer une explosion de processus est inacceptable.

Cela ne répond cependant pas à la question de savoir pourquoi cela fait gagner du temps. Qu'est-ce qui rend difficile la création d'une fonction API interne qui fait la même chose ?

Dans tous les cas, si le bombardement résout un problème particulier, une possibilité de faciliter cette approche pourrait être d'exposer temporairement une commande CLI privée/interne qui facilite la transmission de toutes les informations nécessaires (par exemple, il pourrait même s'agir d'un objet Python sérialisé , etc).

Cela ne répond cependant pas à la question de savoir pourquoi cela fait gagner du temps. Qu'est-ce qui rend difficile la création d'une fonction API interne qui fait la même chose ?

Si vous pensez que c'est facile, alors allez-y. Je ne dis pas cela de manière sarcastique : s'il vous plaît, allez-y, car cela résoudra tous les problèmes.

Je ne pense pas que ce soit facile. Je pose la question pour comprendre pourquoi c'est difficile. (Je suppose que vous y avez pensé puisque vous avez dit que cela ferait gagner du temps.)

Vous avez généralement besoin d'installations de pip distinctes à exécuter à l'intérieur d'un sous-processus, à cause des caches dans des endroits comme pkg_resources je crois (bien que je puisse me tromper là-bas).

Cela ne signifie pas que vous devez appeler pip , vous pouvez créer une API qui sérialise les données via la CLI et appeler python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" et lire plus de données hors stdout. Il serait possible de transformer la solution récursive des pips appelant pips appelant pips appelant pips en la transformant en une pile en utilisant une telle API (puisque toute récursivité peut également être décrite comme une pile), vous feriez essentiellement une API privée qui est appelé en tant que processus.

Je prévois toujours de lire ce fil (j'ai eu un tas d'assiettes qui tournaient ces derniers temps !), Mais une chose au-dessus : nous n'avons pas vraiment de calendrier de publication, nous publions quand il est prêt et non à une date cible. Nous avons parfois une idée générale du moment où nous aimerions sortir, mais ce n'est jamais gravé dans le marbre.

En fin de compte, Python a une profondeur de récursivité maximale pour s'assurer que les choses ne deviennent pas incontrôlables. Nous aurions besoin de mettre cela en œuvre si nous options pour cette approche.

Oui, une approche basée sur la pile rend assez efficace pour aller assez loin (beaucoup plus profond que tout ce qu'une boucle de dépendance ne ferait jamais, par exemple, nous pourrions avoir quelque chose qui dépend littéralement de chaque paquet et toujours bien), la chose principale faire est de détecter les boucles.

Une façon assez naïve et facile de faire la détection de boucle est de simplement mettre une limite supérieure au nombre d'éléments sur la pile et de dire que si vous atteignez cette limite, vous devez sûrement être dans une situation de boucle et sortir de l'erreur. Les inconvénients avec cela sont bien sûr que les boucles ne sont pas détectées le plus tôt possible, et les packages avec des chaînes de dépendance de construction plus profondes que la limite ne fonctionnent tout simplement pas.

L'option généralement meilleure (puisque si vous utilisez une approche basée sur la pile, vous pouvez accéder à l'ensemble de la pile) consiste simplement à traverser la pile et à voir si l'élément que nous tentons d'installer est déjà sur la pile n'importe où, et s'il est éclater et erreur parce que nous avons atteint une boucle (cette erreur peut soit être présentée à l'utilisateur final, soit remonter jusqu'au résolveur pour éventuellement essayer une version différente - bien que cela la rende beaucoup plus lente).

Et pour répondre directement à la question de @cjerdonek : en principe, ce n'est pas difficile, ce qui complique les choses, ce sont certaines hypothèses architecturales intégrées dans le fonctionnement actuel pip qui ne sont plus vraies dans un monde où chaque source est construite obtient son propre environnement de construction isolé, plutôt que de simplement s'exécuter directement dans l'environnement d'installation.

Cela signifie que le moyen le plus simple de réutiliser la logique de gestion des dépendances existante pip sans trébucher sur ces limitations architecturales internes et sans risquer de casser le code en cours de fonctionnement consiste à exécuter une autre instance de pip dans un sous-processus. C'est généralement bien, sauf pour la conséquence que le fait de ne pas détecter et de sortir des boucles de dépendance peut provoquer une bifurcation du système exécutant la construction.

J'aime l'idée de @dstufft de convertir en une approche itérative / basée sur la pile et de passer à une fonction pip interne en utilisant le modèle python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" . Cela semble plus simple sur la base de la discussion, ainsi que robuste.

Je pense que la première étape vers cela serait de réduire l'approche récursive simple à une seule fonction Python récursive avec l'entrée et la sortie attendues (au moins en l'esquissant), puis cela pourrait être traduit/converti en approche itérative. Et oui, vous pouvez conserver un set d'appels visités pour éviter les boucles, ce qui semble être l'un des aspects les plus faciles à résoudre.

J'ai examiné / réfléchi un peu plus à la conversion de l'approche récursive en une approche itérative. Le travail partiel de @xoviat sur la PEP 518 (PR #4799) m'a aidé à trouver le point de récursivité (que certains d'entre vous connaissent probablement déjà). C'est à son commentaire de code:

# TODO: Use single process with recursion handling

où il invoque ensuite pip install ... .

Mon idée est qu'il semble que cela pourrait peut-être être résolu par une variante de pip install (pour les dépendances de construction) avec quelque chose comme le changement suivant :

  • Si l'installation ne nécessite aucune sous-installation, procédez à l'installation.
  • Sinon, revenez avec une liste (éventuellement partielle) des sous-installations requises (par exemple en écrivant les informations dans un fichier convenu si l'écriture sur stdout ne fonctionne pas déjà).

De cette manière, le processus racine de niveau supérieur peut progressivement générer une arborescence des dépendances de construction. Et il peut traiter les feuilles au fur et à mesure qu'elles se trouvent. Au fur et à mesure que les feuilles sont traitées, les nœuds qui n'étaient auparavant pas des feuilles deviendront des feuilles, et ainsi de suite. Avec cette implémentation, à tout moment, il n'y aura au plus qu'une seule installation pip dans un sous-processus.

Une légère variation par rapport à ce que j'ai suggéré ci-dessus est que la commande pip / appel de sous-processus nécessaire peut renvoyer / émettre une liste des invocations de sous-installation qu'une installation candidate nécessiterait (un pip get-subinstalls ou simplement pip subinstalls commander). La seule différence avec ce que j'ai suggéré ci-dessus est que cette commande se limiterait à rapporter des informations. Il ne ferait pas réellement l'installation. Donc, sa mise en œuvre pourrait être plus simple / plus facile à tester.

@cjerdonek Je ne vois aucun problème avec cette idée. Mais finalement quelqu'un doit l'implémenter (je pense que @pradyunsg allait travailler sur quelque chose ce week-end ?) et comme toujours plus de difficultés peuvent être découvertes alors.

Quelque chose est arrivé. Si quelqu'un d'autre veut le récupérer, je n'ai pas
problèmes. :)

J'aime aussi l'idée de @dstufft .

Le dimanche 29 octobre 2017, 08h47, xoviat, [email protected] a écrit :

@cjerdonek https://github.com/cjerdonek Je ne vois aucun problème avec
cette idée. Mais en fin de compte, quelqu'un doit le mettre en œuvre (je pense
@pradyunsg https://github.com/pradyunsg allait travailler sur quelque chose
ce week-end?) et comme toujours plus de difficultés peuvent être découvertes alors.


Vous recevez ceci parce que vous avez été mentionné.

Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-340234567 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/ADH7SYImpWgJGg-DzQRcO_9hHfE6ZxEAks5sw-5RgaJpZM4QBdSg
.

Pour en revenir à cela, voulons-nous aller de l'avant avec l'approche pile + invocation interne suggérée par @dstufft ?

/ping @ncoghlan @pfmoore @xavfernandez

Oui s'il vous plaît. N'importe quoi pour faire avancer ça.

Y a-t-il quelqu'un qui peut résumer où nous en sommes avec PEP 517 et PEP 518 par rapport à une version pip 10 ? Spécifiquement:

  1. Le maître est-il actuellement dans un état libérable ? Aux dernières nouvelles, la prise en charge de PEP 518 était interrompue (il y a au moins un problème de blocage de version ouvert lié à PEP 518 - # 4647).
  2. Sommes-nous susceptibles d'avoir une implémentation PEP 517 et/ou PEP 518 fonctionnelle dans un délai qui rende raisonnable de retarder le pip 10 jusqu'à ce qu'ils soient disponibles ?
  3. En supposant que nous corrigions les choses dans (1), voulons-nous faire une version pip 10 sans PEP 517/518 ? Nous avons produit un e-mail d'avertissement à propos de la sortie, afin que les gens sachent qu'elle arrive. Et il y a des correctifs raisonnablement importants (par exemple, des correctifs d'encodage pour Windows) qu'il serait bon de publier.

Mon sentiment est que nous attendons les bloqueurs de publication, mais nous ne sommes pas assez proches du support PEP 517/518 pour bloquer le pip 10 sur eux. Mais je ne pense pas que quiconque travaille sur # 4647, sauf dans le cadre de la mise en œuvre de la PEP 518.

Une autre option serait de documenter les limites de la prise en charge actuelle de PEP 518 et de rétrograder # 4647 d'être un bloqueur de version. Je n'en sais pas assez sur les cas d'utilisation pour savoir si c'est viable.

Je viens juste de voir cette discussion - excuses pour la mise en œuvre initiale à moitié cuite qui est susceptible d'agir comme une bombe à fourche, et merci à tous ceux d'entre vous qui ont pris le temps de la comprendre et de proposer de meilleures idées.

FWIW, je pense que le limiter à l'installation de roues pour les exigences de construction serait un compromis acceptable pour la première version.

Cela me rappelle également que je devrais probablement régler les problèmes afin que le flit ne soit pas une exigence de construction en soi.

excuses pour la mise en œuvre initiale à moitié cuite qui est susceptible d'agir comme une bombe à fourche,

Aucune excuse nécessaire. Comme je l'ai dit, vous ne pouvez pas prévoir ces problèmes du premier coup. Même en sachant ce que nous savons maintenant, retarder le PR aurait simplement reporté ces discussions.

Le maître est-il actuellement dans un état libérable ?

IIUC, il peut fork-bomb un système dès maintenant ; Est-ce exact? Si oui, je pense que non.

Sommes-nous susceptibles d'avoir une implémentation PEP 517 et/ou PEP 518 fonctionnelle dans un délai qui rende raisonnable de retarder le pip 10 jusqu'à ce qu'ils soient disponibles ?

Je pense que la solution facile (à court terme) serait de se limiter aux roues pour les dépendances de construction. J'essaierai de m'y mettre la semaine prochaine. Si cela ne se matérialise pas, tout ira bien si nous supprimons le support PEP 518 actuel du maître et en supprimons un 10.0.0.

Je ne pense pas que quiconque travaille sur # 4647, sauf dans le cadre de la mise en œuvre de PEP 518.

Je pense que vous voulez dire, implémentation complète de PEP 518 avec les dépendances de construction source autorisées ?

Oh, et à propos de # 4647 - la description de @xoviat ci-dessus indique que la correction nécessiterait de changer/déplacer le code et la propriété/visibilité des objets (en particulier BuildEnvironment ), ce qui n'est pas trivial.

Je pense que le limiter aux roues devrait être aussi simple que de changer cette ligne :

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

à:

finder.format_control = FormatControl(set(), set([':all:']))

Le deuxième champ contient un ensemble de packages à rechercher uniquement en tant que fichiers binaires, avec un cas particulier pour ':all:' pour désigner tous les packages.

Oui. Mais cela seul ne résoudrait pas le # 4647. De plus, aucun de ces codes ne va
via un résolveur.

Le samedi 2 décembre 2017 à 01h23, Thomas Kluyver [email protected] a écrit :

Je pense que le limiter aux roues devrait être aussi simple que de changer cela
ligne:

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

à:

finder.format_control = FormatControl(set(), set([':all:']))

Le deuxième champ contient un ensemble de packages à rechercher uniquement en tant que binaires, avec
un cas particulier pour ':all:' pour désigner tous les packages.


Vous recevez ceci parce que vous avez été mentionné.

Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348598368 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/ADH7SUi0QMS3rr5Iba90XWZmFweGmqeBks5s8FlEgaJpZM4QBdSg
.

C'est vrai, il y a un tas d'autres choses qui ne vont pas. Mais cela devrait l'empêcher de bombarder à la fourchette, ce qui, à mon avis, est la préoccupation la plus urgente.

Si quelqu'un veut reprendre mon PR d'origine ("réparer les problèmes PEP 518"),
il ne devrait pas être trop difficile de le modifier pour que l'isolation de construction ne soit pas
activé sans pyproject.toml. La raison originale pour laquelle il n'a pas été fusionné
était qu'il a abandonné le support pour l'installation de dépendances à partir de la source avec
PEP 518. Cependant, maintenant que les gens commencent à se rendre compte que PEP 518 peut
pas du tout dans le pip 10, ils peuvent être plus disposés à accepter ce PR. je
personnellement, je n'ai pas le temps de le défendre, mais cela ne devrait pas empêcher les autres
de le faire avancer, car seules quelques lignes de changements seront nécessaires
(en plus d'avoir échoué au test PEP 518).

En fait, contre mon meilleur jugement, je suis prêt à implémenter les PEP 517 et 518 sous peu si les développeurs pip acceptent mes conditions :

  1. Les dépendances ne seront initialement que des roues
  2. pip aura initialement un backend de construction interne, même s'il sera finalement supprimé

Je n'ai aucun problème avec 1; Je n'ai aucune préférence pour le 2.

Le dimanche 3 décembre 2017 à 02h36, xoviat [email protected] a écrit :

En fait, contre mon meilleur jugement, je suis prêt à mettre en œuvre les deux PEP
517 et 518 sous peu si les développeurs pip sont d'accord avec mes conditions :

  1. Les dépendances ne seront initialement que des roues
  2. pip aura initialement un backend de construction interne, même s'il
    sera finalement supprimé


Vous recevez ceci parce que vous avez été mentionné.

Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348720096 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/ADH7ST6riptZkYMap5Z5SstRf-VmE7eAks5s8bu5gaJpZM4QBdSg
.

Pour info les conditions ne sont pas arbitraires mais sont là pour rendre possible la mise en place initiale. Est-ce que @pfmoore est d'accord avec ça ?

Je ne suis pas particulièrement à l'aise avec le ton de l'offre "contre mon meilleur jugement... d'accord avec mes conditions". Je ne vais pas m'opposer si les autres développeurs de pip acceptent cette offre, mais personnellement, je n'ai pas le temps pour le moment de relancer tout le débat sur les détails de l'implémentation. En gros, je vais m'en remettre à @dstufft et @xavfernandez à ce sujet ( @pradyunsg a déjà donné son avis).

Le ton de l'offre est tel qu'il est parce que les méthodes de mise en œuvre ont été fermées en raison de désaccords fondamentaux sur ce à quoi ressemblerait une mise en œuvre initiale. Je préfère m'entendre sur les principes maintenant plutôt que de me lancer dans un autre débat sur la mise en œuvre.

Je précise juste que je ne suis pas non plus super à l'aise avec le ton, c'est
juste, je n'ai ni le temps ni l'énergie d'expliquer pourquoi ce ton a été utilisé
etc. Même raison pour la réponse laconique de ma part.

Peut-être vaut-il également la peine de le dire, je suis cool avec les dépendances de construction binaires uniquement dans
la première mise en œuvre, pas à plus long terme. Cela ne s'applique pas à
dépendances d'exécution (puisque cela est également apparu d'une manière ou d'une autre dans un autre
discussion).

Le dimanche 3 décembre 2017, 23h37, xoviat, [email protected] a écrit :

Le ton de l'offre est tel qu'il est parce que les méthodes de
la mise en œuvre ont été interrompues en raison de désaccords fondamentaux sur ce que
une mise en œuvre initiale ressemblerait. Je serais plutôt d'accord sur le
principes maintenant que de se transformer en un autre débat sur la mise en œuvre.


Vous recevez ceci parce que vous avez été mentionné.

Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348802032 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/ADH7ScUh-BveonoTxZ5FkkeSynFvoLb8ks5s8uNRgaJpZM4QBdSg
.

Honnêtement, ce n'est probablement pas une utilisation efficace du temps de quiconque pour discuter davantage du ton de la publication, car il n'est pas pertinent d'inclure ces fonctionnalités dans pip 10. Cependant, j'ai besoin d'une assurance que mes conditions sont acceptables pour fusionner soit @pfmoore ( qui a indiqué qu'il ne peut pas faire une telle assurance, ce qui est acceptable étant donné que personne n'est payé pour son temps ici), @dstufft , ou @xavfernandez.

Encore une fois, les conditions ne sont pas mon opinion personnelle, mais sont axées sur la mise en œuvre. Si j'assouplis ces conditions, alors je ne peux pas promettre une implémentation, donc ça ne sert à rien de passer du temps à préparer un PR, et puis les gens lisent le diff et demandent "oh, pourquoi cette ligne est-elle ici?" puis "oh, donc ce n'est pas fusionnable ?" parce qu'il y avait un malentendu sur le but exact du PR.

D'accord sur le ton. Mon point est simplement que je ne fusionnerai pas le changement [1], donc mon point de vue n'est pas vraiment important ici.

[1] Évidemment, je dis cela sans avoir vu l'implémentation, donc j'espère qu'il est clair que mes raisons ne sont pas liées à des préoccupations concernant la qualité du code - il s'agit de ne pas avoir le temps de s'assurer que je comprends suffisamment bien le code pour être prêt à fusionner, essentiellement.

@xoviat Quels sont vos plans de mise en œuvre en ce qui concerne l'approche itérative ou récursive dont nous avons discuté ci-dessus ?

De plus, pour clarifier, dites-vous que vous effectuerez d'abord une mise en œuvre partielle des PEP 517 et 518 qui peuvent être fusionnées, suivie d'une mise en œuvre complète qui peut être fusionnée ? Ou dites-vous que vous ne ferez que la mise en œuvre partielle, ou dites-vous que vous ferez une mise en œuvre complète en passant par des étapes antérieures qui ne seront pas nécessairement fusionnables ? (J'essaie en partie de mieux comprendre ce que vous entendez par "initialement" et "éventuellement" dans votre commentaire .)

La première condition élimine tout le problème de la récursivité.

De plus, pour clarifier, dites-vous que vous effectuerez d'abord une mise en œuvre partielle des PEP 517 et 518 qui peuvent être fusionnées, suivie d'une mise en œuvre complète qui peut être fusionnée ?

Ce que je dis, c'est que je vais terminer une implémentation partielle qui fonctionnera pour 95 % des cas d'utilisation ; en particulier dans le cas où les dépendances ont des roues (très courantes maintenant) et que vous êtes sur une plate-forme manylinux/windows/OSX (grande majorité des utilisateurs).

Ce n'est pas une implémentation complète. Mais la façon dont vous obtenez des PR non fusionnables est d'essayer de faire l'approche "tout ou rien" où vous vous conformez à la norme ou vous ne la respectez pas.

Gardez à l'esprit qu'une implémentation complète nécessitera de trier certains problèmes assez désagréables qui nécessiteront chacun un PR séparé (car avoir un PR avec plus de 100 commentaires signifie généralement que le code n'est pas bien revu). [1]

[1] https://github.com/btc1/bitcoin/pull/11#issuecomment -313843216

Je vais fermer ce problème maintenant - nous avons un support préliminaire pour PEP 518 dans pip 10 qui ne supporte que les roues en tant que dépendances de construction. J'ouvrirai un nouveau sujet pour discuter du support complet et un autre pour le support PEP 517 (citant ici comme pertinent).

Merci @ncoghlan @rgommers @cjerdonek pour vos idées et votre aide ici. Merci @takluyver pour la mise en œuvre initiale de la PEP 518. Merci @xoviat (qui est @ghost maintenant) pour toute l'aide apportée à la mise en œuvre de ces changements. Merci @benoit-pierre pour votre aide à l'amélioration du support actuel.

PS : 100ème commentaire ! :tada:

Ce fil a été automatiquement verrouillé puisqu'il n'y a eu aucune activité récente après sa fermeture. Veuillez ouvrir un nouveau problème pour les bogues associés.

Cette page vous a été utile?
0 / 5 - 0 notes