Skip to content

Commit 571210b

Browse files
gh-135729: Store reference to globals in Interpreter._decref (GH-139104)
1 parent 36ec60f commit 571210b

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

Lib/concurrent/interpreters/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,17 @@ def __del__(self):
149149
def __reduce__(self):
150150
return (type(self), (self._id,))
151151

152-
def _decref(self):
152+
# gh-135729: Globals might be destroyed by the time this is called, so we
153+
# need to keep references ourself
154+
def _decref(self, *,
155+
InterpreterNotFoundError=InterpreterNotFoundError,
156+
_interp_decref=_interpreters.decref,
157+
):
153158
if not self._ownsref:
154159
return
155160
self._ownsref = False
156161
try:
157-
_interpreters.decref(self._id)
162+
_interp_decref(self._id)
158163
except InterpreterNotFoundError:
159164
pass
160165

Lib/test/test_interpreters/test_api.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,22 @@ def test_pickle(self):
419419
unpickled = pickle.loads(data)
420420
self.assertEqual(unpickled, interp)
421421

422+
@support.requires_subprocess()
423+
@force_not_colorized
424+
def test_cleanup_in_repl(self):
425+
# GH-135729: Using a subinterpreter in the REPL would lead to an unraisable
426+
# exception during finalization
427+
repl = script_helper.spawn_python("-i")
428+
script = b"""if True:
429+
from concurrent import interpreters
430+
interpreters.create()
431+
exit()"""
432+
stdout, stderr = repl.communicate(script)
433+
self.assertIsNone(stderr)
434+
self.assertIn(b"remaining subinterpreters", stdout)
435+
self.assertNotIn(b"Traceback", stdout)
436+
437+
422438

423439
class TestInterpreterIsRunning(TestBase):
424440

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix unraisable exception during finalization when using
2+
:mod:`concurrent.interpreters` in the REPL.

0 commit comments

Comments
 (0)