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?

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 .


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 .


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 .

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 ...


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.


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 :)


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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.