<p>pip install --editable et pip install clash pour les packages d'espace de noms</p>

Créé le 14 mars 2011  ·  41Commentaires  ·  Source: pypa/pip

Un package d'espace de noms installé modifiable et un autre installé régulièrement ne fonctionnent pas bien ensemble.

auto-locked bug

Commentaire le plus utile

Pour tous les curieux, voici une liste exhaustive du fonctionnement des packages d'espace de noms dans pip install , pip install -e , python setup.py install et python setup.py develop :

https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md

tl; dr: Vous pouvez utiliser pip install -e et python setup.py develop tant que tous les autres packages de votre espace de noms ont été installés en utilisant pip .

Tous les 41 commentaires

Même problème ici :(

La racine du problème ici est que setuptools inclut deux méthodes pour faire fonctionner les packages d'espace de noms: la méthode __init__.py (qui est documentée et utilisable par les humains), et la méthode de fichier ...-nspkg.pth , qui est utilisé uniquement avec --single-version-externally-managed (que pip utilise). Les deux méthodes ne sont pas compatibles l'une avec l'autre.

Après quelques discussions avec mitsuhiko et d'autres sur IRC, il semble que la meilleure solution (partielle) pour pip soit de demander à "pip install -e" d'ajouter une version modifiée du fichier standard setuptools ... nspkg.pth pour chaque paquet installé en développement . (Les modifications nécessaires consistent à utiliser le chemin develop egg-link au lieu de sitedir, et à ignorer complètement la vérification de init .py, car un paquet d'espace de noms installé en développement aura un init .py). Cela signifie que pip sera au moins compatible avec lui-même (les packages d'espace de noms pip-installés et pip-editable-installés fonctionneront ensemble). Les packages d'espace de noms installés par Pip et setuptools / distribuer ne seront pas compatibles.

J'ai récemment été mordu par ça aussi. Un autre problème causé par cela est que comme un __init__.py n'est pas installé pour le package d'espace de noms (en supposant que vous n'avez installé qu'un seul package dans cet espace de noms, et qu'il a été installé - version unique-gérée en externe), il casse la recherche du module du nez. C'est peut-être la faute du nez, mais je pense toujours qu'il est raisonnable de s'attendre à ce qu'un répertoire ne contienne pas de __init__.py qu'il ne s'agisse pas d'un package Python.

Je pense que pip devrait en quelque sorte tuer complètement le truc nspkg.pth et installer le __init__.py . Tant que le paquet lui-même est conçu correctement (ie le __init__.py est vide sauf pour extend_path / declare_namespace) cela ne devrait pas poser de problème. --single-version-external-managed a été conçu avec les packagers système à l'esprit, mais ils n'utiliseront pas pip en premier lieu. Je me demande donc s'il existe un moyen de désactiver complètement ce comportement sans être trop intrusif.

+1 pour abandonner '--single-version-external-managed': cette option n'est pas du tout destinée aux cas d'utilisation de pip. Si pip ne peut pas faire au moins un travail d'installation aussi efficace que easy_install, quel est son but?

Abandonner complètement --single-version-externally-managed ne se produira pas; les installations à plat sont une caractéristique. Je n'envisagerais pas de m'en éloigner dans le cas des packages d'espaces de noms pour éviter ces problèmes. Je n'aime pas cela, mais il ne semble pas y avoir de bonne option, étant donné l'incompatibilité inhérente entre les deux types de prise en charge des packages d'espace de noms intégrés à setuptools / distribuer.

Dire que --single-version-externally-managed n'est "pas destiné aux cas d'utilisation de pip" est quelque part entre faux et un hareng rouge. L'indicateur est destiné à autoriser les installations plates à une seule version, gérées par un outil autre que easy_install. C'est précisément pour cela que pip l'utilise; le fait que l'auteur de setuptools pensait à l'origine (et à tort) que seuls les packagers système seraient intéressés par une telle fonctionnalité n'est pas pertinent.

La rupture ici est un bogue inhérent à la technique que setuptools utilise pour les paquets d'espace de noms avec cet indicateur, et le bogue est tout aussi présent lorsque l'indicateur est utilisé par son public initialement prévu, les packagers système (j'ai d'abord vu le bogue dans l'interaction entre un " setup.py develop "un package installé et un package d'espace de noms installé dans le package système).

Je rencontre également ce bug. Je suppose que c'est l'un de ces bugs insolubles qui est là pour rester. Tant pis.

