DistutilsOptionError: phải cung cấp tiền nhà hoặc tiền tố / exec-prefix - không phải cả hai


144

Tôi thường được cài đặt các gói python thông qua pip.

Đối với Google App Engine, tôi cần cài đặt các gói vào thư mục đích khác.

Tôi đã thử:

cài đặt pip -I bình-restful --target ./lib

nhưng nó thất bại với:

phải cung cấp tiền nhà hoặc tiền tố / exec-prefix - không phải cả hai

Làm thế nào tôi có thể làm điều này để làm việc?

Câu trả lời:


289

Bạn đang sử dụng OS X và Homebrew? Trang python Homebrew https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md gọi ra một vấn đề đã biết với pip và một công việc xung quanh.

Đã làm cho tôi.

Bạn có thể đặt "tiền tố trống" này làm mặc định bằng cách thêm tệp ~ / .pydistutils.cfg với nội dung sau:

[install]
prefix=

Chỉnh sửa: Không sử dụng tùy chọn được đề nghị Homebrew này, nó sẽ phá vỡ các hoạt động pip bình thường .


5
thứ tốt, liên kết là xấu, đây là cái mới tôi mong đợi: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/...
patt0

6
Lưu ý rằng tập tin đó đã phá vỡ môi trường ảo cho tôi.
Dmytro Sadovnychyi

