DistutilsOptionError: повинен подавати або домашній, або префікс / exec-префікс - не обидва


144

Мені зазвичай встановлювали пакети python через pip.

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

Я спробував:

pip install - Я колба-спокійний --target ./lib

але це не вдається:

повинен постачати або домашній, або префікс / exec-префікс - не обидва

Як я можу змусити це працювати?

Відповіді:


289

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

Працювали для мене.

Ви можете зробити цей "порожній префікс" за замовчуванням, додавши файл ~ / .pydistutils.cfg з таким вмістом:

[install]
prefix=

Редагувати: Не використовуйте цю рекомендовану опцію Homebrew, вона порушить звичайні операції з піп .


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

Я вважаю, що існує більш просте рішення цієї проблеми (Homebrew's Python на 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 .


2
Це чудово працювало і з pip3.6. І мій піп все ще недоторканий.
Ганнібал

10
Це має бути прийнятою відповіддю. Уникайте виникнення проблем із глобальними налаштуваннями протоколів.
TrinitronX

10
акцент на видалення setup.cfgпісля установки деталі. Я горів через 2 цілих дні, намагаючись з'ясувати, чому моє середовище virtualenv було накручено, з такими помилками 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
Alastair McCormack

Для мене різниця полягає в тому, що це рішення входить у каталог і -t .замість того, щоб залишатися поза dir. Цей спосіб спрацював для мене, а інший - ні, хоча я поняття не маю, чому.
Чак Вільбур

12

Ще одне рішення * для користувачів Homebrew - це просто використовувати virtualenv.

Звичайно, це може усунути потребу в цільовому каталозі - але навіть якщо цього не відбувається, я знайшов --targetроботи за замовчуванням (як у, без створення / зміни конфігураційного файлу), коли у віртуальному середовищі.


* Я кажу рішення; можливо, це просто ще одна мотивація прискіпливо використовувати вентилятори ...


3
Не вірю, що це було лише місяць тому. Щойно зловив себе, відповідаючи на власне запитання; достроково ...
OJFord

Отже, у мене нещодавно виникла проблема в питанні ОП, і просто створення віртуаленв вирішило для мене питання. Я все ще міг встановити в цільовий каталог. Моя проблема була додатково складною, бо я також встановив python3, але +1 для рішення virtualenv.
Джош Браун

3

Я потрапляю на помилки з іншими рекомендаціями навколо --install-option="--prefix=lib". Єдине, що я виявив, що працював - це використання, PYTHONUSERBASEяк описано тут .

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

це не точно так само, як --target, але це робить трюк для мене в будь-якому випадку.


2

Як вже згадувалося, це відома помилка з pip & python, встановленою з домашньою мовою.

Якщо ви створите ~/.pydistutils.cfgфайл з інструкцією "порожній префікс", він вирішить цю проблему, але вона порушить звичайні операції з піп.

Поки ця помилка не буде офіційно вирішена, одним із варіантів буде створення власного скрипту 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 прапор , щоб уникнути помилок , як я , опишіть тут на іншому потоці , де я пояснити конкретний випадок моєї ситуації. Я публікую це тут, очікуючи, що це може допомогти кожному, хто стикається з тією ж проблемою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.