https://github.com/python/cpython/commit/f2f3edb8d7daba96a73741a269ceb61575957633
commit: f2f3edb8d7daba96a73741a269ceb61575957633
branch: 3.14
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ncoghlan <ncogh...@gmail.com>
date: 2025-07-05T00:36:12+10:00
summary:

[3.14] gh-135773: have pyvenv.cfg without home key anchor a venv and deduce 
home (GH-135831) (#136287)

gh-135773: have pyvenv.cfg without home key anchor a venv and deduce home 
(GH-135831)

This is still formally undefined behaviour, but we may as well
keep the *same* undefined behaviour as previous versions.

PEP 796 proposes a cleaner and more consistent replacement for 3.15+
(cherry picked from commit 93263d43141a81d369adfcddf325f9a54cb5766d)

Co-authored-by: Richard Levasseur <rlevass...@google.com>

files:
M Lib/test/test_getpath.py
M Modules/getpath.py

diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py
index f86df9d0d03485..83f09f3495547a 100644
--- a/Lib/test/test_getpath.py
+++ b/Lib/test/test_getpath.py
@@ -354,6 +354,27 @@ def test_venv_posix(self):
         actual = getpath(ns, expected)
         self.assertEqual(expected, actual)
 
+    def test_venv_posix_without_home_key(self):
+        ns = MockPosixNamespace(
+            argv0="/venv/bin/python3",
+            PREFIX="/usr",
+            ENV_PATH="/usr/bin",
+        )
+        # Setup the bare minimum venv
+        ns.add_known_xfile("/usr/bin/python3")
+        ns.add_known_xfile("/venv/bin/python3")
+        ns.add_known_link("/venv/bin/python3", "/usr/bin/python3")
+        ns.add_known_file("/venv/pyvenv.cfg", [
+            # home = key intentionally omitted
+        ])
+        expected = dict(
+            executable="/venv/bin/python3",
+            prefix="/venv",
+            base_prefix="/usr",
+        )
+        actual = getpath(ns, expected)
+        self.assertEqual(expected, actual)
+
     def test_venv_changed_name_posix(self):
         "Test a venv layout on *nix."
         ns = MockPosixNamespace(
diff --git a/Modules/getpath.py b/Modules/getpath.py
index be2210345afbda..b89d7427e3febd 100644
--- a/Modules/getpath.py
+++ b/Modules/getpath.py
@@ -364,10 +364,9 @@ def search_up(prefix, *landmarks, test=isfile):
         venv_prefix = None
         pyvenvcfg = []
 
-    # Search for the 'home' key in pyvenv.cfg. Currently, we don't consider the
-    # presence of a pyvenv.cfg file without a 'home' key to signify the
-    # existence of a virtual environment — we quietly ignore them.
-    # XXX: If we don't find a 'home' key, we don't look for another pyvenv.cfg!
+    # Search for the 'home' key in pyvenv.cfg. If a home key isn't found,
+    # then it means a venv is active and home is based on the venv's
+    # executable (if its a symlink, home is where the symlink points).
     for line in pyvenvcfg:
         key, had_equ, value = line.partition('=')
         if had_equ and key.strip().lower() == 'home':
@@ -412,10 +411,8 @@ def search_up(prefix, *landmarks, test=isfile):
                             if isfile(candidate):
                                 base_executable = candidate
                                 break
+            # home key found; stop iterating over lines
             break
-    else:
-        # We didn't find a 'home' key in pyvenv.cfg (no break), reset 
venv_prefix.
-        venv_prefix = None
 
 
 # 
******************************************************************************

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to