Pip: По умолчанию --user

Созданный на 21 мар. 2014  ·  170Комментарии  ·  Источник: pypa/pip

Когда pip установлен в системе с установленной ОС Python, в настоящее время возникает проблема, когда pip install foo выдает ошибку, поскольку у него нет прав доступа к файлам. Это заставляет людей вместо этого запускать sudo pip install foo , который глобально устанавливает Python в систему. Это создает проблему, когда люди используют pip для управления пакетами системного уровня, когда им, вероятно, следует использовать диспетчер системных пакетов.

Итак, мое намерение состоит в том, чтобы pip по умолчанию был равен --user, однако с этим есть несколько проблем:

  • Как это взаимодействует с Windows? Есть ли в этом смысл?
  • Как это взаимодействует с altinstall'd Pythons? Особенно такие, которые устанавливаются с такими инструментами, как https://github.com/yyuu/pyenv
  • Что мы делаем, когда люди вызывают pip от имени пользователя root? Установка в /root/.local/ не кажется очень полезной.
  • Что это означает для get-pip и инструкции по установке pypa ?
  • ~/.local/bin не находится в $PATH у многих людей, можно ли что-нибудь с этим сделать?
  • Пакеты --user install не имеют приоритета перед глобальными пакетами easy_install 'd, что может быть довольно неожиданным.

Здесь есть ряд актуальных вопросов: #624 #1443 #1153 #1500 #1051

/cc @ncoghlan

user scheme auto-locked enhancement

Самый полезный комментарий

Ночью мне снилось, что опция --user становится по умолчанию (не шучу), есть ли шанс, что мои мечты сбудутся в ближайшее время?

Все 170 Комментарий

Что это значит для инструкций по установке pypa?

в настоящее время упоминание о доступе root или администратора находится в сноске, поэтому инструкции в основном останутся прежними (при условии, что get-pip также автоматически устанавливается по умолчанию на --user ). изменение будет состоять в том, чтобы объяснить, что в конечном итоге они получат установки, которые применимы только к их текущему пользователю.

независимо от изменения --user , текущие инструкции должны объяснять, что некоторые дистрибутивы, такие как debian, отключают surepip, поэтому им не следует искать его как способ получить pip.

В долгосрочной перспективе я почти уверен, что они оставят его включенным, они просто выясняют, как это сделать.

хотя эта проблема описывается как связанная с тем, где pip должен управлять пакетами по умолчанию, почти более важным (по крайней мере для меня) является то, что это косвенно касается того, где get-pip будет размещать pip по умолчанию.

Как это взаимодействует с altinstall'd Pythons?
Особенно такие, которые устанавливаются с такими инструментами, как https://github.com/yyuu/pyenv

пользовательская схема .local/lib/pythonX.Y/site-packages , поэтому, если вы управляете несколькими питонами с одной и той же основной/младшей версией, я думаю, вы можете столкнуться с беспорядком.

для таких инструментов, которые управляют настоящими питонами, привязка pip к глобальному режиму имела бы смысл.

Актуальная проблема в системе отслеживания ошибок redhat/fedora https://bugzilla.redhat.com/show_bug.cgi?id=662034#c10

Похоже, что для Fedora/RedHat PATH=$PATH:$HOME/.local/bin:$HOME/bin уже находится в их /etc/skel/.bash_profile . Это заставит вещи, установленные с --user , по-прежнему отображаться по умолчанию, по крайней мере, для пользователей bash (оболочка по умолчанию). Может быть, в других дистрибутивах это уже есть?

Насколько я знаю, в Windows нет ничего особенного. Но мы только что добавили стандартный каталог Python в PATH людей, я не ожидаю, что получить каталог скриптов для каждого пользователя будет особенно легко - и могут быть технические трудности, я не уверен помещение переменной среды пользовательского уровня, такой как %LOCALAPPDATA% , в системный уровень %PATH% даже работает :-(

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

Кроме того, с моей шляпой Windows, я должен сказать, что усложнение для пользователей Unix, которые еще не поняли, что небрежное использование sudo плохо для глупых вещей, на самом деле не такое уж хорошее оправдание. .

Я предполагаю, что это будет применяться только при запуске pip из системного Python.

Другое дело, что в Windows нет системы, предоставляемой Python, как в * nix, которая также поставляется с пакетами Python, предоставляемыми системой :)

Я тоже особо не тороплюсь. Я просто хотел начать дискуссию.

На самом деле это не влияет на людей, которые набирают sudo pip install , поскольку я думаю, что установка чего-либо с правами root все равно должна по умолчанию переходить к системным пакетам сайта. Это должно помочь людям использовать --user при работе в качестве непривилегированного пользователя. Прямо сейчас вы получаете, что pip install как обычный пользователь просто вылетает с ошибкой разрешения. Даже если мы улучшим это сообщение и предложим --user , это все равно не лучший UX.

В разговоре с одним из разработчиков Fedora я подумал, что это можно сделать, внедрив проверку разрешений. Если у меня есть разрешение на запись в каталог site-packages, то я являюсь привилегированным пользователем, и pip устанавливается на глобальный Python. Если у меня нет, то я непривилегированный пользователь, и он устанавливается в --user .

Что касается Windows, мы обычно избегаем проблемы, потому что по умолчанию устанавливаем Python в непривилегированный каталог, поэтому pip не запускает UAC при глобальной установке. Если кто-то изменит это, чтобы вместо этого установить в Program Files, тогда UAC сработает при запуске pip (что также нормально). Я не уверен, что произойдет, если они выберут установку для каждого пользователя в программе установки.

Как отмечает Пол, PATH в Windows еще не включает каталог _user_scripts (только глобальный), так что это определенно стоит принять во внимание.

Однако я не вижу каких-либо серьезных препятствий на стороне POSIX. Как звучит эта идея UX: для установки с помощью колеса проверьте наличие разрешений в целевом каталоге установки, и, если у пользователя нет прав на запись, выведите запрос, спрашивающий, не хотят ли они вместо этого выполнить установку --user? Новый флаг "--global" или "--system" заставит ответить "нет".

И затем в какой-то момент в будущем мы могли бы пропустить приглашение и просто предположить --user, если разрешения не подходят для глобальной установки.

Подсказка (кроме случая --no-input), вероятно, имеет смысл для шага перехода. Я думаю, что проверка разрешений должна заставить все работать и для Windows, поскольку по умолчанию местоположение находится в месте, где у людей есть разрешения, и поэтому единственный раз, когда они нажмут это, будет, если они используют Python, предоставленный системным администратором, который явно не т дать им разрешение.

По сути, это делает наш режим отказа намного лучше.

усложняет задачу для пользователей Unix, которые еще не освоили небрежное использование sudo
плохо делать глупости, неужели это не очень хорошее оправдание..

sudo , а безопасность на самом деле является второстепенной проблемой IMO.
в первую очередь речь идет о предотвращении конфликта между упаковкой ОС и pip в системном питоне.
В настоящее время пользователи Linux часто оказываются в безвыходной ситуации.

  1. Мандат ОС: «Использовать команду OS pkg mgr; Не заражайте свою систему пакетами, установленными roque pip (включая get-pip 'd pip)'
  2. Реальность: «Пакеты ОС (включая pip) слишком старые, и я не могу перейти на экспериментальную версию дистрибутива, просто чтобы получить обновления какого-то пакета. Я собираюсь мошенничать…».

еще один маленький шаг — задокументировать (при условии, что мы его протестируем), что вы можете get-pip.py --user , и попросить PUG упомянуть --user как возможность для установки virtualenvwheel и twine тоже, если не в виртуалке)

FWIW, поставщики дистрибутивов также считают статус-кво проблемой и ищут различные способы улучшить инструменты для выборочного обновления, не затрагивая основные компоненты ОС. Тем не менее, нам стоит заняться со стороны восходящего потока, поскольку эти усилия находятся на разных стадиях зрелости, и нам нужно согласованное кросс-платформенное решение для конечных пользователей.

У меня нет проблем с внесением изменений для облегчения взаимодействия с дистрибутивами Unix; если допустимо значение по умолчанию --user в Unix, а не в Windows, меня это устраивает. Я просто не считаю переход от плохого опыта в Unix к плохому опыту в Windows хорошим компромиссом. И я еще не уверен, что --user на Windows готов к работе в прайм-тайм.

Обратите внимание, что запуск UAC при запуске pip _плохо_ в Windows, потому что на самом деле это означает, что pip не будет работать, кроме как в окне консоли с повышенными привилегиями. Это не означает, что пользователи pip получают приятное приглашение, на которое они могут сказать «ОК», к сожалению, это только то, как работают приложения с графическим интерфейсом...

@pfmoore Каким, по вашему мнению, должен быть пользовательский интерфейс Windows, когда вы что-то pip install и у вас нет прав на запись в каталог?

FWIW Я полностью согласен с тем, чтобы сделать это необязательным в зависимости от Windows или нет. Мне просто интересно, не будет ли проверка «Есть ли у меня разрешения на запись в папку пакетов сайтов» не достигнет этого в любом случае в 99% установок, и если установка на --user будет лучше в часть случаев, когда у вас нет прав на запись в каталог site-packages.

Другими словами, если мы проверяем разрешения, предложение не заменяет глобальную установку пользовательской установкой, а заменяет ошибку разрешения установкой --user .

предложение не заменяет глобальную установку пользовательской установкой
он заменяет ошибку разрешения на --user install

