GeezerVison is showing github.com — Deprecate and eventually remove macOS-only PYTHONEXECUTABLE environ variable · Issue #91057 · python/cpython
Deprecate and eventually remove macOS-only PYTHONEXECUTABLE environ variable #91057Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2022-03-02.17:45:33.785>
labels = ['OS-mac', '3.11', 'docs']
title = 'Deprecate and eventually remove macOS-only PYTHONEXECUTABLE environ variable'
updated_at = <Date 2022-03-02.17:45:33.785>
user = 'https://github.com/ned-deily'
bugs.python.org fields:
activity = <Date 2022-03-02.17:45:33.785>
actor = 'ned.deily'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation', 'macOS']
creation = <Date 2022-03-02.17:45:33.785>
creator = 'ned.deily'
dependencies = []
files = []
hgrepos = []
issue_num = 46901
keywords = []
message_count = 1.0
messages = ['414382']
nosy_count = 4.0
nosy_names = ['ronaldoussoren', 'ned.deily', 'docs@python', 'steve.dower']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue46901'
versions = ['Python 3.11']
Activityned-deily commented on Mar 2, 2022 The PYTHONEXECUTABLE is a holdover from old Python 2 days; AFAIK, it was specifically to support the Build Applet tool which could be used to build macOS app bundles in Python 2. The only place in current Py3 releases where it is used is in the standard library is in the launch of IDLE.app, a usage that should be able to be eliminated. Otherwise, there shouldn't be any need for it by third-parties. For 3.11, we could eliminate its use by IDLE.app and add a deprecation warning to the docs; not sure about an execution time warning?
https://docs.python.org/3/using/cmdline.html#envvar-PYTHONEXECUTABLE rickeylev commented on May 6, 2025 Hi,
I've found the PYTHONEXECUTABLE environment variable incredibly valuable for the particular case of relocatable virtual environments in read-only file systems using a wrapper script (not symlink) for the venv's bin/python. This case is common in the Bazel ecosystem, where as much as possible is created and determined at build time, and then copied over to a target system to actually run as-is.
In this case, what the PYTHONEXECUTABLE envvar essentially allows is allowing Python to find the underlying interpreter's home directory (which lets it find the interpreter's stdlib etc), while letting site.py's logic look at the venv's directory for e.g site-packages and sys.executable.
The net effect is you can copy a venv directory between systems without having to recreate pyvenv.cfg or the symlinks.
Also: PYTHONEEXECUTABLE is no-longer Mac specific. I'd have to go dig up issue/PR, but checking it only on Mac was intentionally dropped. ned-deily commented on May 18, 2026 Looking into this a bit more, I would like to see the use case of relocatable virtual environments treated as a separate feature that is properly supported and documented rather than using a backdoor 'trick'. I could be misremembering but I think the fact that PYTHONEXECUTABLE is no longer macOS-specific is likely due to an oversight during the rewrite of getpath processing in Python 3.11 rather than an intended change. Most of the references to PYTHONEXECUTABLE in the cpython repo are still macOS-specific. And venvs are specifically documented as being not portable in the general case. I expect there are already other open issues requesting venv portability. mjpieters commented on Jun 5, 2026
I could be misremembering but I think the fact that PYTHONEXECUTABLE is no longer macOS-specific is likely due to an oversight during the rewrite of getpath processing in Python 3.11 rather than an intended change.
PYTHONEXECUTABLE is indeed no longer Mac specific, it is mostly a synonym for __PYVENV_LAUNCHER__ now; see getpath.py:
|
if ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__: |
|
# If set, these variables imply that we should be using them as |
|
# sys.executable and when searching for venvs. However, we should |
|
# use the argv0 path for prefix calculation |
|
|
|
if os_name == 'darwin' and WITH_NEXT_FRAMEWORK: |
|
# In a framework build the binary in {sys.exec_prefix}/bin is |
|
# a stub executable that execs the real interpreter in an |
|
# embedded app bundle. That bundle is an implementation detail |
|
# and should not affect base_executable. |
|
base_executable = f"{dirname(library)}/bin/python{VERSION_MAJOR}.{VERSION_MINOR}" |
|
else: |
|
# Use the real executable as our base, or argv[0] otherwise |
|
# (on Windows, argv[0] is likely to be ENV___PYVENV_LAUNCHER__; on |
|
# other platforms, real_executable is likely to be empty) |
|
base_executable = real_executable or executable |
|
|
|
if not real_executable: |
|
real_executable = base_executable |
|
#real_executable_dir = dirname(real_executable) |
|
executable = ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__ |
|
executable_dir = dirname(executable) |
This is the only location where either variable is actually read and used, outside of tests.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|