mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
gh-126016: Remove bad assertion in PyThreadState_Clear (GH-139158)
In the _interpreters module, we use PyEval_EvalCode() to run Python code in another interpreter. However, when the process receives a KeyboardInterrupt, PyEval_EvalCode() will jump straight to finalization rather than returning. This prevents us from cleaning up and marking the thread as "not running main", which triggers an assertion in PyThreadState_Clear() on debug builds. Since everything else works as intended, remove that assertion.
This commit is contained in:
parent
e3d9bd6be3
commit
9243a4b933
3 changed files with 34 additions and 2 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import contextlib
|
||||
import os
|
||||
import pickle
|
||||
import signal
|
||||
import sys
|
||||
from textwrap import dedent
|
||||
import threading
|
||||
|
|
@ -11,7 +12,7 @@
|
|||
from test.support import os_helper
|
||||
from test.support import script_helper
|
||||
from test.support import import_helper
|
||||
from test.support.script_helper import assert_python_ok
|
||||
from test.support.script_helper import assert_python_ok, spawn_python
|
||||
# Raise SkipTest if subinterpreters not supported.
|
||||
_interpreters = import_helper.import_module('_interpreters')
|
||||
from concurrent import interpreters
|
||||
|
|
@ -434,6 +435,31 @@ def test_cleanup_in_repl(self):
|
|||
self.assertIn(b"remaining subinterpreters", stdout)
|
||||
self.assertNotIn(b"Traceback", stdout)
|
||||
|
||||
@support.requires_subprocess()
|
||||
@unittest.skipIf(os.name == 'nt', "signals don't work well on windows")
|
||||
def test_keyboard_interrupt_in_thread_running_interp(self):
|
||||
import subprocess
|
||||
source = f"""if True:
|
||||
from concurrent import interpreters
|
||||
from threading import Thread
|
||||
|
||||
def test():
|
||||
import time
|
||||
print('a', flush=True, end='')
|
||||
time.sleep(10)
|
||||
|
||||
interp = interpreters.create()
|
||||
interp.call_in_thread(test)
|
||||
"""
|
||||
|
||||
with spawn_python("-c", source, stderr=subprocess.PIPE) as proc:
|
||||
self.assertEqual(proc.stdout.read(1), b'a')
|
||||
proc.send_signal(signal.SIGINT)
|
||||
proc.stderr.flush()
|
||||
error = proc.stderr.read()
|
||||
self.assertIn(b"KeyboardInterrupt", error)
|
||||
retcode = proc.wait()
|
||||
self.assertEqual(retcode, 0)
|
||||
|
||||
|
||||
class TestInterpreterIsRunning(TestBase):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Fix an assertion failure when sending :exc:`KeyboardInterrupt` to a Python
|
||||
process running a subinterpreter in a separate thread.
|
||||
|
|
@ -1625,7 +1625,11 @@ PyThreadState_Clear(PyThreadState *tstate)
|
|||
{
|
||||
assert(tstate->_status.initialized && !tstate->_status.cleared);
|
||||
assert(current_fast_get()->interp == tstate->interp);
|
||||
assert(!_PyThreadState_IsRunningMain(tstate));
|
||||
// GH-126016: In the _interpreters module, KeyboardInterrupt exceptions
|
||||
// during PyEval_EvalCode() are sent to finalization, which doesn't let us
|
||||
// mark threads as "not running main". So, for now this assertion is
|
||||
// disabled.
|
||||
// XXX assert(!_PyThreadState_IsRunningMain(tstate));
|
||||
// XXX assert(!tstate->_status.bound || tstate->_status.unbound);
|
||||
tstate->_status.finalizing = 1; // just in case
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue