]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-135773: have pyvenv.cfg without home key anchor a venv and deduce home (#135831)
authorRichard Levasseur <rlevasseur@google.com>
Fri, 4 Jul 2025 13:44:37 +0000 (06:44 -0700)
committerGitHub <noreply@github.com>
Fri, 4 Jul 2025 13:44:37 +0000 (23:44 +1000)
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+

Lib/test/test_getpath.py
Modules/getpath.py

index f86df9d0d03485e874763d010150368aaf711ac5..83f09f3495547ac2a56d018bd52f0b24e8d859be 100644 (file)
@@ -354,6 +354,27 @@ class MockGetPathTests(unittest.TestCase):
         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(
index be2210345afbda5645a3a54ad93e1211fb5b6a46..b89d7427e3febdda32e114c7a37756b9f62284dc 100644 (file)
@@ -364,10 +364,9 @@ if not py_setpath:
         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 @@ if not py_setpath:
                             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
 
 
 # ******************************************************************************