J'accepterais un correctif pour éviter --single-version-externally-managed lorsqu'un paquet d'espace de noms est impliqué, ce qui, je pense, résoudrait ce problème. Je n'ai actuellement aucun projet pour écrire ce correctif.

Pourquoi pas une option que l'on peut passer à pip install pour ne pas utiliser --single-version-externally-managed ? Je teste en commentant cela dans ./pip/req.py:568 et tous les paquets maintenant installés dans le répertoire egg, comme le fait easy_install. Parfois, je veux faire cela si j'ai utilisé à la fois pip et easy_install afin que mon site-packages ne se mélange pas avec certains packages installés à plat et d'autres non.

Je ne vois pas de problème avec une option --egg pour désactiver --single-version-externally-managed .

https://github.com/k4ml/pip/commit/93cd6b16207d2eba201a7fc3126624b616f5e6f9

Quelqu'un peut-il commenter si je vais dans la bonne direction? C'est la première fois que je pirate du code pip, c'est donc basé sur mes quelques minutes d'aperçu d'une partie de celui-ci, juste pour obtenir pip install --egg somepackages installer tout dans un seul répertoire d'oeuf.

Quelqu'un peut-il commenter si je vais dans la bonne direction?

Cela me semble bien, a juste besoin d'un test. Les tests sont pour la plupart de haut niveau
les tests d'intégration utilisant ScriptTest, devraient être faciles à écrire un basé sur
exemples existants. Dans ce cas, vous voudrez simplement tester cette installation
un exemple de package entraîne un fichier .egg, et non une installation plate, dans
packages de site. Vous devez installer un package à partir du système de fichiers local,
pas le réseau: tests/packages/FSPkg fonctionnera probablement très bien. Ajouter
le test de tests/test_basic.py est ok.

Merci!

Demandes d'extraction - https://github.com/pypa/pip/pull/541

Je pense également rendre possible la mise en place de cet indicateur dans pip.conf. Qu'est-ce que tu en penses?

Je pense également rendre possible la mise en place de cet indicateur dans pip.conf. Qu'est-ce que tu en penses?

Discutons de la pull request.

Demande d'extraction fusionnée n ° 541, qui fournit une solution de contournement. Merci @ k4ml!

Remarque: l'option --egg , qui a été ajoutée pour résoudre ce problème, peut potentiellement être supprimée, sans solution alternative proposée. Voir discussion dans # 1749

Voici un script pour reproduire réellement ce problème

https://gist.github.com/Ivoz/d9bff05069e0ec53e6ea

Je ne suis pas un grand fan de la solution --egg, mais il doit y avoir une solution de contournement moins lourde pour cela.

