DistutilsOptionError: doit fournir soit home, soit prefix / exec-prefix - pas les deux

144

J'ai généralement installé des packages python via pip.

Pour Google App Engine, je dois installer des packages dans un autre répertoire cible.

J'ai essayé:

pip install -I flask-restful --target ./lib

mais cela échoue avec:

doit fournir soit home, soit prefix / exec-prefix - pas les deux

Comment puis-je faire fonctionner cela?

Arkind
la source

Réponses:

289

Utilisez-vous OS X et Homebrew? La page Homebrew python https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md appelle un problème connu avec pip et une solution.

A travaillé pour moi.

Vous pouvez faire de ce "préfixe vide" la valeur par défaut en ajoutant un fichier ~ / .pydistutils.cfg avec le contenu suivant:

[install]
prefix=

Edit: n'utilisez pas cette option recommandée par Homebrew, cela interrompra les opérations normales de pip .

ayvazj
la source
5
bon truc, le lien est mauvais, c'est le nouveau que j'attends: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/…
patt0
6
Notez que ce fichier a cassé l'environnement virtuel pour moi.
Dmytro Sadovnychyi
16
Cette entreprise de préfixe vide rompt les pip installopérations normales :(
Jaap
10
Quelqu'un at - compris comment laisser --targettout ne pas ruiner par défaut le pip installcomportement?
ryantuck
3
Cela ne semble plus être valide. Le lien est rompu et le lien mis à jour ne parle pas de pydistutils.cfg
Lucretiel
164

Je pense qu'il existe une solution plus simple à ce problème (Python de Homebrew sur macOS) qui ne cassera pas vos opérations pip normales.

Tout ce que vous avez à faire est de créer un setup.cfgfichier dans le répertoire racine de votre projet, généralement là où se trouve votre __init__.pyfichier py principal ou exécutable. Donc, si le dossier racine de votre projet est:, /path/to/my/project/créez un setup.cfgfichier là-dedans et mettez les mots magiques à l'intérieur:

[install]
prefix=  

OK, maintenant vous devriez pouvoir exécuter les commandes de pip pour ce dossier:

pip install package -t /path/to/my/project/  

Cette commande s'exécutera correctement pour ce dossier uniquement. Copiez simplement setup.cfgles autres projets que vous pourriez avoir. Pas besoin d'écrire un .pydistutils.cfgsur votre répertoire personnel.

Une fois que vous avez terminé d'installer les modules, vous pouvez supprimer setup.cfg .

AndreG
la source
2
Cela fonctionnait parfaitement avec pip3.6 également. Et mon pip est toujours intact.
Hannibal
10
Cela devrait être la réponse acceptée. Évite de causer des problèmes avec les paramètres globaux du pip.
TrinitronX
10
accent sur la partie retirer setup.cfgaprès l'installation. J'ai brûlé pendant 2 jours entiers en essayant de comprendre pourquoi mon environnement virtualenv était vissé, avec des erreurs comme Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. La suppression du fichier d'installation a restauré ma santé mentale
kip2
1
@ kip2 oui à juste titre noté par vous, j'ai donc édité la réponse pour souligner ce peu, AndreG s'il vous plaît noter.
bool.dev
Merci d'avoir noté. Serait-il plus correct si je disais "Une fois que vous avez terminé d'installer les modules, vous devez supprimer setup.cfg"?
AndreG
25

Sous OSX (mac), en supposant un dossier de projet appelé / var / myproject

  1. cd /var/myproject
  2. Créez un fichier appelé setup.cfget ajoutez [install] prefix=
  3. Courir pip install <packagename> -t .
Jérôme Anthony
la source
1
Je ne sais pas en quoi cela diffère de la réponse @AndreG
Alastair McCormack
La différence pour moi est que cette solution se trouve dans le répertoire et le fait -t .au lieu de rester en dehors du répertoire . Cette façon a fonctionné pour moi et l'autre n'a pas fonctionné, même si je ne sais pas pourquoi.
Chuck Wilbur
12

Une autre solution * pour les utilisateurs de Homebrew consiste simplement à utiliser un fichier virtualenv.

Bien sûr, cela peut supprimer le besoin du répertoire cible de toute façon - mais même si ce n'est pas le cas, j'ai trouvé des --targettravaux par défaut (comme dans, sans créer / modifier un fichier de configuration) dans un environnement virtuel.


* Je dis solution; c'est peut-être juste une autre motivation pour utiliser méticuleusement les venvs ...

OJFord
la source
3
Je ne peux pas croire que c'était il y a seulement un mois. Je viens de me surprendre à répondre à ma propre question; avant le temps ...
OJFord
Donc, j'ai récemment eu le problème dans la question d'OP, et la simple création d'un virtualenv a résolu le problème pour moi. Je pourrais toujours installer dans le répertoire cible. Mon problème était également compliqué car j'ai également installé python3, mais +1 pour la solution virtualenv.
Josh Brown
3

J'ai rencontré des erreurs avec les autres recommandations --install-option="--prefix=lib". La seule chose que j'ai trouvée qui a fonctionné est d'utiliser PYTHONUSERBASEcomme décrit ici .

export PYTHONUSERBASE=lib
pip install -I flask-restful --user

ce n'est pas exactement la même chose que --target, mais cela me convient en tout cas.

Imran Rashid
la source
2

Comme d'autres l'ont mentionné, il s'agit d'un bogue connu avec pip & python installé avec homebrew.

Si vous créez un ~/.pydistutils.cfgfichier avec l'instruction "préfixe vide", cela résoudra ce problème mais cela interrompra les opérations normales de pip.

Jusqu'à ce que ce bogue soit officiellement résolu, l'une des options serait de créer votre propre script bash qui gérerait ce cas:

 #!/bin/bash

 name=''
 target=''

 while getopts 'n:t:' flag; do
     case "${flag}" in
         n) name="${OPTARG}" ;;
         t) target="${OPTARG}" ;;
     esac
 done

 if [ -z "$target" ];
 then
     echo "Target parameter must be provided"
     exit 1
 fi

 if [ -z "$name" ];
 then
     echo "Name parameter must be provided"
     exit 1
 fi

 # current workaround for homebrew bug
 file=$HOME'/.pydistutils.cfg'
 touch $file

 /bin/cat <<EOM >$file
 [install]
 prefix=
 EOM
 # end of current workaround for homebrew bug

 pip install -I $name --target $target

 # current workaround for homebrew bug
 rm -rf $file
 # end of current workaround for homebrew bug

