DistutilsOptionError: debe suministrar home o prefix / exec-prefix, no ambos

144

Por lo general, he instalado paquetes de python a través de pip.

Para Google App Engine, necesito instalar paquetes en otro directorio de destino.

He intentado:

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

pero falla con:

debe suministrar home o prefix / exec-prefix, no ambos

¿Cómo puedo hacer que esto funcione?

Arkind
fuente

Respuestas:

289

¿Estás usando OS X y Homebrew? La página de Python Homebrew https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md señala un problema conocido con pip y una solución alternativa.

Trabajó para mi.

Puede hacer que este "prefijo vacío" sea el predeterminado agregando un archivo ~ / .pydistutils.cfg con el siguiente contenido:

[install]
prefix=

Editar: No use esta opción recomendada por Homebrew, ya que interrumpirá las operaciones normales de pip .

ayvazj
fuente
55
cosas buenas, el enlace es malo, este es el nuevo que espero: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/…
patt0
66
Tenga en cuenta que ese archivo rompió el entorno virtual para mí.
Dmytro Sadovnychyi
16
Este negocio de prefijo vacío interrumpe las pip installoperaciones normales :(
Jaap
10
¿Alguien ha descubierto cómo permitir --targetmientras no arruinar por defecto pip installcomportamiento?
ryantuck
3
Esto ya no parece ser válido. El enlace está roto y el enlace actualizado no habla de pydistutils.cfg
Lucretiel
164

Creo que hay una solución más simple para este problema (Homebrew's Python en macOS) que no interrumpirá sus operaciones normales de pip.

Todo lo que tiene que hacer es crear un setup.cfgarchivo en el directorio raíz de su proyecto, generalmente donde está su __init__.pyarchivo py principal o ejecutable. Entonces, si la carpeta raíz de su proyecto es:, /path/to/my/project/cree un setup.cfgarchivo allí y coloque las palabras mágicas dentro:

[install]
prefix=  

OK, ahora deberías poder ejecutar los comandos de pip para esa carpeta:

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

Este comando se ejecutará correctamente solo para esa carpeta. Simplemente copie setup.cfga cualquier otro proyecto que pueda tener. No es necesario escribir un .pydistutils.cfgen su directorio de inicio.

Una vez que haya terminado de instalar los módulos, puede eliminar setup.cfg .

AndreG
fuente
2
Esto funcionó perfectamente con pip3.6 también. Y mi pepita aún está intacta.
Aníbal
10
Esta debería ser la respuesta aceptada. Evita causar problemas con la configuración global de pip.
TrinitronX
10
énfasis en la parte de quitar setup.cfgdespués de la instalación. Me quemé durante 2 días enteros tratando de descubrir por qué mi entorno virtualenv estaba jodido, con errores como Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Extracción del archivo de instalación me devolvió la cordura
kip2
1
@ kip2 sí, lo has notado correctamente, así que he editado la respuesta para enfatizar ese bit, AndreG, ten en cuenta.
bool.dev
Gracias por notarlo. ¿Sería más correcto si dijera "Una vez que haya terminado de instalar los módulos, debe eliminar setup.cfg"?
AndreG
25

En OSX (mac), suponiendo una carpeta de proyecto llamada / var / myproject

  1. cd /var/myproject
  2. Crea un archivo llamado setup.cfgy agrega [install] prefix=
  3. correr pip install <packagename> -t .
Jerome Anthony
fuente
1
No estoy seguro de cómo esto es diferente de la respuesta de @AndreG
Alastair McCormack
La diferencia para mí es que esta solución está en el directorio y lo hace en -t .lugar de permanecer fuera del directorio. Esta manera funcionó para mí y la otra no, aunque no tengo idea de por qué.
Chuck Wilbur el
12

Otra solución * para los usuarios de Homebrew es simplemente usar a virtualenv.

Por supuesto, eso puede eliminar la necesidad del directorio de destino de todos modos, pero incluso si no lo hace, he encontrado --targettrabajos por defecto (como en, sin crear / modificar un archivo de configuración) cuando está en un entorno virtual.


* Digo solución; tal vez es solo otra motivación para usar meticulosamente los venvs ...

OJFord
fuente
3
No puedo creer que esto fuera solo hace un mes. Me sorprendí respondiendo mi propia pregunta; antes de tiempo ...
OJFord
Entonces, recientemente tuve el problema en la pregunta de OP, y simplemente crear un virtualenv resolvió el problema por mí. Todavía podría instalar en el directorio de destino. Mi problema también fue complicado porque instalé python3 también, pero +1 para la solución virtualenv.
Josh Brown
3

Llegué a errores con las otras recomendaciones --install-option="--prefix=lib". Lo único que encontré que funcionó es usar PYTHONUSERBASEcomo se describe aquí .

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

esto no es exactamente lo mismo --target, pero en cualquier caso me sirve.

Imran Rashid
fuente
2

Como se mencionó, este es un error conocido con pip & python instalado con homebrew.

Si crea un ~/.pydistutils.cfgarchivo con la instrucción "prefijo vacío", solucionará este problema pero interrumpirá las operaciones normales de pip.

Hasta que este error se aborde oficialmente, una de las opciones sería crear su propio script bash que manejaría este caso:

 #!/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

Este script envuelve su comando y:

  1. acepta parámetros de nombre y destino
  2. comprueba si esos parámetros están vacíos
  3. crea un ~/.pydistutils.cfgarchivo con la instrucción "prefijo vacío"
  4. ejecuta su comando pip con los parámetros proporcionados
  5. elimina el ~/.pydistutils.cfgarchivo

Este script se puede cambiar y adaptar para satisfacer sus necesidades, pero se hace una idea. Y le permite ejecutar su comando sin pip de frenado. Espero eso ayude :)

vs.
fuente
2

Si está usando virtualenv *, puede ser una buena idea verificar which pipque esté usando.

Si ve algo como /usr/local/bin/pipque se ha escapado de su entorno. Reactivar su virtualenv arreglará esto:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Uso virtualfish, pero supongo que este consejo es relevante para ambos.

Graham P Heath
fuente
utilizando virtualenv era en realidad la solución en mi caso similar :)
chriscatfr
-1

Tengo un problema similar. Uso el indicador --system para evitar el error, ya que describo aquí en otro hilo donde explico el caso específico de mi situación. Publico esto aquí esperando que pueda ayudar a cualquiera que enfrente el mismo problema.

pipelog
fuente