DistutilsOptionError: musi podać home lub prefix / exec-prefix - nie oba

144

Zazwyczaj instalowałem pakiety Pythona przez pip.

W przypadku Google App Engine muszę zainstalować pakiety w innym katalogu docelowym.

Próbowałem:

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

ale zawodzi z:

musi podać home lub prefix / exec-prefix - nie oba

Jak to działa?

Arkind
źródło

Odpowiedzi:

289

Czy używasz OS X i Homebrew? Strona Homebrew w języku Python https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md przedstawia znany problem z pip i obejście go.

Pracował dla mnie.

Możesz ustawić ten „pusty prefiks” jako domyślny, dodając plik ~ / .pydistutils.cfg o następującej zawartości:

[install]
prefix=

Edycja: nie używaj tej zalecanej opcji Homebrew, spowoduje to przerwanie normalnych operacji pip .

ayvazj
źródło
5
dobra rzecz, link jest zły, to jest nowy, którego oczekuję: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/ ...
patt0
6
Zwróć uwagę, że ten plik zepsuł dla mnie środowisko wirtualne.
Dmytro Sadovnychyi
16
Ten pusty biznes prefiksu przerywa normalne pip installoperacje :(
Jaap,
10
czy ktoś wymyślił, jak zezwolić --target, nie psując domyślnego pip installzachowania?
ryantuck
3
To już nie wydaje się być aktualne. Link jest uszkodzony, a zaktualizowany link nie mówi o pydistutils.cfg
Lucretiel,
164

Uważam, że istnieje prostsze rozwiązanie tego problemu (Python firmy Homebrew na macOS), które nie zakłóci normalnych operacji pip.

Wszystko, co musisz zrobić, to utworzyć setup.cfgplik w katalogu głównym projektu, zwykle tam, gdzie znajduje się główny __init__.pylub wykonywalny plik py. Więc jeśli katalog główny twojego projektu to /path/to/my/project/:, utwórz tam setup.cfgplik i umieść w nim magiczne słowa:

[install]
prefix=  

OK, teraz możesz uruchomić polecenia pip dla tego folderu:

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

To polecenie będzie działać z wdziękiem tylko dla tego folderu. Po prostu skopiuj setup.cfgdo innych projektów, które możesz mieć. Nie musisz pisać .pydistutils.cfgw swoim katalogu domowym.

Po zainstalowaniu modułów możesz je usunąć setup.cfg .

AndreG
źródło
2
Działa to również doskonale z pip3.6. A mój pip jest nadal nienaruszony.
Hannibal
10
To powinna być akceptowana odpowiedź. Pozwala uniknąć problemów z globalnymi ustawieniami pip.
TrinitronX
10
nacisk na usunięcie setup.cfgczęści po instalacji. Spaliłem całe 2 dni, próbując dowiedzieć się, dlaczego moje środowisko virtualenv zostało zepsute, z błędami takimi jak Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Usunięcie pliku instalacyjnego przywróciło mi zdrowie psychiczne
kip2
1
@ kip2 tak, słusznie zauważyłeś, więc zredagowałem odpowiedź, aby to podkreślić, AndreG, proszę zauważyć.
bool.dev
Dzięki za uwagę. Czy byłoby bardziej poprawne, gdybym powiedział: „Po zakończeniu instalacji modułów należy usunąć plik setup.cfg”?
AndreG
25

W systemie OSX (Mac) przy założeniu folderu projektu o nazwie / var / myproject

  1. cd /var/myproject
  2. Utwórz plik o nazwie setup.cfgi dodaj [install] prefix=
  3. Biegać pip install <packagename> -t .
Jerome Anthony
źródło
1
Nie jestem pewien, czym różni się to od odpowiedzi @AndreG
Alastair McCormack
Dla mnie różnica polega na tym, że to rozwiązanie przechodzi do katalogu i -t .zamiast przebywać poza katalogiem . U mnie ten sposób zadziałał, a drugi nie, choć nie mam pojęcia dlaczego.
Chuck Wilbur
12

Innym rozwiązaniem * dla użytkowników Homebrew jest po prostu użycie pliku virtualenv.

Oczywiście może to i tak usunąć potrzebę katalogu docelowego - ale nawet jeśli nie, znalazłem, że --targetdziała domyślnie (jak w, bez tworzenia / modyfikowania pliku konfiguracyjnego) w środowisku wirtualnym.


* Mówię rozwiązanie; może to tylko kolejna motywacja do skrupulatnego stosowania venvów ...

OJFord
źródło
3
Nie mogę uwierzyć, że to było zaledwie miesiąc temu. Po prostu złapałem się na odpowiadaniu na moje własne pytanie; przed czasem ...
OJFord
Tak więc ostatnio miałem problem z pytaniem OP i samo utworzenie wirtualnegoenv rozwiązało problem za mnie. Nadal mogłem zainstalować w katalogu docelowym. Mój problem był dodatkowo skomplikowany, ponieważ zainstalowałem również python3, ale +1 dla rozwiązania virtualenv.
Josh Brown
3

Występują błędy z innymi zaleceniami dookoła --install-option="--prefix=lib". Okazało się, że jedyne, co zadziałało, to używanie w PYTHONUSERBASEsposób opisany tutaj .

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

to nie jest dokładnie to samo, co --target, ale w każdym przypadku działa dla mnie.

Imran Rashid
źródło
2

Jak wspomniano wcześniej, jest to znany błąd występujący w pip & pythonie zainstalowanym z homebrew.

Jeśli utworzysz ~/.pydistutils.cfgplik z instrukcją „pusty prefiks”, rozwiąże to problem, ale spowoduje przerwanie normalnych operacji pip.

Dopóki ten błąd nie zostanie oficjalnie usunięty, jedną z opcji byłoby utworzenie własnego skryptu bash, który będzie obsługiwał ten przypadek:

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

Ten skrypt opakowuje twoje polecenie i:

  1. akceptuje nazwę i parametry docelowe
  2. sprawdza, czy te parametry są puste
  3. tworzy ~/.pydistutils.cfgplik z instrukcją „pusty prefiks”
  4. wykonuje polecenie pip z podanymi parametrami
  5. usuwa ~/.pydistutils.cfgplik

Ten skrypt można zmienić i dostosować do swoich potrzeb, ale masz pomysł. I pozwala na wykonywanie poleceń bez hamowania. Mam nadzieję, że to pomoże :)

vs.
źródło
2

Jeśli używasz virtualenv *, dobrym pomysłem może być dwukrotne sprawdzenie, which pipczy używasz.

Jeśli zauważysz /usr/local/bin/pip, że wydostałeś się ze swojego otoczenia. Ponowna aktywacja virtualenv naprawi ten problem:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Używam virtualfish, ale zakładam, że ta wskazówka dotyczy obu.

Graham P. Heath
źródło
użycie virtualenv było właściwie rozwiązaniem w moim podobnym przypadku :)
chriscatfr
-1

Mam podobny problem. Używam flagi --system, aby uniknąć błędu, tak jak opisuję tutaj w innym wątku, w którym wyjaśniam konkretny przypadek mojej sytuacji. Publikuję to tutaj, spodziewając się, że może to pomóc każdemu, kto ma ten sam problem.

pipelog
źródło