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
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):