From 68434720981f4c0004baac9eceb2942590bcddff Mon Sep 17 00:00:00 2001 From: Vincent Fazio Date: Sun, 6 Nov 2022 09:20:11 -0600 Subject: [PATCH] Set 'home' to parent directory of system_executable PEP 405 says of the "home" key: "If a home key is found, this signifies that the Python binary belongs to a virtual environment, and the value of the home key is the directory containing the Python executable used to create this virtual environment." And: "In this case, prefix-finding continues as normal using the value of the home key as the effective Python binary location, which finds the prefix of the base installation." Previously, "home" was being set to `interpreter.system_exec_prefix` which does not abide by the PEP specification. In Python 3.11, the "home" directory is used to determine the value of `sys._base_executable`, so if the path specified is incorrect, the path + interpreter returned will be invalid. This can cause headaches later when trying to probe info via the discovery module. Now, set this to the parent directory of `interpreter.system_executable`. Signed-off-by: Vincent Fazio --- docs/changelog/2440.bugfix.rst | 1 + src/virtualenv/create/creator.py | 2 +- tests/unit/create/test_creator.py | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/2440.bugfix.rst diff --git a/docs/changelog/2440.bugfix.rst b/docs/changelog/2440.bugfix.rst new file mode 100644 index 000000000..479d7f3c4 --- /dev/null +++ b/docs/changelog/2440.bugfix.rst @@ -0,0 +1 @@ +Use parent directory of python executable for pyvenv.cfg "home" value per PEP 405 - by :user:`vfazio`. diff --git a/src/virtualenv/create/creator.py b/src/virtualenv/create/creator.py index a95b6e2d5..5ea6abec4 100644 --- a/src/virtualenv/create/creator.py +++ b/src/virtualenv/create/creator.py @@ -157,7 +157,7 @@ def run(self): def set_pyenv_cfg(self): self.pyenv_cfg.content = OrderedDict() - self.pyenv_cfg["home"] = self.interpreter.system_exec_prefix + self.pyenv_cfg["home"] = os.path.dirname(os.path.abspath(self.interpreter.system_executable)) self.pyenv_cfg["implementation"] = self.interpreter.implementation self.pyenv_cfg["version_info"] = ".".join(str(i) for i in self.interpreter.version_info) self.pyenv_cfg["virtualenv"] = __version__ diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py index d3adb2ae6..35f919275 100644 --- a/tests/unit/create/test_creator.py +++ b/tests/unit/create/test_creator.py @@ -318,6 +318,15 @@ def test_prompt_set(tmp_path, creator, prompt): assert cfg["prompt"] == actual_prompt +@pytest.mark.parametrize("creator", CURRENT_CREATORS) +def test_home_path_is_exe_parent(tmp_path, creator): + cmd = [str(tmp_path), "--seeder", "app-data", "--without-pip", "--creator", creator] + + result = cli_run(cmd) + cfg = PyEnvCfg.from_file(result.creator.pyenv_cfg.path) + assert cfg["home"] == os.path.dirname(result.interpreter.system_executable) + + @pytest.mark.slow() @pytest.mark.usefixtures("current_fastest") def test_cross_major(cross_python, coverage_env, tmp_path, session_app_data):