хорошо, но помните, что идея с проверкой разрешений (#1048) будет не самой простой

Это будет довольно легко в случае с Wheel, и мы можем покрыть случай 99,9% с помощью sdists, это должно быть проблемой только в setup.py, которые делают действительно прикольные вещи.

Как вы думаете, каким должен быть пользовательский интерфейс Windows, когда вы что-то устанавливаете, но у вас нет прав на запись в каталог?

Что ж, возможность записи в каталог site-packages настолько редка в Windows, что я не уверен, насколько актуален этот вопрос на практике. Но если бы это произошло, я бы сказал, что ошибка о том, что «системные сайт-пакеты не доступны для записи - вы имели в виду использовать --user ?» будет разумным подходом.

На самом деле, я думаю, что это было бы лучше и для Unix. Переключение поведения в зависимости от возможности записи является странным, и мне не ясно, является ли использование --user для собственноручно созданного Python в доступном для записи каталоге правильным подходом (но у меня совершенно нулевой опыт такой настройки, поэтому У меня нет ничего, чтобы поддержать это мнение).

Предложение: начните с ошибки, предлагающей --user , как указано выше. Как только люди начнут использовать --user чаще, а у нас будет больше опыта, давайте подумаем об изменении значения по умолчанию.

Подход, который предлагает Пол, примерно соответствует тому, что я имел в виду, но с подсказкой «да/нет», а не с сообщением об ошибке. У этих двух подходов есть свои плюсы и минусы (в основном связанные с тем, как они терпят неудачу при вызове из другого скрипта).

Можно ли добавить в Python что-то вроде sys.localprefix (здесь я вижу python-dev)?
Sys.localprefix по умолчанию будет sys.prefix. Дистрибутивы могут определять его так же, как они определяют префикс (например, префикс = '/usr', локальный префикс = '/usr/local'). Pip и easy_install будут использовать sys.localprefix в качестве места для установки, если они используются как sudo, если у них нет достаточных прав, вернуться к --user.

Мы сделали что-то подобное с «gem install» в Fedora 17, и разработчики Ruby в целом были очень довольны этим, поэтому я решил поделиться:

  • "gem install foo" устанавливает "foo" в ~/somedir, если uid != 0
  • "gem install foo" устанавливает "foo" в /usr/local/somedir, если uid == 0
  • "yum install rubygem-foo" устанавливает RPM-упаковку "foo" в /usr/somedir

Я думаю, что выбор установочного каталога на основе привилегий пользователя может сбить людей с толку; «pip install foo» должен работать одинаково для всех пользователей без полномочий root. Если учесть большинство пользователей, они захотят установить «pip install» в свой дом и «sudo pip install» в общесистемный каталог. Поэтому я думаю, что это лучший способ сделать это на основе uid, как показано выше, и для тех пользователей, которые не являются root, но хотят установить в общесистемный каталог, всегда есть опция --target.

@bkabrda это простой выбор, если вы не беспокоитесь о добавлении скриптов в $ PATH. Что ты там сделал?

@Ivoz , как заметил @dstufft , в Fedora уже есть $HOME/.local/bin в PATH, так что все работало из коробки (кстати, о скриптах).

Предложение Славека звучит хорошо для систем POSIX. Он также должен хорошо работать с контейнерами, поскольку можно заставить вещи, работающие в контейнере, думать, что это uid 0, даже если это что-то совершенно другое, находящееся вне контейнера.

Для Windows я менее уверен, какой правильный ответ. У нас нет той же проблемы, связанной с спором с системным менеджером пакетов, хотя он в некоторой степени существует (установка pip против установщиков MSI) и имеет дополнительную сложность, заключающуюся в том, что даже в Python 3.4 необязательный PATH установщика модификации добавляют только глобальный каталог Scripts, а не каталог для каждого пользователя.

У Windows также есть странности, связанные с тем, установлен ли Python в папку по умолчанию (неконтролируемо) или в Program Files (для внесения изменений требуется повышение привилегий UAC).

Идея «localprefix», предложенная @rkuska , кажется мне красивой, простой и легкой. Также мне очень нравится подход, который предлагает @bkabrda , особенно для таких дистрибутивов, как Arch, которые делают python 3.x python по умолчанию.

Еще одно замечание: в версии 3.4.0 Arch отключил обеспечение pip, как и в Debian (в основном потому, что мы хотим предоставлять последние версии setuptools и pip, в то время как версии в комплекте могут быть устаревшими на века), поэтому было бы неплохо иметь подсказка для него.

@lvoz
Для Arch мы не добавляли никаких путей из $HOME в PATH, но я думаю, что это нормально. У нас уже есть вики-запись для Ruby , которая предлагает пользователю добавить ее.

Было бы неплохо, если бы разработчики Arch и Debian не просто отключали его, а помогали Славеку работать над его патчем, чтобы гарантировать восстановление колеса из системных версий и установку его в виртуальные среды.

К вашему сведению, у нас уже есть работающие RPM-сборки Python 3.4 в системе сборки Fedora Copr (тестирование, не рекомендуется их устанавливать, если вы не хотите ничего сломать). Если вы хотите узнать больше о том, как мы к этому подходим, взглянуть на код и т. д., см. мою дискуссию с Барри Варшавой [2] на debian-python ML.
(Наши патчи все еще нуждаются в некоторой любви, прежде чем мы предложим их вышестоящим, но все работает нормально для нас нижестоящих ATM)

[1] http://copr-fe.cloud.fedoraproject.org/coprs/bkabrda/python-3.4/
[2] https://lists.debian.org/debian-python/2014/03/msg00046.html

Извините, но AFAIK Arch никогда не поддерживал колесо, и мы не хотим, чтобы makepip вызывал диспетчер пакетов (хотя поправьте меня, если я неправильно понимаю этот подход).

Что касается обеспечения, было бы неплохо предупредить пользователя не устанавливать pip с помощью обеспечения, и это все, что я могу придумать на данный момент.

Наш surepip никогда не будет вызывать менеджер пакетов. Короче говоря, surepip Fedora будет полагаться на системные пакеты setuptools и pip, которые будут всегда присутствовать (наш пакет python3 будет зависеть от них, что создаст цикл зависимости, но мы можем справиться с этим), и когда пользователь создаст новый virtualenv, он будет переупаковывать system setuptools и pip в колеса и установите их в новый файл virtualenv.
Мы начинаем немного отходить от темы, так что, я думаю, нам следует продолжить обсуждение в другом месте...

@felixonmars Означает ли это, что в Arch venv не работает так же, как и в Debian?

Хорошо, спасибо за объяснение, я думаю, что понял идею. Я посмотрю, что я могу сделать, и продолжу работу над debian-python для этого.

@dstufft Да, комплектная версия была установлена ​​вместо системной версии.

@bkabrda Итак, это решает проблему, если вы вызываете pip с системным Python, в этом случае нам нужен особый случай virtualenv / venv (что не является концом света). Но это также означает, что мы предполагаем, что все Python являются системными Python, даже те, которые установлены пользователем в свой домашний каталог, например, с https://github.com/yyuu/pyenv (именно так я запускаю Python). Так что я не уверен, поэтому я подумал о проверке разрешения.

то же самое, что сказал @dstufft , при использовании такого инструмента, как pyenv , для манипулирования некорневыми питонами, было бы довольно странно, чтобы root был ключом для глобальной установки (где «глобальный» != "система")

Мы сделали что-то подобное с «gem install» в Fedora 17.

Вы имеете в виду, что rpm gem для Fedora 17 имеет это как взлом дистрибутива? Или у самого gem есть такая логика?

одна мысль состоит в том, что pip должен обеспечивать «дружественный к системе режим», который может быть включен дистрибутивами, которые упаковывают pip, или когда пользователи знают, что они сами устанавливают pip в управляемый системой python. в противном случае pip выполняет обычную глобальную логику по умолчанию.

А , @felixonmars, я только что видел https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/python , если все, что вы делаете, это вызывать --without-ensurepip , это нормально . Это оставляет модуль обеспечения безопасности нетронутым для модуля venv. Патчи Ubuntu (Debian?), которые в настоящее время установлены, фактически вызывают rm -rf в самом пакете surepip, что делает его недоступным для вызова в venv.

Я думаю, что установка по умолчанию для пользовательских установок была предложена Ником два года назад или, может быть, кем-то еще раньше, но обсуждение разошлось по многим направлениям и не принесло результатов. Основным препятствием была обратная совместимость IIRC, но в наши дни системные администраторы и пользователи pip могут быть более осторожными с обновлениями virtualenv/pip/setuptools, к лучшему или к худшему. Я не помню, происходило ли это обсуждение на distutils-sig или pypa-dev.

@dstufft О, понятно ... Но я все еще чувствую себя неловко, когда у меня установлена ​​пакетная (возможно, старая) версия, в то время как пакеты установлены системно :)

@felixonmars проблема в том, что вы не можете установить системный пакет в виртуальную среду на самом деле :) (И даже если бы вы могли, существуют разные проблемы с тем, что вы хотите в системном пакете, и внутри виртуальной среды)

@dstufft Вот тут и начинается перемотка Славека, но это немного не по теме :)

Да, проверьте последнюю часть https://lists.fedoraproject.org/pipermail/python-devel/2014-March/000583.html :(

@dstufft Спасибо!

Не уверен, стоит ли мне продолжать дискуссию, потому что это не должно быть проблемой, так как мы не развязывали pip в Arch, а rewheel должен генерировать пригодный для использования Wheel :)

@dstufft вы правы в том, что нам, вероятно, понадобится особый регистр virtualenv и, возможно, даже pyenv, что кажется уродливым. Я должен признать, что я не очень хорошо знаком с pyenv, поэтому я не могу придумать никакого «правильного» решения для этого прямо сейчас. Я постараюсь рассмотреть его поближе и что-нибудь придумать.

@qwcode для «установки драгоценного камня» в Fedora, это дополнительный патч. TBH Я долго не прикасался к Rubygems Fedora, но в последний раз, когда я проверял, это было только вниз по течению.

Я разместил ссылку на эту проблему на связанную ошибку в python [1]. Я хотел бы перенести это обсуждение на ядро ​​​​python, чтобы иметь настраиваемое местоположение для локальных установок не только pip , но также easy_install и python setup.py install после того, как этот пункт может использовать ( например) каталог sys.localprefix, если uid==0 , и установить в каталог пользователя, если uid!=0 , как упоминалось @bkabrda .

В настоящее время я в порядке с установкой pip в пользовательский каталог по умолчанию.

[1] http://bugs.python.org/issue1298835

Как заметил Ник, я перенес обсуждение с issue1298835 на pypa-dev [1].
[1] https://groups.google.com/forum/#!topic/pypa-dev/r6qsAmJl9t0

По умолчанию --user

Хорошая идея!

pip install foo выдаст ошибку, потому что у него нет прав доступа к файлам. Это заставляет людей вместо этого запускать sudo pip install foo , который глобально устанавливает в систему Python.

Это еще хуже. Многие люди (например, пользователи университетской компьютерной сети) не имеют привилегий sudo. Когда pip завершается с ошибкой разрешения, они либо:

  1. Напишите их администратору и попросите установить пакет. Это медленно и утомительно для всех.
  2. Сдаться и обойтись без пакета.

Только если они особенно опытны или хорошо информированы, они попробуют pip install --user .

Если мы в конечном итоге примем решение против «по умолчанию --user», нам следует рассмотреть менее разрушительные альтернативы:

  1. Возврат к --user (если установка не удалась из-за ошибок разрешений)
  2. (Если установка не удалась из-за ошибок прав доступа), предложите пользователю (большими понятными буквами) попробовать --user

