DistutilsOptionError: должен указывать либо home, либо prefix / exec-prefix, но не оба

144

Я обычно устанавливал пакеты Python через pip.

Для Google App Engine мне нужно установить пакеты в другой целевой каталог.

Я пробовал:

pip install -I Фляга-отдыхать --target ./lib

но это не с:

должен предоставить либо home, либо prefix / exec-prefix - не оба

Как я могу заставить это работать?

Arkind
источник

Ответы:

289

Вы используете OS X и Homebrew? Страница Python Homebrew https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md выявляет известную проблему с pip и обходным путем.

Работал на меня.

Вы можете сделать этот «пустой префикс» значением по умолчанию, добавив файл ~ / .pydistutils.cfg со следующим содержимым:

[install]
prefix=

Редактировать: не используйте этот вариант, рекомендуемый Homebrew, он нарушит нормальные операции в пунктах .

ayvazj
источник
5
Хорошие вещи, ссылка плохая, это новая, которую я ожидаю: github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/…
patt0
6
Обратите внимание, что этот файл сломал виртуальную среду для меня.
Дмитрий Садовничий,
16
Этот пустой префикс бизнес нарушает обычные pip installоперации :(
Jaap
10
кто-нибудь разобрался, как разрешить --target, не нарушая при этом pip installповедение по умолчанию ?
ryantuck
3
Похоже, это больше не действует. Ссылка не работает, и обновленная ссылка не говорит о pydistutils.cfg
Lucretiel
164

Я полагаю, что есть более простое решение этой проблемы (Python Homebrew на macOS), которое не нарушит ваши обычные операции с пипсами.

Все, что вам нужно сделать, это создать setup.cfgфайл в корневом каталоге вашего проекта, обычно там, где находится ваш основной __init__.pyили исполняемый файл py. Поэтому, если корневая папка вашего проекта:, /path/to/my/project/создайте там setup.cfgфайл и поместите в него волшебные слова:

[install]
prefix=  

Хорошо, теперь вы можете запускать команды pip для этой папки:

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

Эта команда будет выполняться изящно только для этой папки. Просто скопируйте setup.cfgв любые другие проекты, которые у вас могут быть. Нет необходимости писать в .pydistutils.cfgвашем домашнем каталоге.

После того, как вы закончите установку модулей, вы можете удалить setup.cfg .

AndreG
источник
2
Это прекрасно работало и с pip3.6. И мой пункт все еще не поврежден.
Ганнибал
10
Это должен быть принятый ответ. Позволяет избежать проблем с глобальными настройками пипса.
TrinitronX
10
акцент на удаление setup.cfgпосле установки части. Я прожегал целых два дня, пытаясь понять, почему моя виртуальная среда была испорчена, с ошибками вроде Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/easy_install'. Удаление установочного файла восстановило мое здравомыслие
kip2
1
@ kip2 да, правильно заметили вы, поэтому я отредактировал ответ, чтобы подчеркнуть это, AndreG, пожалуйста, обратите внимание.
bool.dev
Спасибо, что заметили. Было бы правильнее, если бы я сказал: «После того, как вы закончите установку модулей, вы должны удалить setup.cfg»?
AndreG
25

В OSX (Mac), предполагая, что папка проекта называется / var / myproject

  1. cd /var/myproject
  2. Создайте файл с именем setup.cfgи добавьте [install] prefix=
  3. Бегать pip install <packagename> -t .
Джером Энтони
источник
1
Я не уверен, чем это отличается от ответа @AndreG
Аластер МакКормак
Разница для меня заключается в том, что это решение попадает в каталог и делает -t .вместо того, чтобы оставаться вне каталога . Этот способ работал для меня, а другой нет, хотя я понятия не имею, почему.
Чак Уилбур
12

Другое решение * для пользователей Homebrew - просто использовать virtualenv.

Конечно, это может устранить необходимость в целевом каталоге в любом случае - но даже если это не так, я нашел --targetработы по умолчанию (например, без создания / изменения файла конфигурации) в виртуальной среде.


Я говорю решение; возможно, это просто еще одна мотивация тщательно использовать венв ...

OJFord
источник
3
Не могу поверить, что это было только месяц назад. Просто поймал себя на том, что отвечаю на свой вопрос; впереди времени ...
OJFord
Итак, недавно у меня возникла проблема в вопросе OP, и простое создание virtualenv решило эту проблему для меня. Я все еще могу установить в целевой каталог. Моя проблема была еще более сложной, потому что я также установил python3, но +1 для решения virtualenv.
Джош Браун
3

Я столкнулся с ошибками с другими рекомендациями вокруг --install-option="--prefix=lib". Единственное, что я обнаружил, это работает, используя PYTHONUSERBASEкак описано здесь .

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

это не совсем то же самое --target, но в любом случае это помогает мне.

Имран Рашид
источник
2

Как уже упоминалось, это известная ошибка при установке pip & python вместе с homebrew.

Если вы создадите ~/.pydistutils.cfgфайл с инструкцией «empty prefix», это решит эту проблему, но нарушит нормальные операции в pip.

До тех пор, пока эта ошибка не будет официально устранена, одним из вариантов будет создание собственного bash-скрипта, который бы обрабатывал этот случай:

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

Этот скрипт оборачивает вашу команду и:

  1. принимает имя и целевые параметры
  2. проверяет, являются ли эти параметры пустыми
  3. создает ~/.pydistutils.cfgфайл с инструкцией «пустой префикс»
  4. выполняет команду pip с указанными параметрами
  5. удаляет ~/.pydistutils.cfgфайл

Этот сценарий может быть изменен и адаптирован к вашим потребностям, но у вас есть идея. И это позволяет вам запускать команду без торможения. Надеюсь, поможет :)

против
источник
2

Если вы используете virtualenv *, было бы неплохо проверить, which pipчто вы используете.

Если вы видите что-то вроде /usr/local/bin/pipтого, что вырвались из своего окружения. Реактивация вашего virtualenv исправит это:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: Я использую virtualfish, но я полагаю, что этот совет относится к обоим.

Грэм П Хит
источник
использование virtualenv на самом деле было решением в моем аналогичном случае :)
chriscatfr
-1

У меня похожая проблема. Я использую флаг --system, чтобы избежать ошибки, поскольку я описываю здесь другой поток, где я объясняю конкретный случай моей ситуации. Я публикую это здесь, ожидая, что это может помочь любому, кто сталкивается с той же проблемой.

pipelog
источник