@@ -1534,6 +1534,42 @@ crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
15341534return NULL ;
15351535}
15361536
1537+ /* Test that the GILState thread and the "current" thread match. */
1538+ static PyObject *
1539+ test_current_tstate_matches (PyObject * self ,PyObject * Py_UNUSED (ignored ))
1540+ {
1541+ PyThreadState * orig_tstate = PyThreadState_Get ();
1542+
1543+ if (orig_tstate != PyGILState_GetThisThreadState ()) {
1544+ PyErr_SetString (PyExc_RuntimeError ,
1545+ "current thread state doesn't match GILState" );
1546+ return NULL ;
1547+ }
1548+
1549+ const char * err = NULL ;
1550+ PyThreadState_Swap (NULL );
1551+ PyThreadState * substate = Py_NewInterpreter ();
1552+
1553+ if (substate != PyThreadState_Get ()) {
1554+ err = "subinterpreter thread state not current" ;
1555+ gotofinally ;
1556+ }
1557+ if (substate != PyGILState_GetThisThreadState ()) {
1558+ err = "subinterpreter thread state doesn't match GILState" ;
1559+ gotofinally ;
1560+ }
1561+
1562+ finally :
1563+ Py_EndInterpreter (substate );
1564+ PyThreadState_Swap (orig_tstate );
1565+
1566+ if (err != NULL ) {
1567+ PyErr_SetString (PyExc_RuntimeError ,err );
1568+ return NULL ;
1569+ }
1570+ Py_RETURN_NONE ;
1571+ }
1572+
15371573/* To run some code in a sub-interpreter. */
15381574static PyObject *
15391575run_in_subinterp (PyObject * self ,PyObject * args )
@@ -3354,6 +3390,7 @@ static PyMethodDef TestMethods[] = {
33543390 {"make_memoryview_from_NULL_pointer" ,make_memoryview_from_NULL_pointer ,
33553391METH_NOARGS },
33563392 {"crash_no_current_thread" ,crash_no_current_thread ,METH_NOARGS },
3393+ {"test_current_tstate_matches" ,test_current_tstate_matches ,METH_NOARGS },
33573394 {"run_in_subinterp" ,run_in_subinterp ,METH_VARARGS },
33583395 {"run_in_subinterp_with_config" ,
33593396_PyCFunction_CAST (run_in_subinterp_with_config ),