<p>pip l'installation d'un répertoire est super lente</p>

Créé le 16 déc. 2014  ·  74Commentaires  ·  Source: pypa/pip

Voir https://github.com/pypa/pip/issues/2195#issuecomment -524606986, pour un résumé de ce problème.


Je me demande pourquoi pip a besoin de 17 secondes pour traiter un répertoire local qui n'est pas sur NFS (en fait, c'est sur un lecteur SSD) pour pip, qui n'a pas de dépendances, puisque tout est vendu.

$ time pip install --no-install ~/dev/git-repos/pip
DEPRECATION: --no-install and --no-download are deprecated. See https://github.com/pypa/pip/issues/906.
Processing /Users/marca/dev/git-repos/pip
  Requirement already satisfied (use --upgrade to upgrade): pip==6.0.dev1 from file:///Users/marca/dev/git-repos/pip in /Users/marca/dev/git-repos/pip
pip install --no-install ~/dev/git-repos/pip  2.80s user 5.86s system 50% cpu 17.205 total

Il devrait probablement au moins enregistrer tout ce qui prend autant de temps, mais peut-être qu'il ne devrait même pas faire ce qu'il fait.

Notez que la ligne "Traitement" apparaît tout de suite et à peu près tout le délai semble être entre cette ligne et la suivante.

needs discussion enhancement

Commentaire le plus utile

La mise en œuvre du PEP 517 résoudra ce problème.

Narrateur : non.

Tous les 74 commentaires

Il fait une copie de l'intégralité du répertoire, y compris .git . Ça ne devrait probablement pas faire ça, non.

$ du -sh pip
263M    pip
$ du -sk * .cache .git .tox .travis | sort -nr | head -n 5
181860  .tox
34836   tests
31700   .git
9212    pip
2852    build

J'ai essayé de passer 3 -v ( time pip install -vvv --no-install ~/dev/git-repos/pip ) -- cela n'a donné plus d'informations.

En parcourant avec pdb, les choses ralentissent lorsque j'arrive à :

> /Users/marca/dev/git-repos/pip/pip/req/req_set.py(365)prepare_files()
-> unpack_url(

Et oui ,

> /Users/marca/dev/git-repos/pip/pip/download.py(635)unpack_file_url()
-> shutil.copytree(link_path, location, symlinks=True)
$ time pip install --no-install ~/dev/git-repos/pip
DEPRECATION: --no-install and --no-download are deprecated. See https://github.com/pypa/pip/issues/906.
Processing /Users/marca/dev/git-repos/pip
  2014-12-15 15:23:34.630794: Copying tree; link_path = '/Users/marca/dev/git-repos/pip'; location = '/var/folders/gw/w0clrs515zx9x_55zgtpv4mm0000gp/T/pip-D6etc4-build'
  2014-12-15 15:23:57.418679: DONE copying tree; link_path = '/Users/marca/dev/git-repos/pip'; location = '/var/folders/gw/w0clrs515zx9x_55zgtpv4mm0000gp/T/pip-D6etc4-build'
  Requirement already satisfied (use --upgrade to upgrade): pip==6.0.dev1 from file:///Users/marca/dev/git-repos/pip in /Users/marca/dev/git-repos/pip
pip install --no-install ~/dev/git-repos/pip  2.75s user 5.03s system 32% cpu 24.168 total
>>> elapsed time 24s

Quelques discussions sur https://github.com/pypa/pip/issues/2196

C'est beaucoup plus rapide maintenant que https://github.com/pypa/pip/pull/2196 est fusionné.

Cela devrait être rouvert puisque #2196 a été annulé. J'aimerais proposer un PR alternatif qui crée un sdist au lieu d'utiliser des heuristiques pour déterminer ce qu'il faut copier. Voir les commentaires sur ce PR pour plus de détails.

$ time pip install --no-install ~/dev/git-repos/pip
DEPRECATION: --no-install and --no-download are deprecated. See https://github.com/pypa/pip/issues/906.
Processing /Users/marca/dev/git-repos/pip
  Requirement already satisfied (use --upgrade to upgrade): pip==6.1.0.dev0 from file:///Users/marca/dev/git-repos/pip in /Users/marca/dev/git-repos/pip
pip install --no-install ~/dev/git-repos/pip  3.67s user 8.12s system 7% cpu 2:45.83 total
>>> elapsed time 2m46s

Aïe, presque 3 minutes.

Probablement principalement à cause de ceci :

$ du -sh .tox
177M    .tox

Le répertoire .tox représente 177 millions sur un total de 270 millions pour l'ensemble de mon répertoire pip .

Veuillez consulter https://github.com/pypa/pip/pull/2535 , qui accélère unpack_file_url en créant un sdist et en le décompressant.

Ce problème devrait être rouvert, car le PR fusionné n'a rien fait (voir gh-3219).

Des avancées pour ce problème ?

Non, et il ne semble pas que la solution finale arrivera de si tôt. PEP 516 ou PEP 517 doivent être acceptés avant qu'une décision puisse être prise quant à savoir si générer un sdist premier est correct (personnellement, je ne le pense pas).

Le PEP 516 le résume ainsi :

Being able to create new sdists from existing source trees isn't a thing pip does today,
and while there is a PR to do that as part of building from source, it is contentious and
lacks consensus.

Le plus simple est probablement que quelqu'un soumette un RP plus simple qui corrige le comportement le plus inconscient, comme copier tous les .git et .tox (en supposant que cela se produise encore aujourd'hui). Ce serait une accélération significative dans de nombreux cas et ne prêtera pas à controverse.