На самом деле я уже некоторое время использую --user во всех своих установках, но обычно люди не знают об этой опции. Я согласен, что раздражает видеть ошибку разрешений каждый раз, когда вы забываете об этой опции. Я заметил, что пользовательские установки несовместимы с conda (conda/conda#448).

Я хотел бы возродить это, так как теперь люди будут сталкиваться с этим в Windows гораздо чаще, поскольку 3.5 по умолчанию устанавливается в Program Files (что требует прав администратора для изменения).

Мне нравится опция «возврат к --user при ошибке разрешения» лучше всего подходит для установки, с «по умолчанию к --user и откат к системе» при удалении и, возможно, добавление опции --system или --system-only чтобы предотвратить откат. Пользователи, преднамеренно запускающие pip с правами администратора, получат установку системы, как и ожидалось, и в настоящее время пользователи без разрешений получат сообщение об ошибке, поэтому я не верю, что здесь есть какие-либо проблемы с обратной совместимостью.

Моя цель состоит в том, чтобы неосведомленный пользователь мог выполнить pip install spam; python -c "import spam" без ошибок (хотя, возможно, предупреждение при повторной попытке с --user ).

Я думал об этом в последнее время, особенно после того, как недавно были открыты # 2403 и # 2401, что заставило меня задуматься об использовании sudo pip install и о том, как это может часто ломать системы, помимо проблем с разрешениями.

С этой целью мне интересно, не является ли лучшая конечная цель просто тем, что --user является значением по умолчанию, никаких магических проверок разрешений и добавлением нового флага, такого как --global , --system , или --no-user , что вернет предыдущее поведение. Это легче объяснить людям, поскольку он будет вести себя одинаково независимо от того, как и где что-то установлено.

Теперь, если мы решим, что это именно тот путь, которым мы хотим идти, остается проблема, как нам добраться до той точки, где мы находимся сегодня. Очевидно, что в какой бы момент мы ни переключили значение по умолчанию, это будет довольно серьезное изменение, поэтому нам потребуется довольно много времени на подготовку. Я думаю, что если мы решим пойти по этому пути, лучший способ сделать это будет продолжать сохранять вариант --user , добавить новый вариант, например --global , а затем, если один или другой параметр не настроен, выполните магию проверки разрешений, о которой мы говорили, и если магия решила использовать поведение --global , мы поднимем очень громкое предупреждение об устаревании. Это предупреждение об устаревании будет действовать намного дольше, чем другие предупреждения об устаревании, которые мы выпустили, поскольку это будет довольно серьезное изменение в поведении. Я думаю, что мы также хотели бы добавить опцию, которая отключила бы волшебный запасной вариант и реализовала бы будущее поведение, чтобы люди могли получить это поведение сегодня.

Другой важный вопрос заключается в том, что нам следует делать, если мы обнаружим, что Python, в который мы устанавливаем, не поддерживает пользовательские сайты. В этом случае я бы просто заявил, что --user является ошибкой, и для этих Python мы просто вернемся к значению по умолчанию --global . Я считаю, что это покрывает virtualenv/venv автоматически, и если кому-то нужна «более тяжелая» изолированная среда с использованием полностью скомпилированных Python, они могут просто исправить site.py , чтобы установить для ENABLE_USER_SITE значение False вверху файла.

+1, и я бы проголосовал за --system.

Отмечу, и я уверен, что вам это понравится, настройки по умолчанию в Ubuntu изменились:

https://launchpad.net/ubuntu/+source/python-pip/1.5.6-4ubuntu1

9 февраля 2015 г. в 16:41 Дональд Стаффт написал:

С этой целью я задаюсь вопросом, не является ли лучшая конечная цель просто тем, что --user является
по умолчанию, никаких магических проверок разрешений и добавьте новый флаг, например --global ,
--system или --no-user , что вернет предыдущее поведение. Этот
легче объяснить людям, так как он будет вести себя одинаково независимо от
как/где все установлено.

Я думаю, что --system неправильно, потому что это действительно применимо только к некоторым Python. Это не относится к:

  • Питон в Windows
  • pyenv установил Pythons
  • Conda установил Pythons
  • Nix установил Pythons
  • Пользовательские скомпилированные Pythons.

Это _только_ применяется к системам *nix, где Python поставляется системой. Я чувствую, что --global — гораздо лучшее имя для этого флага.

И FML, почему Debian/Ubuntu чувствует необходимость постоянно добавлять случайные исправления, которые нарушают ожидаемые варианты использования?

Итак, если патч Ubuntu будет возвращен, каковы сроки его исправления здесь? Неделя/месяц/3 месяца/6 месяцев/год...?

Это зависит от того, что вы подразумеваете под фиксированным.

Предположим на мгновение, что мы используем идею, которая была у меня 2 сообщения назад (которая все еще нуждается в одобрении от других разработчиков pip), мы, вероятно, могли бы довольно быстро получить план перехода, в котором верно следующее:

  • Когда передается --user , мы _всегда_ устанавливаем на пользовательский сайт пакеты.
  • Когда передается --global (или что-то подобное), мы _всегда_ устанавливаем в пакеты глобального сайта.
  • Когда ни один из них не передается, мы реализуем резервный метод, который:

    • Определяет, находимся ли мы в виртуальной среде, и если да, то действует так, как если бы было передано --global .

    • Определяет, отключены ли пользовательские сайт-пакеты, и если это так, действует так, как если бы был передан --global .

    • Определяет, не имеет ли действующий пользователь прав на запись в sys.path и не действует ли он так, как если бы --user был передан.

    • Наконец, если все другие методы обнаружения не сработали, действуйте так, как если бы --global было передано, и выведите предупреждение об устаревании, в котором говорится, что в какой-то момент в будущем поведение этого изменится, и вместо этого он будет установлен в --user .

Это не остановит кого-то от выполнения sudo pip install foo в своей системе Python, однако выведет предупреждение о том, что в какой-то момент это будет означать --user , и предложит явно начать использовать --global . После того, как вышеуказанное будет выпущено в течение достаточно долгого времени, мы можем удалить устаревший путь кода и упростить его, чтобы это было просто:

  • Когда передается --user , мы _всегда_ устанавливаем на пользовательский сайт пакеты.
  • Когда передается --global (или что-то подобное), мы _всегда_ устанавливаем в пакеты глобального сайта.
  • Когда ни одна из опций не передается, мы реализуем резервный метод, который:

    • Определяет, находимся ли мы в виртуальной среде, и если да, то действует так, как если бы было передано --global .

    • Определяет, отключены ли пользовательские сайт-пакеты, и если это так, действует так, как если бы было передано --global .

    • Наконец, по умолчанию используется --user .

Однако переход от первого поведения ко второму поведению займет довольно много времени. Это будет действительно серьезное кардинальное изменение, которое сломает все для любого программного обеспечения (например, соли, шеф-повара, марионетки) или сценария развертывания (например, одного из скриптов Fabric, запеченных в тысячах проектов по всему миру), которые ожидают, что sudo pip install <foo> будет установлен в глобальный Python. Нам потребуется время, чтобы люди увидели предупреждение, и изменить их программное обеспечение и сценарии, чтобы они передавали явный флаг --global , если им действительно нужно такое поведение.

Я думаю, что предложенный Дональдом план является хорошим, хотя, если команда pip решит принять этот подход, мы также должны зарегистрировать проблему блокирования выпуска 3.5 с CPython, чтобы добавить каталог скриптов для каждого пользователя в путь в Windows вместе с глобальным один. Если 3.5 добавит это вместе с переключением на установку в Program Files по умолчанию, то мы должны получить желаемое поведение установки без прав администратора, продолжая «просто работать».

Возможность изменить место установки по умолчанию с помощью файлов конфигурации pip также может быть полезной, позволяя людям выбирать «по умолчанию для каждого пользователя» в своих собственных системах, даже если значение по умолчанию еще не изменилось. (например, «установка по умолчанию = пользователь» и «установка по умолчанию = глобальный»)

@dstufft : я рад помочь реализовать ваше предложение, как сказано об ошибке Ubuntu, если я вам понадоблюсь. Как только мы получим это поведение в транке, я, конечно же, заменю текущий патч Ubuntu этим.

Держите меня в курсе, если вам нужна помощь.

Я +1 в плане @dstufft . Я бы выбрал --global в качестве имени по указанным причинам. Мы уже достаточно долго сидим на заборе, давайте начнем.

O'n и +1 по предложению @ncoghlan о том, что Python 3.5 добавляет каталог сайта пользователя в PATH в Windows. Давайте избегать дальнейших камней преткновения для этого перехода.

Я также +1 за план @dstufft и +1 за --global , хотя мне все еще интересно, что sudo pip install foo нужно --global . Действительно ли необходимо, чтобы root имел пакеты пользовательских сайтов? Можем ли мы в специальном случае root отключить пакеты сайта по умолчанию? (Что заставит sudo pip install foo работать так же, как сейчас)

Я никогда не видел, чтобы кто-то использовал --user для root с текущим состоянием, но если кто-то действительно знает такой вариант использования, я хотел бы знать.

Одна мысль, которая пришла мне в голову, заключалась в том, как каталог сайта пользователя будет работать с несколькими установленными версиями Python?

Если я сделаю pip install pytest --user в Python 2.7 и 3.4 (с Python 3.4 в качестве Python по умолчанию), в какой версии будет выполняться команда py.test ? У меня есть подозрение, что две установки перезапишут друг друга, так что это ситуация «выигрывает последняя», что _не_хорошо. Кроме того, если это «выигрывает последний», и я устанавливаю версию 2.7 после версии 3.4, как мне исправить это, чтобы снова сделать 3.4 по умолчанию?

А как насчет удаления? Рассмотрим следующий сценарий (непроверенный, потому что мне нужно было бы настроить чистую машину, если бы я не хотел рисковать поломкой своего основного ноутбука):

    C:\Apps\Python34\python.exe -m pip install pytest --user
    C:\Apps\Python27\python.exe -m pip install pytest --user
    C:\Apps\Python34\python.exe -m pip uninstall -y pytest

Во-первых, почему вторая команда не выдала предупреждение о перезаписи существующего файла? Или будет? Случилось это или нет, есть ли у меня варианты, что делать?

Во-вторых, не будет ли сбой при удалении из-за того, что контрольная сумма py.test.exe не соответствует значению в файле RECORD ? Если это не удается, как мне удалить? Если это не сработает, сломает ли он мою копию pytest на Python 2.7 (удалив exe)?

И, наконец (на данный момент!) Будет ли каталог пользовательских скриптов идти до или после каталога системных скриптов в PATH? IMO, это должно идти после, так как в противном случае пользовательская установка пакета в Python, который _не_ был запрошен пользователем как «Python по умолчанию», может переопределить тот же пакет, установленный в системных сайтах Python «по умолчанию». пакеты.

Хм, может быть, есть некоторые открытые вопросы, которые нужно решить, прежде чем мы внесем это изменение...

Я ожидаю, что конфликты имен в общем каталоге пользовательских сценариев Windows будут обрабатываться так же, как они обрабатываются в системах POSIX с их общими каталогами bin: Python 3 не будет устанавливать неполное имя сценария для установленных пакетов, поэтому неквалифицированный имя будет относиться к версии Python 2.

То же самое касается того, имеет ли по умолчанию приоритет системная установка или установка для каждого пользователя: поместите каталог пользовательского скрипта после системного.

«Python 3 не будет устанавливать неполное имя сценария для установленных пакетов» - предположительно, вы имеете в виду, что pip и setuptools (в Python 3) не будут здесь? Так это изменение в этих инструментах?

О, и бле. Моя мышечная память на 100% обучена набирать «pip install foo» для установки в мой Python по умолчанию (3.4). Это будет ад, чтобы переучиться.

Кроме того, пользователи Windows могут выбирать, означает ли «python» Python 2 или 3 (через «сделать это Python по умолчанию» и «Добавить в PATH») — в отличие от пользователей Unix, где система Python устанавливает правила. Итак, если я говорю, что хочу использовать Python 3.5 по умолчанию, почему бы не использовать «pip» (или любое другое неполное имя) для этой версии? Кажется странным, что пользователь, у которого в Windows установлен только Python 3.5, не может использовать неквалифицированные имена просто из-за проблемы Unix, связанной с тем, как системному Python нужны имена. (Извините, если мое описание ограничений Unix является неточным - я не очень понимаю проблему). Людям, устанавливающим несколько версий Python, нужно решение, но это решение не должно затрагивать большинство, которым нужна только одна версия.

Может быть, самый простой ответ заключается в том, что каталог пользовательских скриптов должен быть версионным, как и каталог пакетов пользовательского сайта?

О, и должны ли эти дебаты быть на python-dev, а не здесь, поскольку в более общем плане речь идет о каталоге сайта пользователя?

Возобновление обсуждения дизайна PEP 370 для каталога сценариев Windows для каждого пользователя на python-dev, безусловно, было бы разумным. Странно, что глобальные установки сценариев в Windows ограничиваются версией Python, а установки сценариев для каждого пользователя — нет.

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

Что касается общего решения для обработки параллельной установки, то это будет переключатель «-m» — таким образом вы всегда будете знать, какой Python вы вызываете, а не догадываетесь о содержимом строки shebang отдельного скрипта.

Понятно относительно -m , но в прошлый раз, когда это обсуждалось в контексте того, как документировать вещи, сильное предпочтение заключалось в том, что мы должны рассматривать pip install foo как канонический способ установки вещей (с -m и версионные команды рассматриваются как исключения для особых случаев.

В руководстве по pip даже не упоминаются альтернативы (за исключением одного случая использования -m для обновления самого pip в Windows).

Я рекомендую -m в документации пакета stdlib для обработки вызова pip, когда
работа с параллельными установками Python - это единственный стиль вызова, который
работает на всех платформах, для глобальных установок, пользовательских установок и виртуальных
среды.

09 февраля 2015 г., в 19:58, ncoghlan написал:

Возможность изменить место установки по умолчанию через файлы конфигурации pip
также может быть полезно, позволяя людям выбирать «для каждого пользователя по умолчанию» на
свои собственные системы, даже если значение по умолчанию не изменилось
все же. (например, «установка по умолчанию = пользователь» и «установка по умолчанию = глобальный»)

Мне это нравится. Одна из вещей, с которой мы боремся, - это как решить
более консервативный подход upstream к переходу на --user по умолчанию, с
дистрибутивы конкурируют друг с другом, стремясь сделать pip системно безопасным и совместимым с другими
инструменты. Например

https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1419695
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=725848

Если бы у нас был общесистемный конфигурационный файл для выбора значения по умолчанию, то при
по крайней мере, все задействованные механизмы будут идентичными, а дистрибутивы не будут
приходится нести некрасивые дельты. Все, что нам нужно было бы сделать, это изменить
config и задокументируйте его для наших пользователей. Проблемы, которые вызвали бы
нам не справиться, но, по крайней мере, это было бы легко объяснить.

Я не думаю, что Debuntu в настоящее время устанавливает файл pip.conf для всего сайта (у меня
перепроверить).

https://pip.pypa.io/en/latest/user_guide.html#configuration

Одна сложность: мы устанавливаем разные pip-скрипты для Python 2 и Python 3,
поэтому я думаю, что нам понадобятся отдельные файлы конфигурации для разных версий
Python, например, /etc/{xdg/pip/}/pip{2,3}.conf или что-то в этом роде.

10 февраля 2015 г. в 01:24 Пол Мур написал:

Одна мысль, которая пришла мне в голову, это то, как каталог сайта пользователя будет работать с
установлено несколько версий Python?

В Debian/Ubuntu (может быть, во всех *nix?) у нас нет коллизии, потому что
библиотеки устанавливаются в ~/.local/lib/pythonX.Y/site-packages

Однако мы _делаем_ сталкиваемся с ~/.local/bin. Установка пакета с
скрипт 'foo' с использованием pip install --user foo и pip3 install --user foo будет
в конечном итоге затирает скрипт ~/.local/bin/foo.

Одним из недостатков этого изменения является то, что я думаю, что Fedora — единственный нижестоящий дистрибутив, который добавляет ~/.local/bin к $PATH по умолчанию (и он должен стоять перед /usr/bin и /usr/local/bin просто например, пакеты сайта пользователя предшествуют пакетам сайта). В идеале нисходящие потоки смогут модифицировать свои системы так, чтобы ~/.local/bin $PATH .

10 февраля 2015 г. в 07:24 Дональд Стаффт написал:

Одним из недостатков этого изменения является то, что я думаю, что Fedora является единственным нижестоящим
дистрибутив, который добавляет ~/.local/bin к $PATH по умолчанию (и он должен прийти
перед /usr/bin и /usr/local/bin так же, как пакеты пользовательского сайта
перед сайт-пакетами). В идеале нисходящие компании смогут модифицировать свои
систем так, что ~/.local/bin $PATH .

Да, но мы можем принять отдельное решение об этом. (точнее, вниз по течению
дистрибутивы могут это сделать.)

(и он должен стоять перед /usr/bin и /usr/local/bin, как и пользователь
пакеты сайтов идут перед пакетами сайтов)

Хм, @ncoghlan только что сказал обратное, что (в Windows, в частности
контекст) каталог пользовательских скриптов должен быть _после_ системного. Который
Я согласен с тем, что каталог пользовательских скриптов не имеет версии. Если это
версии, я меньше обеспокоен. Но это, вероятно, отражает тот факт, что
Пользователям Windows никогда не приходилось сталкиваться с конфликтами неверсионных сценариев и
чудовища вроде pip2/pip3, как у пользователей Unix ;-)

Да, и проблема с затиранием скриптов - более общая проблема, которая на самом деле не связана точно с --user . Та же проблема существует везде, кроме установки Windows --global . Я думаю, что решение этой проблемы является второстепенной задачей/проблемой, которую мы должны решить отдельно от этой проблемы.

Итак, текущие мысли:

  • Я думаю, что есть согласие по общей идее, которую я изложил ранее, поэтому я думаю, что мы захотим продвинуться вперед с чем-то вроде этого.
  • Мы собираемся использовать флаг --global .
  • Скорее всего, нам нужно какое-то предупреждение, если мы устанавливаем в --user , а ~/.local/bin нет в $PATH .
  • Нам понадобится какая-то опция default-install , которая по существу отключит резервное поведение и просто жестко закодирует либо --global , либо --user .
  • Начиная с pip 6.0 у нас есть файлы конфигурации для конкретных машин, расположенные в /etc/ , однако они не относятся к версии Python, в которой выполняется pip. Я думаю, что это хорошая функция, хотя и несколько отдельная (и может также идти рука об руку с решением проблемы стирания скриптов).

Я все еще вижу один важный открытый вопрос: что мы хотим в долгосрочной перспективе, когда кто-то делает sudo pip install foo или, скорее, если у кого-то есть разрешение на запись в каталог site-packages ?

Варианты, о которых я могу думать, следующие:

  1. Установить в --global . Это наиболее совместимая с предыдущими версиями опция, которая, вероятно, представляет то, что пользователи ожидают, когда они ее набирают. Однако у него есть недостаток, заключающийся в том, что он будет (молча) связываться с глобальным Python, что во многих системах может привести к поломке системы.
  2. Установите в --user , это защитит от сломанных систем (я думаю?), но я не думаю, что кто-то ожидает, что пользователь root получит установку /root/.local/ .
  3. Просто выведите ошибку и попросите пользователя выбрать либо --user , либо --global вручную.
  4. Выберите один из первых двух вариантов, но предоставьте переключатель, который дистрибутивы могут включить в /etc/ , который активирует третий вариант.

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

Я чувствую, что третий вариант, вероятно, плохой, поскольку «у меня есть разрешение на запись» будет сценарием, в котором любой пользователь Windows работает до Python 3.5, или любой, кто использует Conda, или любой, кто использует pyenv. Исключение ошибки кажется неправильным во всех этих случаях и настолько недружелюбно для пользователя при загрузке.

Так что я думаю, что между 1 и 2 это действительно сводится к тому, насколько плохой практикой, по нашему мнению, является то, что люди (концептуально) делают sudo pip install --global foo . В Windows, Conda, pyenv и т. д. мне кажется, что ответ на этот вопрос таков: «мы вовсе не думаем, что это плохая практика». В *nix мне кажется, что, возможно, ответ таков: «пользователям следует разрешить делать со своей системой все, что они хотят, но мы должны предоставить рельсы, чтобы увести их от «плохих» вещей».

Так что, подумав об этом подробнее, я думаю, что мне придется выбрать первый вариант, который нам подходит. Это более или менее решает проблемы обратной совместимости, поскольку поведение, которое мы действительно изменили бы, заключается в том, что если вы наберете pip install foo без разрешения на установку в эти глобальные каталоги, вы установите в --user вместо поднимая ошибку. Я думаю, маловероятно, что в этом случае кто-то действительно зависит от пункта, выдающего ошибку. Я также думаю, что pip install --user в качестве пользователя root вряд ли будет тем, что кто-то ожидает или хочет, и на самом деле это просто ружье для пользователей.

Итак, мое обновленное предложение будет таким:

  • При передаче --user мы всегда устанавливаем пакеты на сайт пользователя.
  • Когда передается --global , мы всегда устанавливаем пакеты на глобальный сайт.
  • Когда ни один из них не передается, мы реализуем резервный метод, который:

    1. Определяет, находимся ли мы в виртуальной среде, и если да, то действует так, как если бы было передано --global .

    2. Определяет, отключены ли пользовательские сайт-пакеты, и если да, то действует так, как если бы был передан --global .

    3. Смотрит на default-install и, если он существует, использует --user или -global на его основе.

    4. Определяет, не имеет ли действующий пользователь разрешений на запись в глобальные пакеты сайтов и не действует ли он так, как если бы был передан --user .

    5. Наконец, если все другие методы обнаружения не сработали, действуйте так, как если бы было передано --global .

Это будет означать отсутствие периода устаревания, и ожидается, что при отсутствии --user или --global мы попытаемся сделать наилучшее предположение, основываясь на возможностях Python, в котором мы работаем. , действующий пользователь и любой настроенный метод установки по умолчанию.

(и он должен стоять перед /usr/bin и /usr/local/bin, как и пользователь
пакеты сайтов идут перед пакетами сайтов)

Хм, @ncoghlan только что сказал обратное, что (в Windows, в частности
контекст) каталог пользовательских скриптов должен быть _после_ системного. Который
Я согласен с тем, что каталог пользовательских скриптов не имеет версии. Если это
версии, я меньше обеспокоен. Но это, вероятно, отражает тот факт, что
Пользователям Windows никогда не приходилось сталкиваться с конфликтами неверсионных сценариев и
чудовища вроде pip2/pip3, как у пользователей Unix ;-)

Я даже не думаю о конфликте названий сценариев. Я просто думаю, что совершенно неправильно, чтобы наша переменная $PATH действовала иначе, чем sys.path . Насколько я знаю, порядок sys.path таков: stdlib > пакеты пользовательских сайтов > глобальные пакеты сайтов. Я думаю, это было бы действительно запутанно, если бы порядок some-script был глобальным каталогом bin > каталогом bin пользователя, а python -m some-script был пакетами сайта пользователя > глобальными пакетами сайта.

Если есть проблема с каталогами скриптов (и с версиями и без версий), то я думаю, что мы должны решить эту проблему, но это не очень важно, в каком порядке они должны быть, потому что я чувствую что-то другое, кроме соответствия тому, что sys.path делает это очень неправильно.

Хорошо, мы должны предположить (и рекомендовать), что $PATH следует за sys.path, с (в терминах Windows) C:PythonXY перед %APPDATA%PythonXYScripts перед C:PythonXYScripts. Я отмечу это в ветке python-dev.

Последнее предложение Дональда звучит хорошо для меня (такое же, как и мое первоначальное, плюс все важные детали, которые я упустил :)). Я согласен на 100% с абзацем «Так что думай об этом больше ...» тоже.

Что касается настройки PATH в Windows, это почти невозможно. Общесистемный установщик может настраивать только общесистемные переменные среды, и они не могут включать расширения, поэтому вы не можете задать разные пути для каждого пользователя. (Установщик для каждого пользователя может это сделать, но в этом случае --global завершится успешно, поэтому в этом нет необходимости.)

Кроме того, из-за неправильной обработки PATH в Windows общесистемные настройки _всегда_ опережают настройки для каждого пользователя. Это привело к моему полупредложению некоторое время назад (на python-dev, IIRC) об использовании средства запуска py.exe для неверсионных скриптов, чтобы pip.exe всегда переходил к последней системе или пользователю Python, а не тот, который его установил, и (например) pip.exe -3.5 позволит выбрать конкретную версию.

Единственный способ заставить это действительно работать, это чтобы установщик Python начал установку пакетных файлов для настройки PATH по запросу (и, возможно, ярлык, который запускает пакетный файл). Таким образом, первое, что пользователи будут вводить, это activate-py35 , а затем их PATH будет правильно настроен для версии 3.5. Я очень переживаю по этому поводу, так как не хочу влезать в ситуацию с vcvarsall.bat, но в то же время это будет отлично для скриптов, которые в настоящее время делают предположения о местах установки или пытаются пройтись по реестру. найти его.

и, возможно, ярлык, который запускает пакетный файл

На мой взгляд, это ярлык «Командная строка Python 3.5 (32-разрядная версия)». Пользователи Visual Studio должны распознавать параллель.

Я недостаточно знаю о Windows, чтобы полностью понять последствия всего этого, но мне очень жаль вернуться к ситуации, когда pip install foo , устанавливающий скрипт foo , не может быть немедленно выполняется как foo в командной строке. Если мы устанавливаем на --user , а это не на их пути по умолчанию, то это кажется мне довольно серьезной регрессией.

Я не уверен, что точно понимаю, как использование py.exe для неверсионных сценариев будет работать на практике и действительно ли это решит проблему. Я лично не привязан к созданию сценариев точно так же, как мы сегодня, поэтому, если это _работает_, я думаю, что мы, возможно, сможем это сделать, но мне нужно лучше понять последствия, прежде чем я смогу поставить +1 по этому поводу.

Что касается настройки PATH в Windows, это почти невозможно. Общесистемный установщик может настраивать только общесистемные переменные среды, и они не могут включать расширения, поэтому вы не можете задать разные пути для каждого пользователя.

О, хуй. Я забыл это.

и, возможно, ярлык, который запускает пакетный файл
На мой взгляд, это ярлык «Командная строка Python 3.5 (32-разрядная версия)». Пользователи Visual Studio должны распознавать параллель.

... что ужасно для тех из нас, кто по умолчанию использует Powershell для всего.

но мне очень неловко возвращаться к ситуации, когда pip install foo, который устанавливает скрипт foo, не может быть немедленно выполнен как foo в командной строке.

Согласованный. Это было бы плохим регрессом, и его необходимо устранить. Я просто хочу, чтобы кто-то мог придумать способ :-)

Я не уверен, что точно понимаю, как использование py.exe для неверсионных скриптов будет работать на практике.

Я думаю, что смысл (который лишь отчасти связан с py.exe ) заключается в том, что оболочка exe вместо того, чтобы вызывать конкретный, жестко запрограммированный интерпретатор Python, как это происходит в настоящее время, должна динамически выбирать интерпретатор на основе того, «что как-то по умолчанию» (реестр, ini-файл py.exe , все, что Python %PATH% дает вам, ...). Однако я не уверен, как это поможет, поскольку нам по-прежнему потребуется каталог пользовательских скриптов с версиями (чтобы файлы не перезаписывали друг друга или файлы не запускались интерпретаторами, у которых не установлен пакет), и мы все равно не могу поместить это в нужное место в %PATH%.

... что ужасно для тех из нас, кто по умолчанию использует Powershell для всего.

Я только что попробовал, и я могу легко создать файлы activate-py35.bat и activate-py35.ps1 , которые выглядят и ведут себя одинаково (т. е. каждый может просто написать activate-py35 и обновить пути). Все еще не идеальный, но, возможно, лучший из плохой ситуации.

Я не уверен, что точно понимаю, как использование py.exe для неверсионных скриптов будет работать на практике.

Я думаю, что смысл (который лишь отчасти связан с py.exe ) заключается в том, что оболочка exe вместо того, чтобы вызывать конкретный, жестко закодированный интерпретатор Python, как это происходит в настоящее время, должна динамически выбирать интерпретатор на основе того, «что по умолчанию" как-то

"Каким-то образом" - это то, где py.exe вступает в силу - следует использовать те же правила. Если бы программа запуска была обновлена ​​для проверки собственного имени, то вместо запуска python.exe она могла бы попытаться запустить вместо этого 'scripts\\{}{}.{}.exe'.format(argv[0], major_version, minor_version) (с подходящей обрезкой расширения на argv[0] и т. д.). Затем установщики должны использовать для неверсированной программы запуска файл, отличный от файла с полной версией (который не изменится с сегодняшнего дня), но этот файл будет просто обычным py.exe с новым именем. (Это могло быть еще проще в старые времена с файлами pip-script.py , но теперь, когда их больше нет...)

Но, как вы говорите, PATH по-прежнему является проблемой. У меня нет хороших решений, и даже не так много плохих решений. Переменные среды действительно предназначены для настройки администраторами или пользователями, а не установщиками.

Мы можем изменить способ установки скриптов, чтобы сделать их более удобными для пользователей. Это все баланс, объединенный файл .exe и .py сделал вещи более приятными для пользователей, поскольку есть только единственный файл .exe . Однако я чувствую, что получение лучшей истории для pip install foo && foo важнее, чем эта конкретная вещь, поэтому, если нам нужно снова разделить .exe и .py , я думаю, что это хороший компромисс для хорошего ответа.

