Как sys.executable определяет путь интерпретатора? - PullRequest
0 голосов
/ 07 ноября 2018

Я установил Python на Mac с homebrew. У некоторых инструментов (например, pipenv) есть некоторые проблемы, потому что они пытаются записать в /lib/python3.7/site-packages/, что не разрешено в Mac. После некоторых исследований я обнаружил, что они запускают новый интерпретатор python, обнаруженный в sys.executable, который фактически не согласуется с путем python, установленным homebrew.

$ which python
/usr/local/bin/python
$ python -c "import sys; print(sys.executable)"
/usr/local/opt/python/bin/python3.7

Я ожидаю, что эти пути указывают на один и тот же двоичный файл, почему это не так? Как я могу контролировать sys.executable?

1 Ответ

0 голосов
/ 07 ноября 2018

Определяется во время выполнения (точнее, функцией calculate_program_full_path() в Module/getpath.c. Обычно она основана на значении argv[0], которое передала ОС.

Вы можете установить альтернативное значение, установив переменную окружения PYTHONEXECUTABLE .

Однако , на доморощенных сборках происходит немного больше. Homebrew форсирует проблему и устанавливает sys.executable непосредственно в sitecustomize.py модуле , сгенерированном во время установки :

$ tail -n2 /usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sitecustomize.py
    # Set the sys.executable to use the opt_prefix
    sys.executable = '/usr/local/opt/python/bin/python3.7'

Это беспечно игнорирует PYTHONEXECUTABLE, даже если установлено.

Так что же происходит, почему доморощенный клоббер sys.executable?

Homebrew Python - это сборка платформы MacOS , поэтому вы можете запускать приложения с графическим интерфейсом с помощью этого двоичного файла Python. Бинарный файл внутри пакета фреймворка предъявляется Apple к очень строгим требованиям относительно того, что вы можете с ним делать, включая то, что разрешено устанавливать имя исполняемого файла. Чтобы обойти эти ограничения, двоичный файл фреймворка на самом деле представляет собой обертку ), которая переводит переводит в лучший путь, устанавливает переменную окружения __PYVENV_LAUNCHER__ и запускает фактический двоичный файл Python , расположенный в Resources/Python.app/Contents/MacOS/Python , который затем использует переменную окружения __PYVENV_LAUNCHER__, чтобы сообщить sys.executable.

Путь, который устанавливает обертка, имеет любые символические ссылки в имени каталога разрешен. Поскольку homebrew делает /usr/local/opt/python символической ссылкой на определенный каталог бутылок Python, запуск /usr/local/opt/python/bin/python3 приводит к тому, что sys.executable задается путь связанной бутылки:

$ /usr/local/opt/python/bin/python3 -S -c 'import sys; print(sys.executable)'
/usr/local/Cellar/python/3.7.0/bin/python3

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

Я бы хотел, чтобы домашний напиток по крайней мере проверил, установлено ли здесь PYTHONEXECUTABLE . Вы можете самостоятельно решить проблему, просто установив sys.executable:

import os, sys

if 'PYTHONEXECUTABLE' in os.environ and :
    sys.executable = os.environ['PYTHONEXECUTABLE']

Я открыл отчет , чтобы запросить проверки формул Python для доморощенного на PYTHONEXECUTABLE и , включая предлагаемое исправление . Исправление было выпущено 28 ноября 2018 года, так что просто обновление ваших пакетов Python должно дать вам новую версию и сделать Homebrew Python честь PYTHONEXECUTABLE еще раз.

...