D'une manière ou d'une autre, problème similaire, que faire lors de l'installation à partir d'un référentiel nu (au lieu de la distribution source ou devrais-je plutôt dire du package publié) dans npm - exécutez prepublish pour les packages git url

@rgommers Que diriez-vous d'ajouter un fichier .pipignore pour lister les fichiers et répertoires à ignorer comme .gitignore au lieu de coder en dur certains noms de fichiers/répertoires comme .git et .tox ?

Ce n'est pas une bonne idée - cela transfère la responsabilité de gérer cette lenteur au développeur de chaque paquet, ce qui ne fonctionne tout simplement pas.

Si npm l'a, ça doit être bon :) – https://docs.npmjs.com/misc/developers#keeping -files-out-of-your-package

cela casse aussi activement des trucs comme setuptools_scm encore plus ^^ - l'installation de pip faire une copie de dossier casse déjà les choses durement

Qu'est-ce que setuptools_scm a à voir avec ça ? Il doit être exécuté sur un référentiel valide et non sur n'importe quel type de package source .

Ce n'est pas une bonne idée - cela transfère la responsabilité de gérer cette lenteur au développeur de chaque paquet, ce qui ne fonctionne tout simplement pas.

Faites en sorte que .pipignore inclue implicitement .git, .hg, etc. avec un .pipignore vide le supprimant.

@piotr-dobrogost une installation pip à partir d'un référentiel source se brisera dans diverses circonstances où pip ne copie pas suffisamment de contexte - par exemple pypa/setuptools_scm#138

Nous avons déjà fait ignorer les répertoires comme .git et des choses telles et déferlait comme PBR et a dû annuler la modification.

@dstufft ça casse toujours des trucs si on est dans un sous-répertoire d'un dépôt git au lieu de la racine ^^

Hmm, si cette casse était déjà assez grave, il n'y a pas de moyen simple d'améliorer les choses ici. Je suppose qu'il attend alors l'un des PEP de construction.

pbr doit faire quelque chose d'assez déraisonnable s'il tombe sans un .git dir présent, mais bon ....

vous vous demandez s'il y a des progrès à ce sujet? Non seulement les .git ou tout autre dossier .${scm} gênants, mais c'est encore pire si les gens incluent .vagrant/ avec la source.

avoir un .pipignore personnalisable aiderait vraiment à soulager la douleur.

Pour un autre point de données ; nous avons un mélange de Python et Javascript dans certains projets, car nous utilisons Sphinx pour documenter nos projets Javascript. Par conséquent, pip copie également un très gros répertoire node_modules , ce qui peut être extrêmement lent.

Nous voterions donc pour l'option .pipignore car notre cas d'utilisation met en évidence que les valeurs codées en dur ne seront pas nécessairement suffisantes pour tous les types de projets.

Les gens gardent toutes sortes de déchets dans l'arborescence au-delà du fichier SCM.

J'ai quelques grosses simulations (16 Go +) produites par le code que je garde dans le même répertoire avec le code source du package (comme moyen de garder une trace de différents projets).