Ce script encapsule votre commande et:

  1. accepte les paramètres de nom et de cible
  2. vérifie si ces paramètres sont vides
  3. crée un ~/.pydistutils.cfgfichier avec l'instruction "préfixe vide"
  4. exécute votre commande pip avec les paramètres fournis
  5. supprime le ~/.pydistutils.cfgfichier

Ce script peut être modifié et adapté pour répondre à vos besoins, mais vous avez une idée. Et cela vous permet d'exécuter votre commande sans pépin de freinage. J'espère que ça aide :)

contre.
la source
2

Si vous utilisez virtualenv *, il peut être judicieux de vérifier which pipque vous utilisez.

Si vous voyez quelque chose comme si /usr/local/bin/pipvous êtes sorti de votre environnement. La réactivation de votre virtualenv résoudra ce problème:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: J'utilise virtualfish, mais je suppose que cette astuce concerne les deux.

Graham P Heath
la source
utiliser virtualenv était en fait la solution dans mon cas similaire :)
chriscatfr
-1

J'ai un problème similaire. J'utilise le drapeau --system pour éviter l'erreur comme je le décris ici sur un autre thread où j'explique le cas spécifique de ma situation. Je poste ceci ici en espérant que cela puisse aider toute personne confrontée au même problème.

pipelog
la source