DistutilsOptionError: deve fornecer home ou o prefixo / exec-prefix - não os dois

144

Eu normalmente instalo pacotes python através do pip.

Para o Google App Engine, preciso instalar pacotes em outro diretório de destino.

Eu tentei:

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

mas falha com:

deve fornecer home ou prefix / exec-prefix - não ambos

Como posso fazer isso funcionar?

Arkind
fonte

Respostas:

289

Você está usando o OS X e o Homebrew? A página python do Homebrew https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md chama um problema conhecido com pip e uma solução alternativa.

Trabalhou para mim.

Você pode tornar esse "prefixo vazio" o padrão adicionando um arquivo ~ / .pydistutils.cfg com o seguinte conteúdo:

[install]
prefix=

Edit: Não use esta opção recomendada da Homebrew, pois ela interromperá as operações normais do pip .

ayvazj
fonte
5
coisas boas, o link é ruim, este é o novo eu espero: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/...
patt0
6
Observe que esse arquivo quebrou o ambiente virtual para mim.
Dmytro Sadovnychyi
16
Este negócio de prefixo vazio interrompe as pip installoperações normais :(
Jaap
10
alguém descobriu como permitir --target, sem arruinar o pip installcomportamento padrão ?
ryantuck
3
Isso não parece mais ser válido. A ligação é interrompida e o link atualizado não falar sobre pydistutils.cfg
Lucretiel
164

Acredito que exista uma solução mais simples para esse problema (o Python da Homebrew no macOS) que não interrompa suas operações normais de pip.

Tudo que você precisa fazer é criar um setup.cfgarquivo no diretório raiz do seu projeto, geralmente onde está o seu __init__.pyarquivo py principal ou executável. Portanto, se a pasta raiz do seu projeto for:, /path/to/my/project/crie um setup.cfgarquivo e coloque as palavras mágicas dentro:

[install]
prefix=  

OK, agora você poderá executar os comandos do pip para essa pasta:

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

Este comando será executado normalmente apenas para essa pasta. Basta copiar setup.cfgpara quaisquer outros projetos que você possa ter. Não é necessário escrever um .pydistutils.cfgno seu diretório pessoal.

Depois de concluir a instalação dos módulos, você poderá removê-lo setup.cfg .

AndreG
fonte
2
Isso funcionou perfeitamente com o pip3.6 também. E meu pip ainda está intacto.
Hannibal
10
Essa deve ser a resposta aceita. Evita causar problemas nas configurações globais de pip.
TrinitronX
10
ênfase na remoção setup.cfgapós a instalação. Eu queimei dois dias inteiros tentando descobrir por que meu ambiente de virtualenv estava ferrado, com erros do tipo Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Removendo o arquivo de instalação restaurou minha sanidade
kip2
1
@ kip2 sim, anotado corretamente por você, por isso editei a resposta para enfatizar esse pouco, AndreG, por favor.
bool.dev
Obrigado por notar. Seria mais correto se eu dissesse "Depois de concluir a instalação dos módulos, você deverá remover o setup.cfg"?
AndreG
25

No OSX (mac), assumindo uma pasta do projeto chamada / var / myproject

  1. cd /var/myproject
  2. Crie um arquivo chamado setup.cfge adicione [install] prefix=
  3. Corre pip install <packagename> -t .
Jerome Anthony
fonte
1
Eu não sei como isso é diferente de resposta @AndreG
Alastair McCormack
A diferença para mim é que o CD desta solução está no diretório e funciona, em -t .vez de ficar fora do diretório. Dessa maneira, funcionou para mim e a outra não, embora eu não tenha idéia do porquê.
Chuck Wilbur
12

Outra solução * para usuários do Homebrew é simplesmente usar a virtualenv.

Obviamente, isso pode remover a necessidade do diretório de destino de qualquer maneira - mas mesmo se não houver, eu encontrei --targettrabalhos por padrão (como em, sem criar / modificar um arquivo de configuração) quando em um ambiente virtual.


* Eu digo solução; talvez seja apenas mais uma motivação para usar meticulosamente os venvs ...

OJFord
fonte
3
Não posso acreditar que isso foi há apenas um mês. Apenas me peguei respondendo minha própria pergunta; antes do tempo ...
OJFord
Então, recentemente, tive o problema na pergunta do OP, e apenas criar um virtualenv resolveu o problema para mim. Eu ainda poderia instalar no diretório de destino. Meu problema foi adicionalmente complicado porque eu instalei o python3 também, mas +1 na solução virtualenv.
Josh Brown
3

Eu encontrei erros com as outras recomendações ao redor --install-option="--prefix=lib". A única coisa que descobri que funcionou é usar PYTHONUSERBASEcomo descrito aqui .

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

isso não é exatamente o mesmo que --target, mas faz o truque para mim em qualquer caso.

Imran Rashid
fonte
2

Como mencionado anteriormente, esse bug é conhecido com o pip & python instalado com o homebrew.

Se você criar um ~/.pydistutils.cfgarquivo com a instrução "prefixo vazio", ele corrigirá esse problema, mas interromperá as operações normais do pip.

Até que esse bug seja resolvido oficialmente, uma das opções seria criar seu próprio script bash que trataria desse 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 envolve seu comando e:

  1. aceita parâmetros de nome e destino
  2. verifica se esses parâmetros estão vazios
  3. cria ~/.pydistutils.cfgarquivo com a instrução "prefixo vazio"
  4. executa seu comando pip com parâmetros fornecidos
  5. remove ~/.pydistutils.cfgarquivo

Este script pode ser alterado e adaptado para atender às suas necessidades, mas você tem uma idéia. E isso permite que você execute seu comando sem frear o pip. Espero que ajude :)

vs.
fonte
2

Se você estiver usando o virtualenv *, pode ser uma boa ideia verificar novamente which pipse está usando.

Se você vir algo como /usr/local/bin/pipse tivesse saído do seu ambiente. A reativação do seu virtualenv corrigirá isso:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Eu uso o peixe virtual, mas suponho que essa dica seja relevante para ambos.

Graham P Heath
fonte
usando virtualenv era na verdade a solução no meu caso semelhante :)
chriscatfr
-1

Eu tenho um problema semelhante. Uso o sinalizador --system para evitar o erro, como descrevo aqui em outro thread, onde explico o caso específico da minha situação. Eu posto isso aqui esperando que possa ajudar alguém que enfrenta o mesmo problema.

pipelog
fonte