@@ -2866,6 +2866,29 @@ test_soft_deprecated_macros(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)
28662866 Py_RETURN_NONE ;
28672867}
28682868
2869+ static PyObject *
2870+ test_thread_state_ensure_detachment (PyObject * self , PyObject * unused )
2871+ {
2872+ PyThreadState * before = PyThreadState_Get ();
2873+ assert (before != NULL );
2874+
2875+ PyInterpreterGuard * guard = PyInterpreterGuard_FromCurrent ();
2876+ assert (guard != NULL );
2877+
2878+ PyThreadStateToken * token = PyThreadState_Ensure (guard );
2879+ assert (token != NULL );
2880+ /* Ensure took the fast path; tstate is unchanged. */
2881+ assert (PyThreadState_Get () == before );
2882+
2883+ PyThreadState_Release (token );
2884+
2885+ PyThreadState * after = PyThreadState_GetUnchecked ();
2886+ assert (after != NULL );
2887+
2888+ PyInterpreterGuard_Close (guard );
2889+ Py_RETURN_NONE ;
2890+ }
2891+
28692892static PyMethodDef TestMethods [] = {
28702893 {"set_errno" , set_errno , METH_VARARGS },
28712894 {"test_config" , test_config , METH_NOARGS },
@@ -2969,6 +2992,7 @@ static PyMethodDef TestMethods[] = {
29692992 {"test_thread_state_ensure_crossinterp" , test_thread_state_ensure_crossinterp , METH_NOARGS },
29702993 {"test_interp_view_after_shutdown" , test_interp_view_after_shutdown , METH_NOARGS },
29712994 {"test_thread_state_ensure_view" , test_thread_state_ensure_view , METH_NOARGS },
2995+ {"test_thread_state_ensure_detachment" , test_thread_state_ensure_detachment , METH_NOARGS },
29722996 {NULL , NULL } /* sentinel */
29732997};
29742998
0 commit comments