gh-127314: Don't mention the GIL when calling without a thread state on the free-threaded build (#127315)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Peter Bierma 2024-12-06 10:58:19 -05:00 committed by GitHub
parent a353455fca
commit 12680ec5bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 7 deletions

View file

@ -190,10 +190,18 @@ static inline void
_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
{
if (tstate == NULL) {
#ifndef Py_GIL_DISABLED
_Py_FatalErrorFunc(func,
"the function must be called with the GIL held, "
"after Python initialization and before Python finalization, "
"but the GIL is released (the current Python thread state is NULL)");
#else
_Py_FatalErrorFunc(func,
"the function must be called with an active thread state, "
"after Python initialization and before Python finalization, "
"but it was called without an active thread state. "
"Are you trying to call the C API inside of a Py_BEGIN_ALLOW_THREADS block?");
#endif
}
}

View file

@ -68,8 +68,13 @@ class PyMemDebugTests(unittest.TestCase):
def check_malloc_without_gil(self, code):
out = self.check(code)
if not support.Py_GIL_DISABLED:
expected = ('Fatal Python error: _PyMem_DebugMalloc: '
'Python memory allocator called without holding the GIL')
else:
expected = ('Fatal Python error: _PyMem_DebugMalloc: '
'Python memory allocator called without an active thread state. '
'Are you trying to call it inside of a Py_BEGIN_ALLOW_THREADS block?')
self.assertIn(expected, out)
def test_pymem_malloc_without_gil(self):

View file

@ -100,11 +100,18 @@ class CAPITest(unittest.TestCase):
_rc, out, err = run_result
self.assertEqual(out, b'')
# This used to cause an infinite loop.
if not support.Py_GIL_DISABLED:
msg = ("Fatal Python error: PyThreadState_Get: "
"the function must be called with the GIL held, "
"after Python initialization and before Python finalization, "
"but the GIL is released "
"(the current Python thread state is NULL)").encode()
else:
msg = ("Fatal Python error: PyThreadState_Get: "
"the function must be called with an active thread state, "
"after Python initialization and before Python finalization, "
"but it was called without an active thread state. "
"Are you trying to call the C API inside of a Py_BEGIN_ALLOW_THREADS block?").encode()
self.assertTrue(err.rstrip().startswith(msg),
err)

View file

@ -0,0 +1,2 @@
Improve error message when calling the C API without an active thread state
on the :term:`free-threaded <free threading>` build.

View file

@ -2910,9 +2910,16 @@ static inline void
_PyMem_DebugCheckGIL(const char *func)
{
if (!PyGILState_Check()) {
#ifndef Py_GIL_DISABLED
_Py_FatalErrorFunc(func,
"Python memory allocator called "
"without holding the GIL");
#else
_Py_FatalErrorFunc(func,
"Python memory allocator called "
"without an active thread state. "
"Are you trying to call it inside of a Py_BEGIN_ALLOW_THREADS block?");
#endif
}
}