sans solution de contournement, pendant le développement, je ne peux pas utiliser - modifiable une fois, puis juste modifier et tester. chaque fois que je sauvegarde mon code, je dois lancer pip install -I --no-deps . qui devient vraiment vieux et fragile (lire: parfois j'oublie).

Une partie du problème avec la façon dont tout ce problème se manifeste est qu'il est silencieux. vous ne pouvez tout simplement pas importer un module même s'il est installé et pip vous dit qu'il est là.

ce serait une étape positive juste de faire se plaindre pip s'il essayait d'installer des packages modifiables dans le cadre d'un espace de noms où un package non modifiable dans cet espace de noms est déjà installé. ou bien de se plaindre si vous essayez d'installer un package non modifiable faisant partie d'un espace de noms où un package modifiable dans cet espace de noms est déjà installé.

une autre option, si nous voulons réellement que les packages d'espaces de noms et les installations modifiables fonctionnent toujours, pourrait être que si un package d'espace de noms est installé comme modifiable, pip pourrait réorganiser tous les autres packages de cet espace de noms comme modifiables avec le package souhaité.

J'ai soumis 2 propositions pour résoudre ce problème dans setuptools https://bitbucket.org/pypa/setuptools/issue/250/develop-and-install-single-version. FYI.

en mettant

import pkg_resources; pkg_resources.fixup_namespace_packages ('')

dans un fichier .pth dans site-packages semble suffisant pour que les éléments installés de pip install -e fonctionnent correctement.

Cela affecte également deux packages avec le même espace de noms supérieur, les deux étant installés comme modifiables. La deuxième installation du package est interrompue.

Nous utilisons un espace de noms global pour toutes nos applications et donc ce problème est un peu difficile (+ le problème que setuptools ne prend pas en charge les roues, ce qui est nécessaire en raison du manque de compilateur sur nos plates-formes de déploiement Windows). De plus, toutes les solutions recommandées semblent échouer dans notre configuration avec Python 3.4.

Après avoir réalisé que pip install -e exécute setup.py develop pour le projet qui devrait être modifiable, je me suis connecté à la procédure setuptools et j'ai écrit un fichier * .pth, qui "introduit" les packages d'espace de noms lorsque le processus python départs. Cela résout le problème pour nous lors de l'utilisation de setuptools 18 et pip 7.1.0.

Un exemple de fichier setup.py, qui montre comment cela peut être réalisé, peut être trouvé ici:
https://gist.github.com/cbrand/a1624ac3e9c81ce45fcb

J'espère que cela sera également utile pour d'autres personnes.

J'ai également rencontré celui-ci aujourd'hui, et cela m'empêche de passer de buildout à virtualenv + pip.

J'ai créé une petite démo pour illustrer le problème. Pour le tester, décompressez le .tar.gz et exécutez le script {{run-me}} à l'intérieur. Cela peut être utile lors du test d'un correctif.

Je rencontre également ce problème.

En essayant de comprendre, je suis tombé sur la solution proposée par @carljm dans https://github.com/pypa/pip/issues/3#issuecomment -1659959, ie _have "pip install -e" ajoute une version modifiée du standard setuptools ... nspkg.pth pour chaque package installé par le développement_.

J'ai expérimenté cette approche manuellement et cela semble bien fonctionner. Il semble que cela résoudrait en même temps la question des arbres source peu profonds avec des paquets d'espace de noms manquants, comme décrit dans # 3160.

Je me demande donc si cette approche est toujours considérée comme valide, s'il y a eu une tentative de la mettre en œuvre et si un correctif serait envisagé?

Alors ... aucun espoir que celui-ci soit corrigé dans un proche avenir?

Un effet secondaire de pkg_resources.get_distribution() fait que l'importation fonctionne. Nous avons découvert cela lorsque le code qui chargeait les points d'entrée fonctionnait correctement alors que le shell python échouait.

Cela peut également expliquer pourquoi un shell ipython n'a aucun problème à importer les packages.

Je suis étonné que ce bogue soit toujours ouvert sans travail clair après 5 ans.

Si votre travail consiste à coller des frameworks ensemble dans un framework unifié, pip rend votre travail nul. Je n'ai honnêtement aucune idée de la manière de faire avancer mon travail à cause de ce bug.

C'est un problème difficile à résoudre dans les projets principalement bénévoles,
N'hésitez pas à ajouter le support nécessaire dans setuptools afin que pip puisse le faire correctement

Brandon Github [email protected] écrit:

Je suis étonné que ce bogue soit toujours ouvert sans travail clair après 5 ans.

Ouais, c'est dommage.

Si votre travail consiste à coller des frameworks ensemble dans un framework unifié,
pip rend votre travail nul. Je n'ai honnêtement aucune idée de la façon de procéder
mon travail à cause de ce bug.

J'ai récemment appliqué le hack fixup_namespace_packages ('') mentionné ci-dessus et
cela semble fonctionner: j'ai créé un z.pth dans les packages de site de venv
contenant juste import pkg_resources; pkg_resources.fixup_namespace_packages('')

Ça vaut le coup d'essayer, à mon humble avis.

Juste encore une autre bosse ici!

Je mentionnerai simplement que chaque paquet marrow utilise des espaces de noms (certains paquets en contenant jusqu'à quatre ou cinq) et que ce problème particulier a été un peu un fléau de mon existence lorsqu'il s'agit d'aider les nouveaux utilisateurs à se mettre en place avec des outils de développement . J'ai un peu moins de 60 paquets qui utilisent cela. La note entry_points est également intéressante, car pratiquement tous les paquets contribuant à un espace de noms contribuent également entry_points .

L'approche pip ne fonctionne, d'après mon expérience, que si le package _every_ est installé, modifiable, à partir du disque, qui coopère sur l'espace de noms. Si un paquet est installé non modifiable via pip, toute la pelote de laine commence à se défaire avec des symptômes très, très obtus pour les nouveaux utilisateurs. (Tels que les modules importables par intermittence; une vérification générale de la cohérence de l'importation de l'espace de noms parent et de la vérification de namespace.__path___ a rapidement identifié le paquet bloqué coupable lors des tests.) Mélange de paquets correctement installés par pip et de setup.py develop 'd pur les sources (en évitant pip) semblent cependant fonctionner.

Nous semblons également être en mesure de nous retrouver dans des situations étranges où un seul package contribuant à l'espace de noms peut être installé de trois manières différentes, parfois toutes simultanément. (Les appels répétés à pip uninstall , chacun trouvant plus de fichiers, est aussi hilarant à voir que malheureux.) L'installation de dépendances lors de l'utilisation de pip install -e semble également incohérente. Dans la majorité des cas, nous nous retrouvons avec des espaces de noms correctement décompressés (installés), des fichiers pth-link (installés modifiables), et dans un cas, nous avons réussi à obtenir un fichier compressé .egg installé, malgré zip_safe étant False sur ce package dépendant et aucune distribution .egg n'est fournie sur Pypi.

La frustration liée aux problèmes d'espace de noms atteint son apogée après la quatrième fois qu'un environnement virtuel est atomisé pour recommencer à zéro. ;)

Pas de solution mais je mets juste quelques notes. Lors du mélange entre des packages 'modifiables', des packages avec un espace de nom et des packages normaux, j'ai plus de chance avec buildout + mr.developer.

Bien que le hack de correction @lelit mentionné semble fonctionner pour certains paquets, il casse également certains paquets / compilations pour nous.

Après avoir joué avec l'installation de pip et le mode modifiable, j'ai eu la même idée que @carljm (ajouter un fichier -nspkg.pth pour chaque paquet modifiable), mais personne ne semble l'avoir implémenté (ou était-ce maintenant obsolète - option -egg?).

Est-ce toujours un problème sur les nouvelles versions de python avec PEP420 implémenté? (lire: cela aiderait-il à passer à une version plus récente de python?)

L'utilisation du style PEP420 m'a aidé à plusieurs reprises maintenant dans le mode modifiable.

Malheureusement, il est livré avec ses propres problèmes: par exemple, setuptools ' find_packages ne le prend pas en charge , donc mes nouveaux paquets contiennent le hack suivant:

-    packages=find_packages('src'),
+    packages=['toplevel.child.' + package
+              for package in find_packages('src/toplevel/child/')],

personne ne semble avoir implémenté l'ajout d'un -nspkg.pth pour chaque paquet modifiable.

Découvrez Setuptools 31 qui ajoute la prise en charge de cette fonctionnalité et coexiste également avec les packages PEP-420 sur Python 3.5+.

Pour tous les curieux, voici une liste exhaustive du fonctionnement des packages d'espace de noms dans pip install , pip install -e , python setup.py install et python setup.py develop :

https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md

tl; dr: Vous pouvez utiliser pip install -e et python setup.py develop tant que tous les autres packages de votre espace de noms ont été installés en utilisant pip .

Je vais clore ce problème. Il semble que setuptools 31 a corrigé ce problème pour nos scripts de reproduction, et au-delà de cela, pip ne peut rien faire ici.

@jonparrott
Quelles versions de pip et setuptools ont été utilisées pour obtenir des résultats sur https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md ?

@dstufft Bien que j'apprécie que ce soit censé être corrigé, j'aimerais voir la table de compatibilité de @jonparrott réexécutée comme preuve. J'espère que tout va pour le mieux, prévoyez le pire sur des tickets qui ont près de 7 ans et qui ont des scénarios d'échec aussi étendus. La confiance n'est pas élevée étant donné la longue histoire de ce problème, et la relance de la suite nox moi-même, les échecs indiqueraient un manque de résolution réelle.

Dans les exemples de @jonparrott , les cas d'échec pourraient être réduits à "en utilisant python setup.py install directement (à l'exclusion des échecs de PEP 420 sur Python 2, qui sont attendus). Cela échoue même dans les cas où pip n'est pas impliqué du tout (comme python setup.py install + python setup.py develop ).

Ce ticket était pour des combinaisons de pip install . et pip install -e ou python setup.py develop .

Le graphique déjà posté par @jonparrott confirme que ce ticket est résolu et que tous les problèmes restants ici sont un problème avec python setup.py install et non avec pip.

J'ai juste relancé mes tests et tout est pareil que je l'ai exécuté initialement. Je suis d'accord avec l' évaluation de

@ piotr-dobrogost le test utilise les dernières versions des deux. Au moment d'écrire ces lignes, pip 9.0.1 et setuptools 34.3.2.

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