pip install . copie dans mon /tmp. La partition pauvre manque en fait d'espace et pip échoue avec une erreur d'espace disque.

Si sdist n'est pas censé être utilisé et que .pipignore étend l'interface, qu'en est-il de la réutilisation du code pour analyser le fichier MANIFEST.in / MANIFEST ? Il aurait dû décrire tous les fichiers nécessaires à l'installation.

Une bonne solution de contournement semble utiliser une installation modifiable ( pip install -e $DIR ).

Une bonne solution de contournement semble utiliser une installation modifiable (pip install -e $DIR).

Sauf, pour les tests, cela ne teste pas ce qu'un utilisateur installant le package à partir de pypi utiliserait. (par exemple, les packages et les modules qui ne sont pas emballés seront toujours disponibles)

J'espère que cela a déjà été mentionné dans ce fil.

Une meilleure solution de contournement serait de créer un sdist ou une roue directement à l'aide de setup.py et d'installer l'artefact généré à l'aide de pip. De cette façon, pip ne fera pas la copie de répertoire (car il a un fichier à installer) et c'est exactement le même résultat que vous le feriez avec pip install . (à partir de pip 9), moins le copie du répertoire.

Pour l'amour du ciel, les gars, cela peut-il déjà être résolu d'une manière ou d'une autre, s'il vous plaît ? Je veux dire, il semble y avoir un certain consensus sur le fait que ce comportement est insensé - pourtant le ticket est ouvert depuis trois ans maintenant, et il n'y a aucune solution en vue. Je déteste avoir à déplacer manuellement des données dans et hors de mon arbre juste pour que pip ne vomisse pas ou ne se bloque pas pendant quelques minutes (je dois travailler sur des systèmes de fichiers partagés).

S'il n'y a pas de consensus sur la façon de ne pas casser le travail existant, une solution comme .pipignore peut-elle être fournie en tant qu'opt-in, peut-être ? Cela ne me dérange pas de sauter à travers quelques cerceaux pour résoudre ce problème.

@andre-merzky s'il vous plaît calmez-vous.

Nous sommes conscients du problème, mais nous sommes une organisation bénévole avec des ressources très limitées. Et en termes pratiques, ce problème n'affecte tout simplement pas suffisamment de nos utilisateurs pour figurer en bonne place sur la liste des priorités.

