gh-135729: Store reference to globals in Interpreter._decref (GH-139104)

This commit is contained in:
Peter Bierma
2025-09-18 07:17:51 -04:00
committed by GitHub
parent 36ec60fb43
commit 571210b8f3
3 changed files with 25 additions and 2 deletions

View 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

View File

@@ -419,6 +419,22 @@ 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.assertIn(b"remaining subinterpreters", stdout)
self.assertNotIn(b"Traceback", stdout)
class TestInterpreterIsRunning(TestBase):

View File

@@ -0,0 +1,2 @@
Fix unraisable exception during finalization when using
:mod:`concurrent.interpreters` in the REPL.