【问题标题】:How does sys.executable determine the interpreter path?sys.executable 如何确定解释器路径?
【发布时间】:2018-11-07 12:05:49
【问题描述】:

我已经用自制软件在 mac 上安装了 python。一些工具(例如 pipenv)有一些麻烦,因为它们试图写入/lib/python3.7/site-packages/,在 mac 下是不允许的。经过一番调查,我发现他们在sys.executable 中启动了一个新的python 解释器,这实际上与自制软件安装的python 路径不一致。

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

我希望这些路径指向同一个二进制文件,为什么不是这样?如何控制sys.executable

【问题讨论】:

标签: python macos homebrew sys pipenv


【解决方案1】:

它是在运行时确定的(确切地说是由calculate_program_full_path() function in Module/getpath.c 确定。它通常基于操作系统传入的argv[0] 值。

您可以通过设置PYTHONEXECUTABLE environment variable 来设置替代值。

然而,在自制版本上,还有更多工作要做。 Homebrew 强制解决问题并将sys.executable 直接设置为sitecustomize.py module generated at install time

$ 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 framework build,因此您可以使用此 Python 二进制文件运行 GUI 应用程序。 Apple 对框架包中的二进制文件提出了非常严格的要求,即你可以用它做什么,包括允许将可执行文件名称设置为什么。为了解决这些问题,框架二进制文件实际上是一个wrapper ),它转换为更好的路径,设置__PYVENV_LAUNCHER__ 环境变量并启动位于Resources/Python.app/Contents/MacOS/Python实际 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

这违背了符号链接的目的,并且每次 homebrew 对 Python 公式进行次要版本更新时,都可能导致 pip 安装的脚本损坏。

我希望自制软件至少在此处检查PYTHONEXECUTABLE 是否设置。您可以通过直接设置sys.executable 自己强制解决问题:

import os, sys

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

我已打开报告 to request the homebrew Python formula checks for PYTHONEXECUTABLEincluded a suggested fix。该修复程序已于 2018 年 11 月 28 日发布,因此只需更新您的 Python 包即可获得新版本并使 Homebrew Python 再次获得 PYTHONEXECUTABLE 荣誉。

【讨论】:

  • 感谢您的详尽回答,我从未想过这会如此复杂。同时,我发现 pipenv 尝试写入 /lib/... 的事实是由以前版本的项目文件夹中留下的 setup.cfg 引起的;删除它会使工作变得像魅力一样。但无论如何,这是一个非常有趣的话题,我学到了一些新东西。
  • @MrTJ:是的,如果你提到你对 pipenv 有问题,我本可以专注于此;这是一个新问题。 :-)
  • @MrTJ:我没有听说过setup.cfg 影响pipenv 到那个程度;您是否使用 pipenv install -e . 来包含当前 setuptools 配置的项目?
  • Homebrew 现在尊重PYTHONEXECUTABLE
  • @StefanDragnev:感谢您的提醒,我的意思是更新这一点,因为我的拉取请求已被接受并登陆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多