pip установить в /usr/local

Вопрос или проблема

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

$ dpkg -S /usr/local
dpkg-query: no path found matching pattern /usr/local

То есть, это пространство имен специально зарезервировано для установки пользователями с помощью make install PREFIX=/usr/local и аналогичных команд, что позволяет хорошему сосуществованию программного обеспечения, управляемого apt, с программным обеспечением, управляемым администратором системы. (Также см. /opt против /usr/local.)

Несмотря на стандарты, python 3.12 нарушает эту традицию. Например, я раньше мог создавать образы с предустановленным awscli просто с помощью:
pip install –prefix=/usr/local awscli

С python 3.12 это больше не работает†.

… Честно говоря, мне всё равно на эволюцию Python, отказ от distutils (где, как я полагаю, раньше обрабатывался –prefix=/usr/local), документация, удаляющая даже упоминания о установках в /usr/local (сравните 3.10 и 3.12) и так далее. Мы не можем отменить эти выборы со стороны разработчиков; они уже сделаны. Что меня интересует, так это:

как установить пакеты pip напрямую на ОС (не в песочнице venv);
так, чтобы это не мешало dpkg (/usr/local справляется с этой задачей идеально для моих нужд);
так, чтобы установленные библиотеки можно было импортировать в python repl (любого пользователя) сразу после установки;
так, чтобы установленные исполняемые файлы находились в /usr/local/bin/ и были доступны сразу.

На данный момент, варианты, которые я вижу:

pip install –break-system-packages –prefix=/usr/local foo bar

–break-system-packages выглядит страшно для проведения проверки, несмотря на то, что не имеет смысла;

pip install –target=/usr/local/lib/python3.12/dist-packages/ foo bar

почти работает, как ожидалось — не связывает исполняемые файлы с /usr/local/bin.

Есть ли другие варианты?

Ссылки:

Совет Debian
Обсуждение на Reddit
Обсуждение на SO
PEP-668

† это в конечном итоге требует зловещего флага –break-system-packages, который выглядит страшно, но не имеет смысла в контексте классического префикса /usr/local.

Странным образом, в Debian и Devuan префикс, необходимый для установки в /usr/local, — это /usr. В то время как –prefix=/usr/local устанавливает в /usr/local/local/bin ¯\_(ツ)_/¯. Это:
pip install –prefix=/usr awscli

даёт желаемый результат, а именно:

исполняемый файл /usr/local/bin/aws,
python -c ‘import botocore’ работает,
для всех пользователей образа контейнера.

Предостережения
Лучше быть уверенным, что пересечение между установленными пакетами apt и pip пусто и останется таким. Это связано с тем, что как /usr, так и /usr/local образуют одну “установку python”; интерпретатор видит пакеты, установленные в обоих. (apt в /usr; pip в /usr/local). Таким образом, в терминах PEP-668 может произойти наложение пакетов:

системный инструмент foo зависит от common == 1.*;
вы устанавливаете pip bar, который требует common >= 2.0;
системный инструмент foo теперь сломан, потому что версия common v1 была наложена.

В общем, советы по этой проблеме:
1. Используйте пакет apt, если возможно
Для простых нужд, вам может не понадобиться pip. Например, (какая-то версия) requests может быть установлена с помощью
sudo apt install python3-requests

2. Используйте venv, виртуальную среду
Создать отдельную “установку python”, т.е. venv с полностью изолированным набором пакетов, довольно просто.
sudo apt install python3-venv

python3 -m venv my-shiny-awesome-sandbox
source my-shiny-awesome-sandbox/bin/activate

pip list #– пусто
pip install ….

Тогда вам не нужно беспокоиться о взаимодействиях с системными пакетами. Вместо этого вы заботитесь о поддержании и активации venv.
3. Используйте pipx
sudo apt install pipx
pipx run pycowsay moo

Этот инструмент концептуально поддерживает неявную скрытую venv. Поскольку pipx ориентирован на приложения (точки входа console_scripts), с его помощью не просто установить библиотеки, которые вы могли бы использовать в своих собственных скриптах.
4. Укажите –break-system-packages
sudo pip install –break-system-packages awscli

Это установит в /usr/local. Вы получите как скрипты входных точек, так и библиотеки. Предостережение заключается в том, что вы рискуете смешать пакеты apt с пакетами pip, если не будете осторожны. Поэтому название опции намеренно пугающее.

pip install –user также можно «починить» с помощью:
dpkg-divert –rename –add /usr/lib/python3.12/EXTERNALLY-MANAGED

— как объясняется в /usr/share/doc/python3.12/README.venv.

Ответ или решение

К вопросу установки пакетов с помощью pip в директорию /usr/local, необходимо учитывать несколько ключевых моментов, особенно в контексте изменений, произошедших с Python версии 3.12. В этом ответе я изложу основные аспекты, а также предложу несколько рекомендаций по вашему запросу.

1. Проблема с установкой пакетов через pip в /usr/local

Как вы правильно отметили, каталог /usr/local является стандартной локацией для установки пользовательского программного обеспечения и, согласно иерархии файловой системы Unix (Filesystem Hierarchy Standard, FHS), его использование подразумевает наличие действующих правил для избежания конфликтов с системными пакетами, управляемыми пакетным менеджером, таким как apt.

С переходом на Python 3.12 произошли значительные изменения, которые затруднили установку пакетов через pip в /usr/local. Ранее можно было использовать флаг --prefix=/usr/local, чтобы все компоненты, включая исполняемые файлы и библиотеки, устанавливались в соответствующие директории и были доступны для всех пользователей.

2. Рекомендации для установки пакетов

Исходя из имеющихся проблем, вот несколько практических рекомендаций:

  1. Используйте apt-пакеты, когда это возможно: Если ваши нужды позволяют, рекомендуется использовать apt для установки Python-библиотек. Например, библиотеку requests можно установить командой:

    sudo apt install python3-requests

    Это позволит избежать возможных конфликтов между пакетами pip и apt.

  2. Создавайте виртуальные окружения (venv): Для работы с изолированным набором пакетов вы можете создать виртуальное окружение. Это также поможет избежать проблем с взаимодействием между системными пакетами.

    sudo apt install python3-venv
    python3 -m venv my-env
    source my-env/bin/activate
    pip install <package-name>
  3. Используйте pipx для установки однопользовательских приложений: Если вы планируете установить консольные приложения, вы можете использовать pipx. Он автоматически создает виртуальное окружение для каждого приложения, что исключает конфликты.

    sudo apt install pipx
    pipx install <app-name>
  4. Тем не менее, если необходимо использовать pip для установки в /usr/local, действуйте осторожно: Если вы решите использовать флаг --break-system-packages, будьте внимательны. Этот флаг позволяет установить пакеты в /usr/local, но может привести к конфликтам. Используйте команду:

    sudo pip install --break-system-packages --prefix=/usr <package-name>

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

3. Заключение

Таким образом, несмотря на изменения в Python 3.12, вы все еще можете выполнять установку пакетов в /usr/local, однако это требует аккуратного подхода и полной осведомленности о потенциальных конфликтах. Всегда полезно делать резервные копии и внимательно следить за зависимостями пакетов. Помните, что в большинстве случаев использование apt или venv является более безопасным и надежным решением, чем смешивание системных и упакованных зависимостей с помощью pip в глобальной среде.

Оцените материал
Добавить комментарий

Капча загружается...