16
Doanh nghiệp tiền tố trống này phá vỡ các pip installhoạt động bình thường :(
Jaap

10
có ai tìm ra cách cho phép --targettrong khi không phá hỏng pip installhành vi mặc định không?
ryantuck

3
Điều này dường như không còn hiệu lực nữa. Liên kết bị hỏng và liên kết được cập nhật không nói về pydistutils.cfg
Lucretiel

164

Tôi tin rằng có một giải pháp đơn giản hơn cho vấn đề này (Homebrew's Python trên macOS) sẽ không phá vỡ các hoạt động đường ống thông thường của bạn.

Tất cả bạn phải làm là tạo một setup.cfgtệp tại thư mục gốc của dự án của bạn, thường là nơi __init__.pytệp py chính hoặc thực thi của bạn . Vì vậy, nếu thư mục gốc của dự án của bạn là : /path/to/my/project/, hãy tạo một setup.cfgtệp trong đó và đặt các từ ma thuật vào bên trong:

[install]
prefix=  

OK, bây giờ bạn có thể chạy các lệnh của pip cho thư mục đó:

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

Lệnh này sẽ chỉ chạy một cách duyên dáng cho thư mục đó. Chỉ cần sao chép setup.cfgvào bất kỳ dự án nào khác mà bạn có thể có. Không cần phải viết một .pydistutils.cfgtrên thư mục nhà của bạn.

Sau khi bạn hoàn tất cài đặt các mô-đun, bạn có thể loại bỏ setup.cfg .


2
Điều này làm việc hoàn hảo với pip3.6 là tốt. Và pip của tôi vẫn còn nguyên.
Hannibal

10
Đây phải là câu trả lời được chấp nhận. Tránh gây ra sự cố với cài đặt pip toàn cầu.
TrinitronX

10
nhấn mạnh vào phần gỡ bỏ setup.cfgsau khi cài đặt. Tôi đã đốt cháy suốt 2 ngày cố gắng tìm hiểu tại sao môi trường virtualenv của tôi bị hỏng, với các lỗi như thế Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Xóa tệp cài đặt đã khôi phục sự tỉnh táo của tôi
kip2

1
@ kip2 có bạn lưu ý đúng, vì vậy tôi đã chỉnh sửa câu trả lời để nhấn mạnh bit đó, AndreG xin lưu ý.
bool.dev

Cảm ơn đã lưu ý. Sẽ đúng hơn nếu tôi nói "Sau khi cài đặt xong các mô-đun, bạn nên xóa setup.cfg"?
AndreG

25

Trên OSX (mac), giả sử một thư mục dự án có tên / var / myproject

  1. cd /var/myproject
  2. Tạo một tệp được gọi setup.cfgvà thêm [install] prefix=
  3. Chạy pip install <packagename> -t .

1
Tôi không chắc nó khác với câu trả lời của @AndreG
Alastair McCormack

Sự khác biệt đối với tôi là giải pháp này cd vào thư mục và -t .thay vì ở ngoài thư mục. Cách này hiệu quả với tôi và cách khác thì không, mặc dù tôi không biết tại sao.
Chuck Wilbur

12

Một giải pháp khác * cho người dùng Homebrew chỉ đơn giản là sử dụng a virtualenv.

Tất nhiên, điều đó có thể loại bỏ sự cần thiết của thư mục đích - nhưng ngay cả khi không, tôi đã tìm thấy --targethoạt động theo mặc định (như trong, mà không tạo / sửa đổi tệp cấu hình) khi ở trong môi trường ảo.


* Tôi nói giải pháp; có lẽ đó chỉ là một động lực khác để sử dụng venvs một cách tỉ mỉ ...


3
Không thể tin được đây chỉ là một tháng trước. Chỉ cần bắt bản thân mình trả lời câu hỏi của riêng tôi; trước thời hạn ...
OJFord

Vì vậy, gần đây tôi có vấn đề trong câu hỏi của OP và chỉ việc tạo một virtualenv đã giải quyết vấn đề cho tôi. Tôi vẫn có thể cài đặt vào thư mục đích. Vấn đề của tôi cũng rất phức tạp vì tôi cũng đã cài đặt python3, nhưng +1 cho giải pháp virtualenv.
Josh Brown

3

Tôi gặp lỗi với các khuyến nghị khác xung quanh --install-option="--prefix=lib". Điều duy nhất tôi thấy rằng làm việc là sử dụng PYTHONUSERBASEnhư được mô tả ở đây .

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

Điều này không hoàn toàn giống như --target, nhưng nó thực sự là mánh khóe đối với tôi trong mọi trường hợp.


2

Như đã đề cập khác, đây là lỗi đã biết với pip & python được cài đặt với homebrew.

Nếu bạn tạo ~/.pydistutils.cfgtập tin với hướng dẫn "tiền tố trống", nó sẽ khắc phục vấn đề này nhưng nó sẽ phá vỡ các hoạt động pip bình thường.

Cho đến khi lỗi này được xử lý chính thức, một trong các tùy chọn sẽ là tạo tập lệnh bash của riêng bạn để xử lý trường hợp này:

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

Kịch bản lệnh này kết thúc lệnh của bạn và:

  1. chấp nhận tên và tham số đích
  2. kiểm tra xem các tham số đó có trống không
  3. tạo ~/.pydistutils.cfgtập tin với hướng dẫn "tiền tố trống" trong đó
  4. thực thi lệnh pip của bạn với các tham số được cung cấp
  5. xóa ~/.pydistutils.cfgtập tin

Kịch bản này có thể được thay đổi và điều chỉnh để đáp ứng nhu cầu của bạn nhưng bạn có ý tưởng. Và nó cho phép bạn chạy lệnh của bạn mà không cần phanh pip. Hy vọng nó giúp :)


2

Nếu bạn đang sử dụng virtualenv *, có thể nên kiểm tra kỹ which pipbạn đang sử dụng.

Nếu bạn thấy một cái gì đó giống như /usr/local/bin/pipbạn đã thoát ra khỏi môi trường của bạn. Kích hoạt lại virtualenv của bạn sẽ khắc phục điều này:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Tôi sử dụng cá ảo, nhưng tôi cho rằng mẹo này có liên quan đến cả hai.


sử dụng virtualenv thực sự là giải pháp trong trường hợp tương tự của tôi :)
chriscatfr

-1

Tôi có một vấn đề tương tự. Tôi sử dụng cờ --system để tránh lỗi khi tôi giải mã ở đây trên luồng khác, nơi tôi giải thích trường hợp cụ thể của tình huống của mình. Tôi đăng bài này ở đây với hy vọng có thể giúp bất cứ ai gặp phải vấn đề tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.