Разделение .exe / .py — наименьшая из проблем :)

На самом деле я разогреваюсь (или неохотно принимаю?) идею activate-py35 . Я никогда не был поклонником того, что установщик добавляет Python в PATH, и команда py -m pip на самом деле не набрала обороты (и она не будет работать, скажем, для Sphinx). Я напишу более подробное описание того, как activate-py может работать, и опубликую его на python-dev, чтобы посмотреть, получит ли оно какую-либо поддержку.

Будут ли эти activate-whatever файлы похожи на файлы внутри виртуальной среды? За исключением того, что вместо виртуальной среды, добавляемой в $PATH , добавляются настоящие Питоны?

Ага, почти идентичны. В python-dev я только что предложил взять параметр -x.y , передать его в py.exe и использовать sysconfig для получения путей.

Ok. У меня нет мнения о том, насколько это плохо для пользователей Windows, поскольку я не один из них. Звучит не так уж ужасно (может быть?), но это все, на что способны мои знания Windows.

10 февраля 2015 г. в 08:02 Дональд Стаффт написал:

Да, и стирание сценария — это более общая проблема, которая не
действительно связано с --user точно. Везде одна и та же проблема
кроме установок Windows --global . Я думаю, что решение этой проблемы
второстепенная проблема/проблема, которую мы должны решить отдельно от этой проблемы.

Согласованный.

Мы собираемся использовать флаг --global .

+1

Вероятно, нам нужно какое-то предупреждение, если мы устанавливаем в --user и
~/.local/bin не находится на $PATH .

+1, возможно, с опцией конфигурации, чтобы подавить предупреждение?

Нам нужен какой-то вариант default-install , который, по сути,
отключите резервное поведение и просто жестко закодируйте либо --global , либо
--user .

+1

Начиная с pip 6.0 у нас есть файлы конфигурации для конкретных машин, расположенные в /etc/
однако они не относятся к версии Python, которая выполняется
точка Я думаю, что это хорошая функция, хотя и несколько отдельная (и
также может идти рука об руку с решением проблемы стирания сценария).

Я бы предложил такой порядок поиска:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

сначала (?) в /etc/xdg/pip, затем в /etc, где XY, конечно,
основной.младший номер версии. Первый найденный, выигрывает.

Я все еще вижу один большой открытый вопрос: что мы хотим в долгосрочной перспективе, когда
кто-то делает sudo pip install foo вернее, если у кого-то есть разрешение на
писать в каталог site-packages ?

Обратите внимание, что существует не только один каталог «site-packages». Например,
в Debian/Ubuntu мы не хотим, чтобы sudo pip install _всегда_ устанавливалась в
/usr/lib, но только /usr/local/lib. И не забывайте, что это dist-packages.
не сайт-пакеты (кроме ~/.local из-за причин $).

Это действительно важный момент, о котором иногда забывают (даже я).
Дональд описывает это лучше всего, когда говорит, что существует локальный каталог сайта и
локальный каталог поставщика. В Debian site-local — это
/usr/lib/pythonX.Y/dist-packages, и ни одна команда pip не должна касаться этого,
в то время как локальный поставщик - это /usr/local/lib/pythonX.Y/dist-packages, и это
задокументированный и популярный вариант использования некоторыми системными администраторами для установки pip
в этот каталог.

Итак, что я бы предложил, поскольку мы уже прошли путь к файлу конфигурации, это
сделать их настраиваемыми, например

  • глобальный_каталог_установки
  • global_install_as_sudo (истина/ложь)
  1. Установить в --global . Это самый обратно совместимый вариант
    и, вероятно, представляет то, что пользователи ожидают, когда они набирают это. Однако он имеет
    недостаток в том, что он будет (молча) связываться с глобальным Python, который на многих
    системы могут привести к поломке систем.

С описанной выше возможностью настройки это было бы полностью совместимо с Debian.
Суперпользователи Debian ожидают, что sudo pip install перейдет в
/usr/local/lib/pythonX.Y/dist-packages. Я бы не сказал, что это «мешает
system», потому что он не ломает менеджер пакетов, и хотя он может
переопределить установленные системой пакеты (которые находятся в
/usr/lib/pythonX.Y/dist-packages), он делает это определенным и задокументированным способом.

  1. Установите в --user , это защитит от сломанных систем (я думаю?)
    но я не думаю, что кто-то ожидает, что пользователь root получит
    /root/.local/ установить.

Согласитесь, это было бы неожиданно.

  1. Просто выведите ошибку и попросите пользователя выбрать либо --user , либо
    --global вручную.

Я бы не возражал, но см. переключатель конфигурации выше.

  1. Выберите один из первых двух вариантов, но предоставьте переключатель, который могут использовать дистрибутивы.
    сдайте /etc/ , чтобы активировать третий вариант.

Эй, какой отличный вариант!

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

Я согласен иметь другое, определяемое платформой поведение, если, скажем, у pip было
--dry-run опция, которая, по крайней мере, сообщила бы пользователю, что именно происходит
делать и где.

Я чувствую, что третий вариант, скорее всего, плохой, так как «я должен написать
разрешение» будет сценарием, в котором любой пользователь Windows предварительно
Python 3.5 или любой, кто использует Conda, или любой, кто использует pyenv. Ошибка
кажется неправильным во всех этих случаях, и
недружественный для загрузки.

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

Так что я думаю, что между 1 и 2 все сводится к тому, насколько плоха практика.
мы думаем, что люди должны (концептуально) делать sudo pip install --global foo .

В Debian это ожидаемый вариант использования, если он находится в /usr/local/lib.
Он не может перейти в /usr/lib.

(Все это описывает поведение вне продажи, кстати.)

  • При передаче --user мы всегда устанавливаем пакеты на сайт пользователя.

+1

  • При передаче --global мы всегда устанавливаем на глобальный сайт
  • пакеты.

Глобальные пакеты _vendor_ == +1, глобальные пакеты сайтов == -1.

  • Когда ни один из них не передается, мы реализуем резервный метод, который:

    1. Определяет, находимся ли мы в виртуальной среде, и если да, то действует так, как если бы

      --global пройдено.

+1, хотя повторюсь, что этот каталог внутри venv называется
/lib/pythonX.Y/сайт-пакеты

  1. Определяет, отключены ли пользовательские сайт-пакеты, и если да, то действует как
    --global было передано.

Хм, я не уверен насчет этого.

  1. Смотрит на default-install и, если он существует, использует --user или
    -global на его основе.

+1

  1. Определяет, если у действующего пользователя нет прав на запись в глобальные
    пакеты сайта, и если они не действуют, как если бы был передан --user .

+1

  1. Наконец, если все другие методы обнаружения не сработали, действуйте так, как если бы --global
    был пропущен.

Тоже не уверен.

Это будет означать отсутствие периода устаревания и ожидание того, что в
отсутствие --user или --global мы постараемся сделать наилучшее предположение на основе
о возможностях Python, в котором мы работаем, эффективном пользователе и
любой настроенный метод установки по умолчанию.

Звучит как разумная цель.

Чтобы было ясно, когда я говорю о «глобальных пакетах сайтов», я в первую очередь имею в виду «все, что distutils говорит нам устанавливать вещи глобально». Поскольку сам Python не имеет различия между «локальным поставщиком» и «локальным сайтом», это будет один и тот же каталог на любом нисходящем канале, который не исправляет свой Python. Однако в Debian это будет каталог dist-packages , а «глобальный» на самом деле означает «локальный сайт». Это не то, что pip должен делать что-то особенное для поддержки, потому что об этом позаботятся патчи Debuntu для Python.

Другими словами, pip уже устанавливается на /usr/local/../dist-packages/ в Debuntu, так как Debuntu исправил distutils для поддержки этого различия. Единственный раз, когда pip будет возиться с /usr/../dist-packages/ без передачи пользователем какого-либо флага, это то, что pip удалит оттуда файлы (потому что pip не видит этот каталог как особый, он просто видит его как вещь на sys.path ). Debian исправил pip, чтобы предотвратить удаление оттуда, и я думаю, что реальная поддержка этого зависит от реальной поддержки пакетов сайта «локального поставщика» в Python upstream.

Вероятно, нам нужно какое-то предупреждение, если мы устанавливаем в --user и ~/.local/bin нет в $PATH

Насколько хрупким может быть это предупреждение? Будет ли он преобразован в абсолютный путь? Будет ли он нечувствительным к регистру в файловых системах, нечувствительных к регистру? Будет ли это рассматривать и / как эквивалентные в Windows? Как насчет символических ссылок?

Если вы устанавливаете пакет, который не устанавливает никаких скриптов, предупреждение в любом случае не имеет значения.

Лично я думаю, что предупреждение, вероятно, принесет больше вреда, чем пользы.

Вероятно, нам нужно какое-то предупреждение, если мы устанавливаем в --user и
~/.local/bin не находится на $PATH .

+1, возможно, с опцией конфигурации, чтобы подавить предупреждение?

Мы могли бы просто заставить его использовать предупреждения Python, чтобы люди могли просто замолчать
это с использованием встроенных предупреждений Python. Если мы чувствуем необходимость заставить его замолчать в
все.

Начиная с pip 6.0 у нас есть файлы конфигурации для конкретных машин, расположенные в /etc/
однако они не относятся к версии Python, которая выполняется
точка Я думаю, что это хорошая функция, хотя и несколько отдельная (и
также может идти рука об руку с решением проблемы стирания сценария).

Я бы предложил такой порядок поиска:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

сначала (?) в /etc/xdg/pip, затем в /etc, где XY, конечно,
основной.младший номер версии. Первый найденный, выигрывает.

Разделите это на # 2417, так как я считаю, что это только косвенно связано с этим
обсуждение.

Я все еще вижу один большой открытый вопрос: что мы хотим в долгосрочной перспективе, когда
кто-то делает sudo pip install foo вернее, если у кого-то есть разрешение на
писать в каталог site-packages ?

Обратите внимание, что существует не только один каталог «site-packages». Например,
в Debian/Ubuntu мы не хотим, чтобы sudo pip install _всегда_ устанавливалась в
/usr/lib, но только /usr/local/lib. И не забывайте, что это dist-packages.
не сайт-пакеты (кроме ~/.local из-за причин $).

Это действительно важный момент, о котором иногда забывают (даже я).
Дональд описывает это лучше всего, когда говорит, что существует локальный каталог сайта и
локальный каталог поставщика. В Debian site-local — это
/usr/lib/pythonX.Y/dist-packages, и ни одна команда pip не должна касаться этого,
в то время как локальный поставщик - это /usr/local/lib/pythonX.Y/dist-packages, и это
задокументированный и популярный вариант использования некоторыми системными администраторами для установки pip
в этот каталог.

Итак, что я бы предложил, поскольку мы уже прошли путь к файлу конфигурации, это
сделать их настраиваемыми, например

  • глобальный_каталог_установки
  • global_install_as_sudo (истина/ложь)

pip на самом деле не контролирует их (я имею в виду, очевидно, что на высоком уровне он контролирует
потому что это тот, который перемещает файлы), они берутся из distutils/sysconfig.

Я думаю, что этот pip, вероятно, никогда не должен касаться локального каталога поставщика, если только
был задан какой-то флаг, например --vendor , который позволил бы поставщикам использовать
pip в их цепочке сборки. Эта концепция на самом деле не существует за пределами debuntu.
щас и их патчи с этим уже справляются, так что не думаю, что это супер
имеет отношение к этому обсуждению, за исключением того, что, когда я говорю
"глобальные пакеты сайтов" я имел в виду /usr/local/.../dist-packages на Debubuntu
и «локальные» пакеты в какой-то момент, если Python принимает Debuntu
система вверх по течению.

  1. Установить в --global . Это самый обратно совместимый вариант
    и, вероятно, представляет то, что пользователи ожидают, когда они набирают это. Однако он имеет
    недостаток в том, что он будет (молча) связываться с глобальным Python, который на многих
    системы могут привести к поломке систем.

С описанной выше возможностью настройки это было бы полностью совместимо с Debian.
Суперпользователи Debian ожидают, что sudo pip install уйдут в
/usr/local/lib/pythonX.Y/dist-packages. Я бы не сказал, что это «мешает
system», потому что он не ломает менеджер пакетов, и хотя он может
переопределить установленные системой пакеты (которые находятся в
/usr/lib/pythonX.Y/dist-packages), он делает это определенным и задокументированным способом.