Cela sera corrigé en temps voulu (et le travail le plus important que nous essayons d'aborder en ce moment, en particulier le PEP 517, est susceptible de résoudre ce problème comme effet secondaire), mais crier sur les volontaires n'aidera pas. Si vous pensez qu'un correctif immédiat est essentiel, nous serions heureux d'examiner un PR - mais vous devez savoir que même si vous levez un PR et le faites accepter, il ne sera pas publié avant le PIP 10, et c'est la sortie, nous aimerions obtenir au moins une partie du travail « important » auquel j'ai fait référence ci-dessus (cela peut ne pas se produire à nouveau en raison de contraintes de ressources bénévoles, mais c'est notre objectif). Il peut donc être remplacé avant sa sortie - mais cela ne signifie pas que vous n'êtes pas le bienvenu pour créer un PR, ce sera une solution de repli si les grands projets ne se concrétisent pas à temps.

@pfmoore désolé pour le ton, la frustration parlait... J'ai créé un PR pour un correctif trivial (et donc peut-être inacceptable) (#4900). Je t'ai entendu sur le cycle de sortie, c'est comme ça que les choses se passent, je sais...

J'ai aussi rencontré ça :

(env) $ find node_modules/ | wc -l
140287
(env) $ time pip install .
Processing /path/to/myproject
Installing collected packages: myproject
  Running setup.py install for myproject ... done
Successfully installed myproject-1.0

real    4m35.598s
user    0m6.928s
sys 0m7.992s

Après la réinitialisation :

(env) $ mv node_modules/ ../
(env) $ time pip install .
Processing /path/to/myproject
Installing collected packages: myproject
  Running setup.py install for myproject ... done
Successfully installed myproject-1.0

real    0m0.899s
user    0m0.496s
sys 0m0.120s

Où se trouve le dernier rapport de profilage concernant le problème ?

Aucun changement ici. Aujourd'hui, pip copie toujours l'intégralité du package dans un répertoire de construction temporaire.

Ce répertoire est-il en mémoire ?

Non, c'est écrit sur le disque - ce qui le rend particulièrement pénible sur les systèmes de fichiers partagés...

Est-ce au moins en /tmp ou en /dev/shm ? https://stackoverflow.com/questions/9745281/tmp-vs-dev-shm-for-temp-file-storage-on-linux Peut-il détecter quand tmpfs n'est pas utilisé et proposer d'en créer un ?

C'est en /tmp . Cela dépend de la stdlib tempfile .

La mise en œuvre du PEP 517 résoudra ce problème.

Je rencontre cela avec la dernière version de développeur de pip - je pensais que la prise en charge de PEP 517 avait été ajoutée dans le pip 19, alors cela devrait-il toujours se produire?

Dans mon cas, parce que je travaille sur un projet (astropie) où j'ai de nombreuses télécommandes et branches, mon répertoire .git est de 1,8 Go, et cela prend quelques minutes pour le copier dans un répertoire temporaire. Il semble qu'il serait plus logique de construire d'abord une distribution source, puis de construire la roue à partir de là, dans les coulisses.

Nous souffrons toujours assez gravement à cause de ce problème également. Il est vraiment difficile de dire à nos utilisateurs qu'ils ne peuvent pas conserver le code et les données expérimentales (qui sont volumineuses) dans le même répertoire - c'est assez contre-intuitif. Sur nos propres systèmes, nous utilisons le correctif .pipignore , mais n'avons pas la possibilité de le déployer sur la majorité des systèmes que nous supportons... :/

Nous rencontrons également ce https://github.com/pypa/pip/issues/2195#issuecomment -351258913 aujourd'hui. C'est encore en train d'arriver.

(venv) (venv) pip --version
pip 19.1.1 from /application/venv/lib/python2.7/site-packages/pip (python 2.7)

La mise en œuvre du PEP 517 résoudra ce problème.

Narrateur : non.

La résolution de ce problème nécessite une installation via sdist, et la dernière fois que nous en avons discuté, il y a eu beaucoup de réactions de la part des personnes utilisant des outils qui (apparemment) ont besoin du répertoire source réel. Personnellement, je pense que nous devrions mordre la balle et déprécier les processus de construction qui ne donnent pas les mêmes résultats lorsque vous faites build_sdist puis build_wheel que vous obtenez lorsque vous faites juste build_wheel , mais je n'ai pas le temps ni l'énergie de défendre moi-même cette proposition pour le moment.

La résolution de ce problème nécessite l'installation via sdist

En fait, no - #4900 a fourni une implémentation qui résout le problème avec peu de code d'une manière rétrocompatible. Cela ne résoudra peut-être pas d'autres problèmes - mais étant donné l'âge de ce billet, je voudrais demander de reconsidérer cette approche.

La résolution de ce problème nécessite une installation via sdist, et la dernière fois que nous en avons discuté, il y a eu beaucoup de réactions de la part des personnes utilisant des outils qui (apparemment) ont besoin du répertoire source réel. Personnellement, je pense que nous devrions mordre la balle et déprécier les processus de construction qui ne donnent pas les mêmes résultats lorsque vous faites build_sdist puis build_wheel que vous obtenez lorsque vous faites juste build_wheel, mais je n'ai pas le temps ou l'énergie de défendre cette proposition moi-même à l'heure actuelle.

En tant que personne qui se souciait de la construction en place et n'aimait donc pas le "doit toujours passer par la route sdist": j'ai fait la paix avec la "route go sdist" il y a longtemps.

Ce problème est _très_ douloureux si vous le rencontrez, et le "tout copier par défaut" n'a pas de sens. Donc +10 pour mordre la balle.

La résolution de ce problème nécessite l'installation via sdist

J'avais, à tort, supposé que nous ferions le changement avec PEP 517.

Je suis tout à fait d'accord avec vous ici cependant.

IIRC, nous aurions pu le faire, mais les débats qu'il aurait déclenchés pour savoir si l'installation via sdist était acceptable étaient trop de controverse supplémentaire à ajouter à l'époque - et comme l'installation via la copie et la construction d'une roue était toujours une option, j'ai pris le moins stressant cours :-)

Je préférerais toujours passer à la construction via sdist, mais je n'ai pas le temps pour le moment de le faire moi-même.

solution de contournement : utilisez un clone peu profond (modifiez la profondeur en fonction):

cd d:\code
git clone --depth=100 https://github.com/PROJECT/PROJECT.git d:/code/shallow-PROJECT
move d:\code\PROJECT d:\code\PROJECT-bloated
move d:\code\shallow-PROJECT d:\code\PROJECT

Pour réitérer et résumer :

  • Les responsables de pip conviennent que ce n'est pas une bonne expérience pour les utilisateurs. les propres processus de développement de pip ont rencontré ce problème.
  • La raison pour laquelle cela se produit est que pip copie le répertoire source dans un répertoire temporaire, pour s'assurer que la construction ne dépend pas de quelque chose hors des sources.
  • La façon dont nous voulons résoudre ce problème consiste à modifier le comportement de pip pour créer une distribution source dans l'arborescence, décompresser la distribution source dans un répertoire temporaire et créer un binaire à partir de cela.

Maintenant, suivre cette voie résout également un tas d'autres problèmes d'utilisation autour de la mécanique de construction de pip pour les utilisateurs.

J'ai commencé un projet motivé pour refactoriser la logique de construction de pip. Bien que je ne m'attaque pas à ce problème dans le cadre de mon travail de refactorisation, je suis plus que disposé à aider quelqu'un qui est assez enclin à essayer de résoudre ce problème - le correctif serait assez impliqué dans la logique de construction de pip, qui est Ce n'est pas le morceau de code le plus simple et il peut y avoir des cas particuliers difficiles que nous ne remarquons que lors de l'implémentation.

Oh, et comme solution de contournement pour cela, ajouté dans #6770, le pip 19.3 exclura les répertoires .nox et .tox lors de la copie. Cela devrait réduire le temps que prendraient ces installations, pour un bon nombre d'utilisateurs.

Cela ne résout pas le problème pour les gros répertoires .git ou build -- c'est ce que l'approche que j'ai élaborée dans mon commentaire ci-dessus résoudrait. :)

Cela ne résout pas le problème pour les grands répertoires .git ou build -- c'est ce que l'approche que j'ai élaborée dans mon commentaire ci-dessus résoudrait. :)

Je sais qu'il existe des outils qui reposent sur .git , mais est-ce que quelqu'un s'appuie sur la copie de build ? Ce serait bien d'ajouter aux répertoires ignorés, heureux d'envoyer un PR si vous êtes d'accord.

Est-ce encore à l'étude ? C'est une surprise très douloureuse de voir plusieurs gigaoctets de vidages de données de débogage ignorés par git être copiés pendant un pip install .

Oui, jetez un œil aux problèmes liés comme #7555.

Ce problème persiste, car le répertoire à partir duquel j'installe contient peut-être 10 Mo de code python, mais beaucoup de fichiers de données json et .git .

Cela devrait être résolu par #7882 (créer des répertoires locaux en place).

Nous avons maintenant (par #7951) publié une version bêta de pip, pip 20.1b1. Cette version inclut #7882, qui a mis en œuvre une solution à ce problème.

J'espère que les participants à ce numéro nous aideront en testant la version bêta et en recherchant de nouveaux bogues. Nous aimerions identifier et aplanir tous les problèmes potentiels avant la sortie principale de la 20.1 mardi.

J'accueille également les commentaires positifs du type « yay, ça marche mieux maintenant ! » aussi, puisque le traqueur de problèmes est généralement plein de "problèmes". :)

Je dirai que c'est nettement mieux.

Ancien : noglob pip3 install . 3.76s user 2.51s system 12% cpu 50.245 total

Nouveau : noglob pip3 install . 3.40s user 0.70s system 42% cpu 9.764 total

Fonctionne très bien/plus rapide pour moi ! :+1:

» pip --version
pip 20.0.2 
» time pip install .
noglob pip install .  8.03s user 18.47s system 25% cpu 1:44.84 total
» pip --version
pip 20.1b1 
» time pip install .
noglob pip install .  3.69s user 0.31s system 92% cpu 4.307 total

de ~2 minutes à 4 secondes, merci beaucoup !

Merci pour les rapports positifs @PythonCoderAS @astrofrog @klamann ! :)

Malheureusement, il y a eu un certain nombre de problèmes avec la mise en œuvre des versions sur place (qui sont suivies sous #7555), ce qui signifie que pour l'instant, nous devons revenir à #7882. En conséquence, ce problème redeviendra un problème, et nous allons donc le rouvrir. À plus long terme, nous espérons avoir une solution qui résout les problèmes que les builds sur place ont résolus, mais sans l'impact sur les autres flux de travail que la solution actuelle avait.

Désolé pour le dérangement que cela va causer.

Malheureusement, il y a eu un certain nombre de problèmes avec la mise en œuvre des versions sur place

@pradyunsg merci pour la mise à jour. Quelques commentaires sur la terminologie (n'hésitez pas à ignorer, juste pour votre information) : cette phrase, ainsi que gh-7555, m'a dérouté car pip ne fait pas de builds sur place. Ce que les builds sur place ont toujours signifié est python setup.py build_ext --inplace (ou python setup.py develop ).

Ici, vous avez changé le sens en : "construire sans copier dans un tmpdir". Les modules d'extension ne se retrouvent toujours pas sur place, ils se retrouvent dans un build/ qui est généralement facile à nettoyer. Ce serait bien d'être un peu plus explicite dans par exemple gh-7555.

C'était ma formulation à l'origine. Désolé pour toute confusion, je ne savais pas que setuptools utilisait le terme "en place" pour signifier quelque chose de différent (et je ne sais toujours pas vraiment comment cette terminologie s'applique en dehors des setuptools). Nous verrons si nous pouvons trouver un terme plus neutre à l'avenir (bien que désinvolte, je ne sais pas quoi - suggestions acceptées avec reconnaissance 😉)

Pas de soucis du tout, merci @pfmoore. J'ai juste pensé le signaler, car la confusion sur la terminologie peut parfois entraîner une conversation entre eux.

et je ne sais toujours pas vraiment comment cette terminologie s'applique en dehors des outils de configuration

Pour des outils comme CMake et scikit-build, je pense que cela signifie la même chose : en fait, sur place, les binaires atterrissent à côté des sources.

« installations modifiables » d'autre part est (je crois) inventé ici, et signifie en quelque sorte « sur place dont pip est au courant ».

bien que désinvolte, je ne sais pas quoi - suggestions acceptées avec reconnaissance

peut-être juste une « construction locale » (par rapport à l'actuelle « copier dans tmpdir et compiler ») ?

« installations modifiables » d'autre part est (je crois) inventé ici, et signifie en quelque sorte « sur place dont pip est au courant ».

Nous avons récemment eu une longue discussion sur ce que signifie l'installation modifiable, et je pense que nous avons en fait atterri dans un endroit qui ressemble plus à machine local en ce qui concerne le pip. Mais pip ne sait pas où et comment sur la machine locale et c'est le travail des backends de build pour définir et gérer cela.

Vous pouvez essayer « in-tree build » (similaire à « in-tree PEP 517 backend ») ou « build in source dir »

Ma question est, pourquoi la fonctionnalité ne peut-elle pas être facultative, donc elle ne pose pas de problèmes mais peut être activée par un argument ou quelque chose de similaire ?

J'essaie de comprendre les solutions de contournement pour cela, où une installation modifiable n'est pas une option. Y a-t-il?

Une solution de contournement pourrait être de construire une roue (en utilisant directement votre backend de construction) puis de pointer pip pour l'installer

pourquoi la fonctionnalité ne peut-elle pas être facultative, donc elle ne pose pas de problèmes mais peut être activée par un argument ou quelque chose de similaire ?

Ça peut. La raison de l'annulation du changement était que nous n'avions aucune option de retrait ou une période pour obtenir des commentaires sur le changement. Nous avons de nouveaux indicateurs pour faciliter cela (--use-feature et --deprecated-feature), mais quelqu'un doit réimplémenter/réintroduire la fonctionnalité dans ce contexte maintenant.

En gros, je pense que ce que nous voulons faire ici est :

  • Ajoutez un --use-feature=in-tree-build comme opt-in.
  • Changez la valeur par défaut dans une version ultérieure avec --deprecated-feature=out-of-tree-build en tant qu'opt out + poussant les utilisateurs de --use-feature=in-tree-build à l'abandonner.
  • Supprimez les deux options dans une version ultérieure.

Une solution de contournement pourrait être de construire une roue (en utilisant directement votre backend de construction) puis de pointer pip pour l'installer

Je pensais sans étape de construction supplémentaire. Mais je suppose que je n'aurais jamais pensé que Python pourrait s'en tirer sans équivalents Makefile dès le début.

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