]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-135729: Store reference to globals in `Interpreter._decref` (GH-139104...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 7 Oct 2025 18:18:15 +0000 (20:18 +0200)
committerGitHub <noreply@github.com>
Tue, 7 Oct 2025 18:18:15 +0000 (14:18 -0400)
* gh-135729: Store reference to globals in `Interpreter._decref` (GH-139104)
(cherry picked from commit 571210b8f34a54922e5eb11d65060d7a77b8bdf0)

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Lib/concurrent/interpreters/__init__.py
Lib/test/test_interpreters/test_api.py
Misc/NEWS.d/next/Library/2025-09-18-05-32-18.gh-issue-135729.8AmMza.rst [new file with mode: 0644]

index aa46a2b37a48d51112a05a0dc69c80530117286d..ea4147ee9a25da554cddc06632e04e620008a6d2 100644 (file)
@@ -149,12 +149,17 @@ class Interpreter:
     def __reduce__(self):
         return (type(self), (self._id,))
 
-    def _decref(self):
+    # gh-135729: Globals might be destroyed by the time this is called, so we
+    # need to keep references ourself
+    def _decref(self, *,
+                InterpreterNotFoundError=InterpreterNotFoundError,
+                _interp_decref=_interpreters.decref,
+                ):
         if not self._ownsref:
             return
         self._ownsref = False
         try:
-            _interpreters.decref(self._id)
+            _interp_decref(self._id)
         except InterpreterNotFoundError:
             pass
 
index 3fee98ea93e6377676e387de9b89103e149ed616..c5a1743e7fdedfb923f7994463c16d97df41780e 100644 (file)
@@ -419,6 +419,21 @@ class InterpreterObjectTests(TestBase):
                 unpickled = pickle.loads(data)
                 self.assertEqual(unpickled, interp)
 
+    @support.requires_subprocess()
+    @force_not_colorized
+    def test_cleanup_in_repl(self):
+        # GH-135729: Using a subinterpreter in the REPL would lead to an unraisable
+        # exception during finalization
+        repl = script_helper.spawn_python("-i")
+        script = b"""if True:
+        from concurrent import interpreters
+        interpreters.create()
+        exit()"""
+        stdout, stderr = repl.communicate(script)
+        self.assertIsNone(stderr)
+        self.assertNotIn(b"Traceback", stdout)
+
+
 
 class TestInterpreterIsRunning(TestBase):
 
diff --git a/Misc/NEWS.d/next/Library/2025-09-18-05-32-18.gh-issue-135729.8AmMza.rst b/Misc/NEWS.d/next/Library/2025-09-18-05-32-18.gh-issue-135729.8AmMza.rst
new file mode 100644 (file)
index 0000000..1777839
--- /dev/null
@@ -0,0 +1,2 @@
+Fix unraisable exception during finalization when using
+:mod:`concurrent.interpreters` in the REPL.