Да, "беспорядок в системе" может быть слишком резким. В основном я имею в виду, что
sudo pip install foo может привести к поломке, если система зависит от foo и
вы устанавливаете несовместимую версию вещей. Однако тот же случай имеет место
true практически для всего, что вы устанавливаете в `/usr/local``.

  • При передаче --global мы всегда устанавливаем на глобальный сайт
  • пакеты.

Глобальные пакеты _vendor_ == +1, глобальные пакеты сайтов == -1.

Вы имеете в виду это наоборот, верно?

  • Когда ни один из них не передается, мы реализуем резервный метод, который:

    1. Определяет, находимся ли мы в виртуальной среде, и если да, то действует так, как если бы

      --global было передано.

+1, хотя повторюсь, что этот каталог внутри venv называется
/lib/pythonX.Y/сайт-пакеты

Да, снова мы просто спрашиваем Python, где этот каталог, мы не вычисляем его.
сами, так что «где находится этот каталог» — это вопрос venv/virtualenv.

  1. Определяет, отключены ли пользовательские сайт-пакеты, и если да, то действует как
    --global было передано.

Хм, я не уверен насчет этого.

Я не думаю, что это можно обойти, если пакеты пользовательских сайтов отключены.
не думаю, что мы должны установить туда, потому что у нас нет возможности узнать
если это отключение означает, что _is_ нет пользовательских пакетов сайта, или почему. Мы можем только
считать, что его нет.

  1. Наконец, если все другие методы обнаружения не сработали, действуйте так, как если бы --global
    был пропущен.

Тоже не уверен.

Это в основном сводится к:

Если мы не нашли причину, мы должны использовать --user, как флаг --user, или
не имея прав на запись в каталог, не используйте его. Этот
это то, что сохранит sudo pip install foo без флага --global
работающий. Это также означает, что это самое важное правило для того, чтобы не нарушать
рабочее программное обеспечение, которое ожидает, что sudo pip install foo будет действовать таким образом.

Вероятно, нам нужно какое-то предупреждение, если мы устанавливаем в --user и ~/.local/bin нет в $PATH

Насколько хрупким может быть это предупреждение? Будет ли он преобразован в абсолютный путь? Будет ли он нечувствительным к регистру в файловых системах, нечувствительных к регистру? Будет ли это рассматривать и / как эквивалентные в Windows? Как насчет символических ссылок?

Если вы устанавливаете пакет, который не устанавливает никаких скриптов, предупреждение в любом случае не имеет значения.

Лично я думаю, что предупреждение, вероятно, принесет больше вреда, чем пользы.

Ну, мы могли бы реализовать это как (кросс-платформенный эквивалент):

def user_bin_on_path():
    paths = os.environ.get("PATH").split(":")
    for path in paths:
        if os.path.realpath(path) == os.path.realpath(USER_BIN_DIR):
            return True
    return False

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

Я согласен с тем, что предупреждение не имеет значения, если скрипты не устанавливаются, и я хотел сказать, что мы будем беспокоить предупреждение только при установке скриптов.

Основная идея заключается в том, что я не хочу, чтобы кто-то делал что-то вроде pip install [--user] foo , где --user является неявным, а затем делал foo и получал «команда не найдена» без каких-либо указаний по поводу почему его можно не найти. Предупреждение, по крайней мере, скажет им, что им нужно добавить что-то в PATH. Это также может помочь пользователям Windows добавить свой пользовательский каталог в их PATH вручную (или запустить какой-либо скрипт для этого), что может уменьшить потребность в сценариях activate , на которые указал Стив. Хотя я думаю, что это по-прежнему будет означать, что системные значения имеют приоритет над пользовательскими значениями, поэтому это все еще может сбивать с толку, поскольку порядок PATH и sys.path все еще будет обратным.

Дох. Я забыл, что realpath канонизировал путь. Да, конечно, это работает достаточно хорошо.

Что меня беспокоит, так это то, что _if_ тест ошибочно видит проблему, пользователь получает раздражающее и неправильное предупреждение, и у него нет возможности избежать его, кроме как изменить свою систему, чтобы обойти ошибку со стороны pip. Но учитывая, что тест, который вы предлагаете, вероятно, достаточно надежен, и мы проверяем его только в том случае, если устанавливаем скрипты, проблема, вероятно, достаточно редкая, чтобы ее можно было игнорировать.

Хорошо, я думаю, что у нас есть общее согласие здесь. Я думаю, что следующим шагом будет установка патча. Я пойду вперед и попытаюсь получить что-нибудь позже сегодня вечером или завтра.

10 февраля 2015 г. в 12:14 Дональд Стаффт написал:

Основная идея заключается в том, что я не хочу, чтобы кто-то делал что-то вроде pip install [--user] foo , где --user является неявным, а затем делал foo и
получить «команда не найдена» без каких-либо указаний о том, почему это может быть не так
нашел.

В Debian и, возможно, в других Linux-ах есть пакет, который не найден.
который предлагает пользователю установить пакет, если он вызывает команду, которая
не установлен.

% чернильный пейзаж
Программа inkscape в настоящее время не установлена. Вы можете установить его, набрав:
sudo apt-get установить inkscape

Может быть, мы могли бы подключиться к этому для поддержки платформ.

10 февраля 2015 г. в 12:06 Дональд Стаффт написал:

  • При передаче --global мы всегда устанавливаем на глобальный сайт
  • пакеты.

Глобальные пакеты _vendor_ == +1, глобальные пакеты сайтов == -1.

Вы имеете в виду это наоборот, верно?

Я мог перепутать мою терминологию, поэтому я буду откровенен:

/usr/local/lib/pythonX.Y/dist-packages == +1
/usr/lib/pythonX.Y/dist-packages == -1

но, как вы сказали ранее, это не то, о чем действительно нужно беспокоиться
о том, что он унаследован от distutils, а distutils Debuntu исправлен
делать правильные вещи.

  1. Определяет, отключены ли пользовательские сайт-пакеты, и если да, то действует как
    --global было передано.

Хм, я не уверен насчет этого.

Я не думаю, что это можно обойти, если пакеты пользовательских сайтов отключены.
не думаю, что мы должны установить туда, потому что у нас нет возможности узнать
если это отключение означает, что _is_ нет пользовательских пакетов сайта, или почему. Мы можем только
считать, что его нет.

О, теперь я понимаю, что вы имеете в виду. Думаю, это имеет смысл. Меня беспокоит то, что это
может быть труднее предсказать, что на самом деле собирается сделать pip, но, как я
скажем, я был бы доволен флагом --dry-run, чтобы pip мог недвусмысленно _tell_
вы, что он собирается делать.

  1. Наконец, если все другие методы обнаружения не сработали, действуйте так, как если бы --global
    был пропущен.

Тоже не уверен.

Это в основном сводится к:

Если мы не нашли причину, мы должны использовать --user, как флаг --user, или
не имея прав на запись в каталог, не используйте его. Этот
это то, что сохранит sudo pip install foo без флага --global
работающий. Это также означает, что это самое важное правило для того, чтобы не нарушать
рабочее программное обеспечение, которое ожидает, что sudo pip install foo будет действовать таким образом.

Понимаю. Я думаю, что это нормально, так как основной случай недопустимости использования, которого мы хотим избежать, это:

normal_user$ pip установить foo
ЭЙ, У ТЕБЯ НЕТ РАЗРЕШЕНИЙ
normal_user$ sudo pip установить foo
ЭЙ, ТЫ ПРОСТО ИСПОЛЬЗОВАЛ СВОЮ СИСТЕМУ

а правило "не иметь прав на запись в каталог подразумевает --user"
позаботится об этом.

Ах да, я забыл о команде-не-найдено. Может быть полезно. Кстати, вы не знаете, где правильно предложить, чтобы devubtu по умолчанию имел локальный бин пользователя в пути?

10 февраля 2015 г., в 16:05, Барри Варшава, [email protected] , написал:

10 февраля 2015 г. в 12:14 Дональд Стаффт написал:

Основная идея заключается в том, что я не хочу, чтобы кто-то делал что-то вроде pip install [--user] foo , где --user является неявным, а затем делал foo и
получить «команда не найдена» без каких-либо указаний о том, почему это может быть не так
нашел.

В Debian и, возможно, в других Linux-ах есть пакет, который не найден.
который предлагает пользователю установить пакет, если он вызывает команду, которая
не установлен.

% чернильный пейзаж
Программа inkscape в настоящее время не установлена. Вы можете установить его, набрав:
sudo apt-get установить inkscape

Может быть, мы могли бы подключиться к этому для поддержки платформ.


Ответьте на это письмо напрямую или просмотрите его на GitHub.

10 февраля 2015 г. в 13:17 Дональд Стаффт написал:

Ах да, я забыл о команде-не-найдено. Может быть полезно. Кстати, ты
знать правильное место, чтобы предложить, чтобы у devubtu была локальная корзина пользователя на
путь по умолчанию?

Не окончательно, но, может быть, пакеты adduser или passwd? Бывший владеет
/usr/sbin/adduser, а последний владеет /usr/bin/useradd.

Первый проход: https://github.com/pypa/pip/pull/2418

Я не уверен, что это поможет, но…

  • ~/.local/bin не находится в $PATH у многих людей, можно ли что-нибудь с этим сделать?

Некоторые другие проекты используют /etc/profiled.d/ для добавления каталогов в $PATH. По крайней мере, на Antergos я вижу следующее (если я не понимаю, что они делают): jre.csh, jre.sh, perlbin.csh, perlbin.sh.

# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
setenv PATH "${PATH}:/usr/lib/jvm/default/bin"
# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
export PATH=${PATH}:/usr/lib/jvm/default/bin
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && setenv PATH ${PATH}:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && setenv PATH ${PATH}:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && setenv PATH ${PATH}:/usr/bin/core_perl

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl

export PATH

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2

Как случайный пользователь pip, я просто хочу сказать _спасибо_ за работу над такими проблемами взаимодействия с пользователем, как эта и другие, отраженные в вехе « Улучшение нашего взаимодействия с пользователем». Есть ли место, где я могу внести финансовый вклад в это усилие?

Кроме того, я использую Homebrew и всегда ценил тот факт, что я мог просто brew install something , и он работал бы без какой-либо возни с разрешениями.

Как только я понял, почему установка с помощью Homebrew никогда не требовала sudo , я попытался привыкнуть делать pip install --user something , но по иронии судьбы Homebrew отключил это из-за сообщения об ошибке в distutils.

Учитывая популярность Homebrew в OS X, возможно, вы захотите изучить предполагаемую несовместимость Homebrew и pip install --user .

В любом случае, +1 от меня за то, что я сделал --user по умолчанию.

Быстрое продолжение. Дидье загрузил изменение в pip Ubuntu, которое установило параметр --user по умолчанию. Я в основном также разрешал это, но теперь я думаю, что это была ошибка, и я намерен отменить это для wily (но, вероятно, не будет SRU изменение для яркого). См. https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1460203 для получения подробной информации и обоснования.

+1 за то, что позволили восходящему потоку управлять временем этого изменения, поскольку различие между пользователем и системой уже достаточно запутанно, а различия платформ не вступают в игру.

Тем не менее, для дистрибутивов Linux может быть разумно начать переключать значение по умолчанию на --user, как только --global support появится в восходящем пипсе (пип 8?), поскольку в Linux выполняются глобальные установки, а не для каждого пользователя или per-venv зарекомендовал себя как плохая идея с потенциально непредсказуемыми побочными эффектами.

Я сказал @warsaw в частном порядке, но я скажу это и здесь:

Я думаю, что это изменение важно, и я планирую вернуться к моему запросу на включение, чтобы закончить его. Тем не менее, я один человек, работающий над несколькими проектами, и сейчас Warehouse важнее для меня, чем это изменение, потому что наследие PyPI становится все более обременительным в эксплуатации, и я чувствую, что нам нужно заменить его как можно скорее. Поэтому мое время на pip не сосредоточено на внесении многих изменений самому, а сосредоточено на руководстве изменениями, которые делают другие участники, а также на любых материалах процесса выпуска.

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

Возможно, здесь стоит повторить:

Если мы в конечном итоге примем решение против «по умолчанию --user», нам следует рассмотреть менее разрушительные альтернативы.

  1. Возврат к --user (если установка не удалась из-за ошибок разрешений)
  2. (Если установка не удалась из-за ошибок прав доступа), предложите пользователю (большими понятными буквами) попробовать --user

FWIW, теперь, когда установщик Windows для Python 3.5 настоятельно рекомендует установку для каждого пользователя, меня не так беспокоит это изменение, происходящее в pip. Вероятно, это был бы лучший вариант конфигурации для дистрибутивов (с переопределением --global ), чем новое значение по умолчанию или резервный вариант.

Просто хотел добавить +1 к этой проблеме и сказать спасибо за работу над ней! В настоящее время мы проводим научную летнюю школу Python, и многие люди sudo pip install столкнулись с проблемами с разрешениями.

FWIW Я за то, чтобы по умолчанию использовать --user или вернуться к --user , если установка не удалась из-за ошибок разрешения. В этом случае я бы предпочел дать им указания, как отменить то, что они сделали (например, We installed to your user directory. If you don't want this, then 'pip uninstall my_package' ), а не потерпеть неудачу и сказать им, как повторить попытку.

Я вижу много отчетов об ошибках в mock из-за --user - по крайней мере, в Ubuntu, где место --user на пути находится после dist-packages, и поэтому установленный pip фактически не используется для любой общей зависимости (например, six), что находится в dist-пакетах.

Они поставили это _после_ dist-packages ? Это сломанная установка ИМО.

Правильно, пользовательские установки должны выполняться перед пакетами site(/dist), а затем системные скрипты и утилиты должны запускаться с параметром -I (или -Es в Python 2).

Да, я согласен :). Это может быть исправлено в ярком, но мне определенно кажутся отчеты, в которых все происходит совершенно не из того места.

Я просто использовал системный pip для установки setuptools на мою яркую машину, чтобы поэкспериментировать.

>>> import setuptools
>>> setuptools.__path__
['/home/robertc/.local/lib/python2.7/site-packages/setuptools']
>>> import sys
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/robertc/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/home/robertc/work/mock']

Так что этот в здравом уме. Но сбивчиво это было введено в красках - так ИДК. Я посмотрю, смогу ли я в какой-то момент откопать воспроизводящий файл (для файла в Ubuntu BTS)

Пейджинг @warsaw

Пользовательские сайт-пакеты могут в конечном итоге быть переупорядочены после глобальных сайтов-пакетов злыми .pth-файлами setuptools. Это была повторяющаяся проблема для меня, пока я не научился никогда не использовать setup.py напрямую - я устанавливал что-то, и вдруг я использовал более старые версии всех видов других вещей. Несколько раз я написал агрессивный инструмент, чтобы разобрать мою систему.

Я думаю, по крайней мере, на данный момент pip должен просто напечатать дружественное сообщение с просьбой запустить --user в случае сбоя команды. Хотя переключение на значение по умолчанию имеет свои преимущества, напечатать лучшее сообщение не должно быть слишком сложно.

Это хорошее «быстрое решение» проблемы, пока мы фактически не перейдем к значению по умолчанию --user .

Также требуется --global, --system или --no-user, если в /etc/pip.conf установлен пользовательский режим. Насколько я могу судить, у пользователей нет простого способа переопределить это.

Это хорошее "быстрое решение" проблемы

Позднее обновление: #4233 сделал это.

Людей (особенно новичков), которые не используют Windows, действительно следует направлять на https://github.com/pyenv/pyenv , если они хотят получить хороший опыт. PEP 370 сегодня не имеет для меня особого смысла, тем более что ~/.local — это XDG_DATA_HOME.

Я думаю, что я буду не единственным, кто откажется от такого поведения, если/когда оно произойдет. Надеюсь, переход будет плавным, и мне не придется менять работу моей системы и передавать дополнительные флаги CLI, потому что я вполне доволен pyenv. Конечно, я не знаю, насколько хорошо pyenv работает с Windows, но подсистема bash могла бы помочь...

@jcrben pyenv делает довольно много предположений о том, как люди используют Python (и, в частности, как они получают свои двоичные файлы Python), что означает, что это очень хорошо работает для людей, для которых эти предположения действительны, но недостаточно универсален, чтобы быть рекомендацией по умолчанию (в этом отношении он похож на conda ).

Значение по умолчанию --user на уровне pip не повлияет на правильно настроенные виртуальные среды Python, поэтому влияние этого изменения на сторонние менеджеры среды, такие как conda и pyenv будет заключаться в том, что им нужно будет убедиться, что они правильно сигнализируют о состоянии среды таким образом, что pip и другие инструменты обнаружат (то есть либо так, как virtualenv сообщает об этом, или так, как venv стандартной библиотеки).

Связанное предложение: https://github.com/pypa/pip/issues/1056#issuecomment -218130183.

~ Рассматривалось ли разрешение пользователю настраивать каталог (возможно, через переменную env), чтобы избежать установки непосредственно в ~/.local ? Я, вероятно, предпочел бы вложить их в ~/.local/pip или что-то в этом роде - насколько я понимаю, Python не имеет особого права на верхний уровень этого общего пространства. ~ В 9.0.1 кажется, что вещи вложены в ~/.local/lib/python<version> плюс добавление исполняемых файлов в ~/.local/bin , что, я думаю, нормально...

@jcrben Да, целевое местоположение на самом деле является каталогом пользовательского сайта Python, который отражает схему именования для системного каталога сайтов-пакетов: https://docs.python.org/3/library/site.html#site.USER_SITE

Это уже настраивается на уровне интерпретатора с помощью переменной окружения PYTHONUSERBASE : https://docs.python.org/3/using/cmdline.html#envvar -PYTHONUSERBASE

Для тех, кто заинтересован, я только что выпустил https://github.com/ofek/hatch , в котором есть команды пакетов install , uninstall и update , которые по умолчанию используют это поведение. Для изменения системы пользователи могут использовать опцию -g/--global , аналогичную https://github.com/npm/npm.

Учитывая недавнюю проблему с зараженными вредоносным ПО пакетами на PyPI , я думаю, что в интересах pip сделать все возможное, чтобы воспрепятствовать использованию sudo pip install ... , особенно принимая во внимание, что сценарии установки могут выполнять произвольный код при установке. Устанавливать зараженные пакеты от имени пользователя достаточно плохо, но гораздо хуже, если они устанавливаются от имени пользователя root.

Установка по умолчанию пользователем означает, что меньше людей будут добавлять sudo к своей команде pip, а это означает, что случайно установленное вредоносное ПО может сделать меньше.

В качестве конкретного следующего шага я выделил отдельную проблему для добавления флага --global : https://github.com/pypa/pip/issues/4865 .

Это почти наверняка плохая идея в средах virtualenv или conda. Что бы ни было установлено в .local , когда одна среда активна, это может легко нарушить работу другой среды. Так что же думать в таких случаях?

копия @msarahan @kalefranz

Эта проблема не возникает внутри активной виртуальной среды — она применяется только в том случае, если активная среда не обнаружена и не указан ни один из параметров определения цели ( --prefix , --root и т. д.). в командной строке.

Как это определяется?

Мы рассматривали возможность отключения по умолчанию ~/.local на sys.path для python внутри сред conda, которым по определению является любой python, установленный conda. Хотя это сложно. В любом случае мы можем нарушить ожидания группы пользователей. Обсуждение на https://github.com/conda/conda/issues/7173

Разве pip не смог загрузить какой-либо аргумент из переменных среды, начинающихся с PIP_ ? Это работает для --user ? Каким будет полное имя переменной?

Это будет PIP_USER .

Документы: https://pip.pypa.io/en/stable/user_guide/#environment -переменные

PIP_USER=yes , если быть точным, спасибо! Использование переменных среды намного проще для использования CI, так как вам нужно определить их только один раз, и они будут использоваться всякий раз, когда вызываются команды.

Мне пришлось придумать действительно уродливую логику для Трэвиса, где, по-видимому, некоторые этапы выполняются от имени обычного пользователя без virtualemv, а некоторые — внутри virtualenv, и вы понятия не имеете, какой именно.

внутри virtualenv, скорее всего, --user завершится ошибкой, если вы не использовали сайт-пакеты (что вызывает другие проблемы).

Это упоминание о том, что я должен был обнаружить virtualenv в bash и не добавлять —user, иначе запуск завершится ошибкой.

Это уродливо и заставило меня потратить много времени на отладку, я уверен, что другие столкнутся с тем же.

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

pip должен завершиться ошибкой только в том случае, если не удастся найти место для установки пакета.

Любое движение по этому поводу?

Я не видел упоминания об этом, но, возможно, pip должен жаловаться, если --user передается при запуске под sudo.

Эти нерешенные проблемы уводят программистов от pip и даже python и заставляют их использовать другие пакеты или даже другие языки программирования, такие как javascript и npm, с меньшим количеством подобных проблем. Для новичка, который хочет использовать python, эти дополнительные необходимые опции разочаровывают.

Почему --user по умолчанию? Нельзя ли указать явно? Я не могу запустить pip --target из-за того, что он жалуется, что его нельзя использовать вместе с пользователем. Есть идеи, как этого избежать?

@dmikov : это не по умолчанию. Если вы не используете сломанную версию Debian/Ubuntu, в этом случае вы можете обойти --user с автоматической установкой, используя: PIP_USER=0 pip install -t ... . Или еще лучше, установите официальную версию и используйте ее.

Ночью мне снилось, что опция --user становится по умолчанию (не шучу), есть ли шанс, что мои мечты сбудутся в ближайшее время?

Мне нужна помощь в установке pygame, он продолжает говорить о недопустимом синтаксисе

я использовал
python3 -m pip install -U pygame --user
это неправильно что мне делать?

@flamedro56 : вместо того, чтобы комментировать случайную проблему, откройте новую и предоставьте дополнительную информацию: версию Python, версию pip, операционную систему, вывод команды...

Установщик reCAPTCHA

Как насчет новой опции конфигурации default=system,user? Это было бы достаточно ясно, чтобы никто не подумал, что это означает «всегда пользователь, даже в virtualenv». Это позволило бы изящный путь миграции.

См. № 4575.

Похоже, Манджаро пытается установить --user по умолчанию.

Есть ли что-то новое от апстрима по этому вопросу?

@Tids : «filesystem-2018.9-3 по умолчанию добавляет $HOME/.local/bin в ваш $PATH». ключевой дополнительный элемент, который Manjaro делает правильно.

Debian сочетает «по умолчанию с --user» на уровне Python с «$HOME/.local/bin не находится в вашем $PATH по умолчанию» на уровне учетной записи пользователя, и это комбинация, которая ломает вещи.

В # 7002 я попытался заставить pip выполнять пользовательскую установку по умолчанию, когда глобальный каталог сайтов-пакетов недоступен для записи, а пользовательские сайт-пакеты включены. Это должно в значительной степени избежать выполнения пользовательской установки, когда вы хотели установить в env, если у вас есть разрешение на изменение env.

Сначала я жду обсуждения идеи — давайте не будем зацикливаться на рассмотрении реализации, прежде чем мы подумаем, имеет ли вообще смысл это делать.

Стоит отметить, что смешивание пользовательских и непользовательских установок (самого pip) чревато проблемами - недавно см. # 7209 в качестве одного из примеров.

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

(В основном я добавляю этот комментарий здесь, чтобы он где-то был записан — в основном это вообще не проблема pip, а скорее усложнение того, как работает каталог USER_SITE Python в целом, что недостаточно хорошо понимают пользователи, устанавливающие с --user ).

Похоже, проблема в том, что PATH (для поиска команд) и sys.path (для поиска импорта Python) имеют противоположные приоритеты, поэтому скрипт запуска из одной установки пытается загрузить пакет из разное. Предположительно, это не относится к pip — это может повлиять на любой пакет, устанавливающий скрипт.

Я не уверен, что мы можем с этим сделать, если что, но я согласен, что об этом стоит подумать.

Да, это основное «осложнение USER_SITE», которое я имел в виду. IMO, отказ от сценариев-оболочек и поддержка только python -m pip является наиболее эффективным решением. (Я не против оберток как таковых, но проблемы, которые мы видим с ними, обычно связаны с тем, что люди случайно запускают не ту оболочку, поэтому исправление проблем со сценарием оболочки обычно не является проблемой pip как таковой, а скорее «диагностикой и исправлением неправильной конфигурации пользовательской среды». " проблема)

Вы имеете в виду устаревший скрипт-оболочку pip или устаревшие скрипты-оболочки как вещь, которую может установить pip?

Я, конечно, -1 на последнее - возможность установки команд очень полезна, даже если это вызывает проблемы.

Отказ pip в пользу python -m pip может быть более разумным. Поскольку pip устанавливается в среду Python, в которой он работает, имеет смысл уточнить, какой именно. Но это все равно было бы потерей удобства и большой переменой в том, к чему привыкли люди.

Я имел в виду конкретно сценарии-оболочки для самого pip. Согласен, это потеря удобства, и я был бы не против сохранить их в той или иной форме (#3164 предлагает создать новый проект pip-cli , который просто поставляет обертки), но ключевой момент будет для python -m pip в качестве поддерживаемого средства запуска pip.

Не удалось вызвать скрипт-оболочку pip, чтобы показать предупреждение, если текущий python (в PATH или что-то еще, что будет использоваться с python -m pip ) не является python , используемым pip ? Может быть, даже делегировать python -m pip , если это так называется?

Точно так же pipenv предупреждает, если пользователь уже находится в virtualenv, и если это так, использует этот virtualenv вместо того, чтобы управлять своим собственным, после выдачи предупреждения.

Хорошо, отметим здесь, что #7002 был одобрен 3 из 6 сопровождающих пипсов на данный момент.

Это заставляет pip переключаться с непользовательских установок на пользовательские установки по умолчанию, в большинстве случаев, когда мы действительно должны выполнять пользовательские установки в любом случае. У меня есть две более широкие проблемы, связанные с внесением этого изменения, которые мы должны выяснить, прежде чем выпускать выпуск, в котором реализовано это улучшение.

  • Нужен ли нам механизм явного отказа от пользовательских установок после того, как мы переключимся на него по умолчанию? Если да, то чем он будет отличаться от --no-user ? (Я согласен переименовать --no-user в --global в качестве явного отказа).
  • Какова наша «переходная» стратегия?

    • Как мы хотим сообщить об этом изменении?

    • сказать пользователям быть осторожными при выполнении этого обновления?

    • Какие вопросы мы ожидаем от пользователей, когда это изменение будет реализовано + выпущено?

Я бы сказал, что --global неправильно назван, если вы находитесь внутри среды. Для flit install противоположностью --user является --env , что я имел в виду, чтобы включить «системную среду Python», но я не думаю, что это полностью ясно. Возможно, --no-user по-прежнему лучший выбор — это явно противоположно --user .

Я думаю, что --no-user (или эквивалентная переменная среды или запись конфигурации) должны вернуть вам существующее поведение, поскольку в настоящее время по умолчанию фактически user = False .

Единственный сценарий, который я придумал, когда изменение могло бы сбить с толку, - это если вы думаете, что у вас есть разрешение на установку в среду (с включенным пользовательским сайтом, например, conda), когда на самом деле у вас его нет: сбой понятнее, чем выполнение пользовательская установка, даже если об этом есть сообщение в журнале. Я не придумал ни одного хорошего способа улучшить это.

Также возможно, что обнаружение возможности записи может пойти не так. Ложное срабатывание просто дает вам существующее поведение (попробуйте и не выполните обычную установку). Ложный отрицательный результат приведет к пользовательской установке, хотя она могла бы выполнить обычную.

Это заставляет pip переключаться с непользовательских установок на пользовательские установки по умолчанию.

Не (например) в Windows, где (по умолчанию) установка Python является установкой для каждого пользователя, а сайт-пакеты по умолчанию доступны для записи. Это то, что я предпочитаю в целом в # 7002, потому что мой опыт с момента открытия этой проблемы (# 1668) заключается в том, что слишком легко запутаться со «смешанными» средами, где у вас есть такие пакеты, как pip, установленные как в пакетах сайта и пользовательский сайт. Так что теперь я выступаю за системные установки, если это вообще возможно, и только за пользовательские установки в таких случаях, как Python, управляемый системой Linux, где пакеты сайта не могут быть записаны.

Было сказано, что:

  1. Кажется, нет смысла использовать опцию --no-user , поскольку #7002 означает, что вы получаете установку пользователя, только если установка системы все равно не удалась.
  2. Я думаю, что самое главное, что нам нужно сообщить о переходе, это то, что люди должны быть очень осторожны с множественными установками, и это то, с чем можно справиться только с пониманием и образованием пользователя, а не с помощью какого-либо обходного пути в pip. Это в основном основная проблема Python. Мы могли бы расширить pip check , чтобы сообщать, когда есть сайт и пользователь устанавливает пакет, и пользователь, я думаю, затеняет сайт.

Кажется, нет смысла в опции --no-user

Чтобы было ясно, это уже существует, хотя, вероятно, не часто полезно. Если у вас есть user=true в файле конфигурации, --no-user должен переопределить это.

Чтобы было ясно, это уже существует

Извините, я должен был быть более ясным. Я не вижу смысла в «механизме явного отказа от пользовательских установок после того, как мы переключимся на него по умолчанию», по крайней мере, в том смысле, который, как я предполагаю, имел в виду @pradiunsg , а именно об отказе от поведения # 7002, которое это не то же самое, что «переключение на пользовательские установки по умолчанию», как я сказал.

На самом деле, я не уверен, что это понятнее ;-) Может быть, все, что я хочу сказать, это «нам не нужны другие варианты, кроме тех, которые у нас есть сейчас»…

Хм... @pfmoore После # 7002, что нужно, чтобы считать эту проблему решенной?

PS: Я написал этот предыдущий комментарий в спешке, и он был случайно опубликован. Пули в порядке; Я все еще составлял абзац перед ним, когда он был опубликован. Извините за путаницу, которая могла возникнуть.

@pradyunsg Учитывая, что я теперь гораздо менее склонен считать, что --user по умолчанию является хорошей идеей, если только это не является абсолютно необходимым (адреса случаев # 7002), я бы скорее сказал, что мы можем отказаться от этой проблемы как больше не является хорошей идеей, когда #7002 готов.

Принимая ваши 2 маркированных пункта как вещи, которые нам могут понадобиться, чтобы считать № 7002 завершенным, мои комментарии выше охватывают это.

Я следил за примечаниями к выпуску здесь.
https://pip.pypa.io/en/stable/news/#id3
«По умолчанию выполняется пользовательская установка (как если бы был передан параметр --user), когда основной каталог site-packages недоступен для записи, а пользовательские site-packages включены. (#1668)»

Мои сборки теперь терпят неудачу с

ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Кажется, это исправлено путем удаления --user из моих команд pip.

Было ли это ожидаемым поведением? Примечания к выпуску, похоже, не отражают этого.

ссылка на скрипт, который теперь дает сбой на pip 20.0.1 (удаление --user исправляет жесткий сбой)
https://github.com/lfit/releng-global-jjb/blob/master/shell/python-tools-install.sh

Если правильно, что пакеты пользовательских сайтов нельзя импортировать из этой среды, то это ожидаемое поведение, но оно ортогонально этому PR. Эта проверка была введена много лет назад (# 567), но похоже, что до недавнего времени она была нарушена с помощью venv (# 7155). Для этого есть примечание к выпуску:

Правильно обрабатывать системные сайт-пакеты в виртуальных средах, созданных с помощью venv (PEP 405).

Ах да, спасибо за ваши комментарии. Я понял это...
мой скрипт заполнял .local/bin/
когда я бежал

python3 -m venv ~/.local

а затем в оболочке входа в Ubuntu (#!/bin/bash -l) .local/bin добавляется к пути (поэтому вызов python3 теперь вызывает исполняемый файл .local/bin/python3), чего мы не хотим.
Мне никогда не нужно было запускать python3 -m venv ~/.local
или вызывать мои сценарии из оболочки входа в систему, и удаление обеих или любой из этих проблем устраняет это.

#fresh ubuntu docker
root<strong i="13">@7d8107816f64</strong>:/# python3 -m pip install  --user --upgrade pip
Successfully installed pip-20.0.1
root<strong i="14">@7d8107816f64</strong>:/# python3 -m pip --version
pip 20.0.1 from /root/.local/lib/python3.6/site-packages/pip (python 3.6)
root<strong i="15">@7d8107816f64</strong>:/# ls root/.local/bin/pip
pip     pip3    pip3.6
#Now we populate ~/.local/bin/
root<strong i="16">@7d8107816f64</strong>:/# python3 -m venv ~/.local
root<strong i="17">@7d8107816f64</strong>:/# ls root/.local/bin/
activate          activate.fish     easy_install-3.6  pip3              python
activate.csh      easy_install      pip               pip3.6            python3
root<strong i="18">@7d8107816f64</strong>:/# ./root/.local/bin/python --version
Python 3.6.9
root<strong i="19">@7d8107816f64</strong>:/# ./root/.local/bin/python -m pip install  --user --upgrade pip
ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Поэтому, если мы когда-либо запустим исполняемый файл .local/bin/python, мы не сможем установить pip с --user

О, я пропустил, что ты делаешь python3 -m venv ~/.local . Это может сбить с толку такие инструменты, как pip, потому что ~/.local — это префикс для установки --user (в Linux). venvs и --user — это два _различных_ способа установки пакетов без внесения общесистемных изменений: вы должны использовать либо один, либо другой. Создание venv в ~/.local делает странный гибрид этих двух вещей.

Новое поведение, по-видимому, удобно для многих, но «пользовательские» установки вызвали у меня как у веб-разработчика некоторое огорчение — мне часто нужно подготовить виртуальные окружения, которые будут развернуты на наших рабочих машинах, и если какой-либо пакет установлен в моей пользовательской библиотеке, тогда по умолчанию pip откажется устанавливать его на виртуальную среду, которую я готовлю, и все равно успешно завершит работу. Уведомление о том, что он решил не устанавливать пакет, скрыто внутри 30 или 40 страниц вывода сценария, который я использую для подготовки virtualenv. Конечным результатом является то, что после развертывания virtualenv пакеты из моего домашнего каталога больше не доступны, поэтому в моем рабочем веб-приложении отсутствуют некоторые случайные пакеты, и оно падает мертвым.

Я готов признать, что мой вариант использования не типичен, так что, возможно, это была хорошая идея с точки зрения общего удобства использования.

Для тех, у кого были похожие проблемы, есть несколько способов обойти это:

  • Добавьте --force-reinstall во все ваши pip install командные строки в сценариях и т. д.
  • Удалите ~/.local/lib/python* и отредактируйте ~/.pip/pip.conf , добавив user = no в раздел global :
[global]
user = no
  • Сделайте что-нибудь более радикальное, например, измените ~/.local/lib на файл, а не на каталог :smirk:

Как всегда, дорогие мейнтейнеры упаковки, спасибо вам за все, что вы делаете — я уверен, что практически невозможно что-то изменить, не сломав чей-то материал, а то, что вы все равно подделываете, на самом деле здорово, потому что это позволяет нам двигаться вперед.

Да, пользовательские установки также могут вызвать огромные проблемы в средах непрерывной интеграции, где множество разных вещей запускается под одной и той же учетной записью пользователя, но люди по-прежнему ожидают, что сборки будут изолированы друг от друга. Мы решили эту проблему, сделав ~/.local доступной только для чтения, но приведенные выше решения, вероятно, также будут работать.

Когда вы создаете виртуальную среду с параметрами по умолчанию, она изолирована: она не может видеть ваши пользовательские или системные пакеты сайта, и, следовательно, pip должен работать только с пакетами, установленными в файле env. Это стало значением по умолчанию много лет назад именно из-за тех проблем, которые вы описываете.

Если вы создаете virtualenv с опцией --system-site-packages (или очень старые версии virtualenv, где это было по умолчанию), они действуют как наложение на пакеты, которые вы в противном случае установили бы, как в масштабе всей системы, так и в вашем доме. каталог. Если вы хотите, чтобы системные пакеты были видны, но не пользовательские пакеты, вы можете запустить Python с опцией -s или с переменной окружения PYTHONNOUSERSITE .

Ой! Мне очень жаль, вы совершенно правы. Странная политика системных пакетов моей организации снова наносит удар. Спасибо, что указали на некоторые решения.

Без проблем. Системные пакеты сайтов были более распространены несколько лет назад, когда мы часто полагались на системные менеджеры пакетов для таких вещей, как numpy, поэтому, возможно, стоит пересмотреть эту политику. Но все еще могут быть разумные причины использовать его сегодня.

Закрытие в соответствии с https://github.com/pypa/pip/issues/1668#issuecomment -544569965.

Большое спасибо @takluyver! ^>>^

@takluyver Спасибо за решение проблемы, которая меня давно беспокоила
Но я заметил, что при установке пакетов с непривилегированными пользователями Windows 10 python 3.8.2 с pip 20.0.2 по-прежнему сильно не работает.

ERROR: Exception:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\cli\base_command.py", line 186, in _main
    status = self.run(options, args)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 253, in run
    options.use_user_site = decide_user_install(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 604, in decide_user_install
    if site_packages_writable(root=root_path, isolated=isolated_mode):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 548, in site_packages_writable
    return all(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 549, in <genexpr>
    test_writable_dir(d) for d in set(get_lib_location_guesses(**kwargs))
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 140, in test_writable_dir
    return _test_writable_dir_win(path)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 153, in _test_writable_dir_win
    fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL)
PermissionError: [Errno 13] Permission denied: 'c:\\program files (x86)\\python38-32\\Lib\\site-packages\\accesstest_deleteme_fishfingers_custard_m59lch'

Я думал, что это может быть вызвано OSError errno errno.EACCES но errno.EPERM .

@catPill, пожалуйста, откройте новую проблему, чтобы ее можно было правильно отслеживать. Вполне вероятно, что я что-то пропустил в Windows.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги