]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149671: Restore compatibility with setuptools -nspkg.pth files in site module...
authorVictor Stinner <vstinner@python.org>
Mon, 15 Jun 2026 08:29:52 +0000 (10:29 +0200)
committerGitHub <noreply@github.com>
Mon, 15 Jun 2026 08:29:52 +0000 (08:29 +0000)
Inject the "sitedir" variable in the frame which executes ".pth" code.

Lib/site.py
Lib/test/test_site.py
Misc/NEWS.d/next/Library/2026-06-11-11-52-23.gh-issue-149671.6Rpr5r.rst [new file with mode: 0644]

index b7f5c7f0246bc1beaa4a0e40b2db358cf4ec2582..d06549b8df800e3959e4faa07712ef0b65ec8707 100644 (file)
@@ -505,6 +505,11 @@ class StartupState:
         # batch.  In that case, PEP 829 says the import lines are
         # suppressed in favor of the .start's entry points.
         for filename, imports in self._importexecs.items():
+            # Inject 'sitedir' local variable in the current frame for
+            # compatibility with Python 3.14. Especially, "-nspkg.pth" files
+            # generated by setuptools use: sys._getframe(1).f_locals['sitedir'].
+            sitedir = os.path.dirname(filename)
+
             # Given "/path/to/foo.pth", check whether "/path/to/foo.start" was
             # registered in this same batch.
             name, dot, pth = filename.rpartition(".")
index 5fd65ad999210e4f552e009db1beab85c7b04e0a..bcb51ed7d8476a8ce309f230321cc932caff996f 100644 (file)
@@ -233,6 +233,20 @@ class HelperFunctionsTests(unittest.TestCase):
             self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], sys.path)
             self.assertIn(pth_file.base_dir, sys.path)
 
+    def test_sitedir_variable(self):
+        # gh-149671: setuptools use of `-nspkg.pth` files in Python < 3.15.
+        code = '; '.join((
+            # Code used by "-nspkg.pth" files generated by setuptools.
+            "import sys",
+            "sitedir = sys._getframe(1).f_locals['sitedir']",
+            "print(sitedir)",
+        ))
+        pth_dir, pth_fn = self.make_pth(code)
+        with support.captured_stdout() as stdout:
+            known_paths = site.addpackage(pth_dir, pth_fn, set())
+        sitedir = stdout.getvalue().rstrip()
+        self.assertEqual(sitedir, pth_dir)
+
     # This tests _getuserbase, hence the double underline
     # to distinguish from a test for getuserbase
     def test__getuserbase(self):
diff --git a/Misc/NEWS.d/next/Library/2026-06-11-11-52-23.gh-issue-149671.6Rpr5r.rst b/Misc/NEWS.d/next/Library/2026-06-11-11-52-23.gh-issue-149671.6Rpr5r.rst
new file mode 100644 (file)
index 0000000..5c08828
--- /dev/null
@@ -0,0 +1,3 @@
+Restore compatibility with setuptools ``-nspkg.pth`` files in the :mod:`site`
+module. Inject ``sitedir`` variable in the frame which executes pth code.
+Patch by Victor Stinner.