DistutilsOptionError: harus menyediakan awalan atau awalan / exec-awalan - tidak keduanya

144

Saya biasanya menginstal paket python melalui pip.

Untuk Google App Engine, saya perlu menginstal paket ke direktori target lain.

Saya sudah mencoba:

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

tetapi gagal dengan:

harus menyediakan rumah atau awalan / exec-awalan - tidak keduanya

Bagaimana saya bisa membuatnya bekerja?

Arkind
sumber

Jawaban:

289

Apakah Anda menggunakan OS X dan Homebrew? Halaman python Homebrew https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md menyebut masalah yang diketahui dengan pip dan pekerjaan sekitar.

Bekerja untukku.

Anda dapat menjadikan "awalan kosong" ini sebagai default dengan menambahkan file ~ / .pydistutils.cfg dengan konten berikut:

[install]
prefix=

Sunting: Jangan gunakan opsi yang disarankan Homebrew ini, itu akan merusak operasi pip normal .

ayvazj
sumber
5
bagus, tautannya buruk, ini yang baru saya harapkan: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/…
patt0
6
Perhatikan bahwa file itu merusak lingkungan virtual untuk saya.
Dmytro Sadovnychyi
16
Bisnis awalan kosong ini menghentikan pip installoperasi normal :(
Jaap
10
Adakah yang tahu cara mengizinkan --targetsementara tidak merusak pip installperilaku default ?
ryantuck
3
Tampaknya ini tidak berlaku lagi. Tautan rusak dan tautan yang diperbarui tidak berbicara tentang pydistutils.cfg
Lucretiel
164

Saya percaya ada solusi yang lebih sederhana untuk masalah ini (Homebrew's Python on macOS) yang tidak akan merusak operasi pip normal Anda.

Yang harus Anda lakukan adalah membuat setup.cfgfile di direktori root proyek Anda, biasanya di mana __init__.pyfile py utama atau file executable Anda berada. Jadi jika folder root proyek Anda adalah /path/to/my/project/:, buat setup.cfgfile di sana dan masukkan kata-kata ajaib di dalamnya:

[install]
prefix=  

OK, sekarang Anda dapat menjalankan perintah pip untuk folder itu:

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

Perintah ini akan berjalan dengan anggun untuk folder itu saja. Cukup salin setup.cfgke proyek lain apa pun yang mungkin Anda miliki. Tidak perlu menulis .pydistutils.cfgdi direktori home Anda.

Setelah Anda selesai menginstal modul, Anda dapat menghapus setup.cfg .

AndreG
sumber
2
Ini bekerja dengan baik dengan pip3.6 juga. Dan pip saya masih utuh.
Hannibal
10
Ini harus menjadi jawaban yang diterima. Hindari menyebabkan masalah dengan pengaturan pip global.
TrinitronX
10
penekanan pada bagian hapus setup.cfgsetelah instalasi. Saya terbakar melalui 2 hari penuh mencoba mencari tahu mengapa lingkungan virtualenv saya kacau, dengan kesalahan seperti Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Menghapus file setup mengembalikan kewarasan saya
kip2
1
@ kip2 ya benar dicatat oleh Anda, jadi saya telah mengedit jawaban untuk menekankan bahwa sedikit, AndreG harap dicatat.
bool.dev
Terima kasih telah mencatat. Apakah akan lebih benar jika saya berkata "Setelah Anda selesai menginstal modul, Anda harus menghapus setup.cfg"?
AndreG
25

Pada OSX (mac), dengan asumsi folder proyek bernama / var / myproject

  1. cd /var/myproject
  2. Buat file yang dipanggil setup.cfgdan tambahkan [install] prefix=
  3. Lari pip install <packagename> -t .
Jerome Anthony
sumber
1
Saya tidak yakin bagaimana ini berbeda dari jawaban @AndreG
Alastair McCormack
Perbedaannya bagi saya adalah bahwa solusi ini masuk ke dalam direktori dan -t .bukannya tinggal di luar direktori. Cara ini bekerja untuk saya dan yang lainnya tidak, meskipun saya tidak tahu mengapa.
Chuck Wilbur
12

Solusi lain * untuk pengguna Homebrew adalah menggunakan a virtualenv.

Tentu saja, itu mungkin menghapus kebutuhan untuk direktori target - tetapi bahkan jika tidak, saya telah menemukan --targetkarya secara default (seperti pada, tanpa membuat / memodifikasi file konfigurasi) ketika dalam lingkungan virtual.


* Saya katakan solusi; mungkin itu hanya motivasi lain untuk menggunakan vena dengan cermat ...

OJFord
sumber
3
Tidak percaya ini baru sebulan yang lalu. Hanya menangkap diri saya menjawab pertanyaan saya sendiri; sebelumnya ...
OJFord
Jadi, saya baru-baru ini memiliki masalah dalam pertanyaan OP, dan hanya membuat virtualenv memecahkan masalah bagi saya. Saya masih bisa menginstal ke direktori target. Masalah saya juga rumit karena saya menginstal python3 juga, tetapi +1 untuk solusi virtualenv.
Josh Brown
3

Saya menemukan kesalahan dengan rekomendasi lain di sekitar --install-option="--prefix=lib". Satu-satunya hal yang saya temukan yang berfungsi adalah menggunakan PYTHONUSERBASEseperti yang dijelaskan di sini .

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

ini tidak persis sama dengan --target, tetapi itu memang trik untuk saya dalam hal apapun.

Imran Rashid
sumber
2

Seperti disebutkan lainnya, ini dikenal bug dengan pip & python diinstal dengan homebrew.

Jika Anda membuat ~/.pydistutils.cfg file dengan instruksi "kosong awalan" itu akan memperbaiki masalah ini tetapi itu akan merusak operasi pip normal.

Sampai bug ini ditangani secara resmi, salah satu opsi adalah membuat skrip bash Anda sendiri yang akan menangani kasus ini:

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

Script ini membungkus perintah Anda dan:

  1. menerima parameter nama dan target
  2. memeriksa apakah parameter tersebut kosong
  3. menciptakan ~/.pydistutils.cfg file dengan instruksi "kosong awalan" di dalamnya
  4. jalankan perintah pip Anda dengan parameter yang disediakan
  5. menghapus ~/.pydistutils.cfgfile

Script ini dapat diubah dan disesuaikan untuk memenuhi kebutuhan Anda tetapi Anda mendapatkan ide. Dan itu memungkinkan Anda untuk menjalankan perintah Anda tanpa mengerem pip. Semoga bermanfaat :)

vs.
sumber
2

Jika Anda menggunakan virtualenv *, mungkin ide yang baik untuk memeriksa ulang apakah which pipAnda menggunakan.

Jika Anda melihat sesuatu seperti /usr/local/bin/pipAnda keluar dari lingkungan Anda. Mengaktifkan kembali virtualenv Anda akan memperbaikinya:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Saya menggunakan virtualfish, tetapi saya menganggap tip ini relevan untuk keduanya.

Graham P Heath
sumber
menggunakan virtualenv sebenarnya adalah solusi dalam kasus serupa saya :)
chriscatfr
-1

Saya memiliki masalah serupa. Saya menggunakan flag --system untuk menghindari kesalahan saat saya mendekripsi di sini di utas lain tempat saya menjelaskan kasus spesifik dari situasi saya. Saya posting ini di sini mengharapkan yang dapat membantu siapa pun menghadapi masalah yang sama

pipelog
sumber